Added config option to ignore all nodes except from Yggdrasil.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "alfis"
|
name = "alfis"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
authors = ["Revertron <alfis@revertron.com>"]
|
authors = ["Revertron <alfis@revertron.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|||||||
+11
-13
@@ -1,35 +1,33 @@
|
|||||||
# Main settings
|
|
||||||
|
|
||||||
# The hash of first block in a chain to know with which nodes to work
|
# The hash of first block in a chain to know with which nodes to work
|
||||||
origin = "00000102C2F9BFD2803284D93327F089D60FC72A06F19AF2384567F2646B8348"
|
origin = "00000102C2F9BFD2803284D93327F089D60FC72A06F19AF2384567F2646B8348"
|
||||||
# A path to your key file to load autamatically
|
# A path to your key file to load autamatically
|
||||||
key_file = "default.key"
|
key_file = "default.key"
|
||||||
|
|
||||||
|
# Network settings
|
||||||
|
[net]
|
||||||
|
# All bootstap nodes
|
||||||
|
peers = ["test-ip4.alfis.name:4244", "test-ip6.alfis.name:4244"]
|
||||||
# Your node will listen on that address for other nodes to connect
|
# Your node will listen on that address for other nodes to connect
|
||||||
listen = "[::]:4244"
|
listen = "[::]:4244"
|
||||||
# Set true if you want your IP to participate in peer-exchange, or false otherwise
|
# Set true if you want your IP to participate in peer-exchange, or false otherwise
|
||||||
public = true
|
public = true
|
||||||
|
# Allow connections to/from Yggdrasil only (https://yggdrasil-network.github.io)
|
||||||
# Bootstrap nodes
|
yggdrasil_only = false
|
||||||
|
|
||||||
# All bootstap nodes
|
|
||||||
#peers = ["test-ip4.alfis.name:4244", "test-ip6.alfis.name:4244"]
|
|
||||||
# Yggdrasil nodes only
|
|
||||||
peers = ["test-ip6.alfis.name:4244"]
|
|
||||||
|
|
||||||
# DNS server options
|
# DNS server options
|
||||||
[dns]
|
[dns]
|
||||||
# Your DNS resolver will be listening on this address and port (Usual port is 53)
|
# Your DNS resolver will be listening on this address and port (Usual port is 53)
|
||||||
listen = "127.0.0.1:5300"
|
listen = "127.0.0.1:53"
|
||||||
# How many threads to spawn by DNS server
|
# How many threads to spawn by DNS server
|
||||||
threads = 20
|
threads = 20
|
||||||
# AdGuard DNS servers to filter ads and trackers
|
# AdGuard DNS servers to filter ads and trackers
|
||||||
#forwarders = ["94.140.14.14:53", "94.140.15.15:53"]
|
forwarders = ["94.140.14.14:53", "94.140.15.15:53"]
|
||||||
# Wyrd servers
|
# Wyrd servers
|
||||||
forwarders = ["[301:2522::53]:53", "[303:8b1a::53]:53"]
|
#forwarders = ["[301:2522::53]:53", "[303:8b1a::53]:53"]
|
||||||
# Cloudflare servers
|
# Cloudflare servers
|
||||||
#forwarders = ["1.1.1.1:53", "1.0.0.1:53"]
|
#forwarders = ["1.1.1.1:53", "1.0.0.1:53"]
|
||||||
|
|
||||||
#Mining options
|
#Mining options
|
||||||
[mining]
|
[mining]
|
||||||
# How many CPU threads to spawn for mining
|
# How many CPU threads to spawn for mining, zero = number of cores
|
||||||
threads = 0
|
threads = 0
|
||||||
+29
-1
@@ -3,6 +3,7 @@ use rand::Rng;
|
|||||||
|
|
||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub use constants::*;
|
pub use constants::*;
|
||||||
|
use std::net::IpAddr;
|
||||||
|
|
||||||
/// Convert bytes array to HEX format
|
/// Convert bytes array to HEX format
|
||||||
pub fn to_hex(buf: &[u8]) -> String {
|
pub fn to_hex(buf: &[u8]) -> String {
|
||||||
@@ -80,9 +81,20 @@ pub fn random_string(length: usize) -> String {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if this IP is from Yggdrasil network
|
||||||
|
/// https://yggdrasil-network.github.io
|
||||||
|
pub fn is_yggdrasil(addr: &IpAddr) -> bool {
|
||||||
|
if let IpAddr::V6(ipv6) = addr {
|
||||||
|
let first_byte = ipv6.octets()[0];
|
||||||
|
return first_byte == 2 || first_byte == 3;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::check_domain;
|
use crate::{check_domain, is_yggdrasil};
|
||||||
|
use std::net::IpAddr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_domain() {
|
fn test_check_domain() {
|
||||||
@@ -98,4 +110,20 @@ mod test {
|
|||||||
assert!(!check_domain(".ab.c", true));
|
assert!(!check_domain(".ab.c", true));
|
||||||
assert!(!check_domain("ab.c-", true));
|
assert!(!check_domain("ab.c-", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_yggdrasil() {
|
||||||
|
let addr: IpAddr = "200::1".parse().unwrap();
|
||||||
|
assert!(is_yggdrasil(&addr));
|
||||||
|
let addr: IpAddr = "226::1".parse().unwrap();
|
||||||
|
assert!(is_yggdrasil(&addr));
|
||||||
|
let addr: IpAddr = "300::1".parse().unwrap();
|
||||||
|
assert!(is_yggdrasil(&addr));
|
||||||
|
let addr: IpAddr = "326::1".parse().unwrap();
|
||||||
|
assert!(is_yggdrasil(&addr));
|
||||||
|
let addr: IpAddr = "2001::1".parse().unwrap();
|
||||||
|
assert!(!is_yggdrasil(&addr));
|
||||||
|
let addr: IpAddr = "2201::1".parse().unwrap();
|
||||||
|
assert!(!is_yggdrasil(&addr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-7
@@ -15,7 +15,7 @@ use log::{trace, debug, info, warn, error};
|
|||||||
|
|
||||||
use std::net::{SocketAddr, IpAddr, SocketAddrV4, Shutdown};
|
use std::net::{SocketAddr, IpAddr, SocketAddrV4, Shutdown};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use crate::{Context, Block, p2p::Message, p2p::State, p2p::Peer, p2p::Peers, Bytes};
|
use crate::{Context, Block, p2p::Message, p2p::State, p2p::Peer, p2p::Peers, Bytes, is_yggdrasil};
|
||||||
use crate::blockchain::enums::BlockQuality;
|
use crate::blockchain::enums::BlockQuality;
|
||||||
use crate::commons::CHAIN_VERSION;
|
use crate::commons::CHAIN_VERSION;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
@@ -36,9 +36,9 @@ impl Network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self) -> Result<(), String> {
|
pub fn start(&mut self) -> Result<(), String> {
|
||||||
let (listen_addr, peers_addrs) = {
|
let (listen_addr, peers_addrs, yggdrasil_only) = {
|
||||||
let c = self.context.lock().unwrap();
|
let c = self.context.lock().unwrap();
|
||||||
(c.settings.listen.clone(), c.settings.peers.clone())
|
(c.settings.net.listen.clone(), c.settings.net.peers.clone(), c.settings.net.yggdrasil_only)
|
||||||
};
|
};
|
||||||
|
|
||||||
let running = Arc::new(AtomicBool::new(true));
|
let running = Arc::new(AtomicBool::new(true));
|
||||||
@@ -61,7 +61,7 @@ impl Network {
|
|||||||
// States of peer connections, and some data to send when sockets become writable
|
// States of peer connections, and some data to send when sockets become writable
|
||||||
let mut peers = Peers::new();
|
let mut peers = Peers::new();
|
||||||
// Starting peer connections to bootstrap nodes
|
// Starting peer connections to bootstrap nodes
|
||||||
peers.connect_peers(peers_addrs, &poll.registry(), &mut unique_token);
|
peers.connect_peers(peers_addrs, &poll.registry(), &mut unique_token, yggdrasil_only);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Poll Mio for events, blocking until we get an event.
|
// Poll Mio for events, blocking until we get an event.
|
||||||
@@ -89,6 +89,13 @@ impl Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if yggdrasil_only && !is_yggdrasil(&address.ip()) {
|
||||||
|
info!("Dropping connection from Internet");
|
||||||
|
stream.shutdown(Shutdown::Both).unwrap_or_else(|e|{ warn!("Error in shutdown, {}", e); });
|
||||||
|
let _ = poll.registry().reregister(&mut server, SERVER, Interest::READABLE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If connection is from the same IP and not from loopback we ignore it to avoid connection loops
|
// If connection is from the same IP and not from loopback we ignore it to avoid connection loops
|
||||||
let local_ip = stream.local_addr().unwrap_or("0.0.0.0:0".parse().unwrap());
|
let local_ip = stream.local_addr().unwrap_or("0.0.0.0:0".parse().unwrap());
|
||||||
if !local_ip.ip().is_loopback() && local_ip.ip() == address.ip() {
|
if !local_ip.ip().is_loopback() && local_ip.ip() == address.ip() {
|
||||||
@@ -104,7 +111,7 @@ impl Network {
|
|||||||
}
|
}
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
}
|
}
|
||||||
poll.registry().reregister(&mut server, SERVER, Interest::READABLE).expect("Error reregistering server");
|
let _ = poll.registry().reregister(&mut server, SERVER, Interest::READABLE);
|
||||||
}
|
}
|
||||||
token => {
|
token => {
|
||||||
if !handle_connection_event(Arc::clone(&context), &mut peers, &poll.registry(), &event) {
|
if !handle_connection_event(Arc::clone(&context), &mut peers, &poll.registry(), &event) {
|
||||||
@@ -130,7 +137,7 @@ impl Network {
|
|||||||
};
|
};
|
||||||
mine_locker_block(Arc::clone(&context));
|
mine_locker_block(Arc::clone(&context));
|
||||||
peers.send_pings(poll.registry(), height, hash);
|
peers.send_pings(poll.registry(), height, hash);
|
||||||
peers.connect_new_peers(poll.registry(), &mut unique_token);
|
peers.connect_new_peers(poll.registry(), &mut unique_token, yggdrasil_only);
|
||||||
}
|
}
|
||||||
info!("Network loop finished");
|
info!("Network loop finished");
|
||||||
});
|
});
|
||||||
@@ -209,7 +216,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
|
|||||||
debug!("Sending hello to {}", &peer.get_addr());
|
debug!("Sending hello to {}", &peer.get_addr());
|
||||||
let data: String = {
|
let data: String = {
|
||||||
let c = context.lock().unwrap();
|
let c = context.lock().unwrap();
|
||||||
let message = Message::hand(&c.app_version, &c.settings.origin, CHAIN_VERSION, c.settings.public, peer.get_rand());
|
let message = Message::hand(&c.app_version, &c.settings.origin, CHAIN_VERSION, c.settings.net.public, peer.get_rand());
|
||||||
serde_json::to_string(&message).unwrap()
|
serde_json::to_string(&message).unwrap()
|
||||||
};
|
};
|
||||||
send_message(peer.get_stream(), &data.into_bytes()).unwrap_or_else(|e| warn!("Error sending hello {}", e));
|
send_message(peer.get_stream(), &data.into_bytes()).unwrap_or_else(|e| warn!("Error sending hello {}", e));
|
||||||
|
|||||||
+11
-3
@@ -9,7 +9,7 @@ use rand::random;
|
|||||||
use rand::seq::IteratorRandom;
|
use rand::seq::IteratorRandom;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{trace, debug, info, warn, error};
|
use log::{trace, debug, info, warn, error};
|
||||||
use crate::Bytes;
|
use crate::{Bytes, is_yggdrasil};
|
||||||
use crate::commons::MAX_RECONNECTS;
|
use crate::commons::MAX_RECONNECTS;
|
||||||
|
|
||||||
pub struct Peers {
|
pub struct Peers {
|
||||||
@@ -252,7 +252,7 @@ impl Peers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn connect_new_peers(&mut self, registry: &Registry, unique_token: &mut Token) {
|
pub fn connect_new_peers(&mut self, registry: &Registry, unique_token: &mut Token, yggdrasil_only: bool) {
|
||||||
if self.new_peers.is_empty() {
|
if self.new_peers.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -260,6 +260,10 @@ impl Peers {
|
|||||||
if self.ignored.contains(&addr.ip()) {
|
if self.ignored.contains(&addr.ip()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if yggdrasil_only && !is_yggdrasil(&addr.ip()) {
|
||||||
|
info!("Ignoring not Yggdrasil address '{}'", &addr.ip());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
match TcpStream::connect(addr.clone()) {
|
match TcpStream::connect(addr.clone()) {
|
||||||
Ok(mut stream) => {
|
Ok(mut stream) => {
|
||||||
info!("Created connection to peer {}", &addr);
|
info!("Created connection to peer {}", &addr);
|
||||||
@@ -278,7 +282,7 @@ impl Peers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Connecting to configured (bootstrap) peers
|
/// Connecting to configured (bootstrap) peers
|
||||||
pub fn connect_peers(&mut self, peers_addrs: Vec<String>, registry: &Registry, unique_token: &mut Token) {
|
pub fn connect_peers(&mut self, peers_addrs: Vec<String>, registry: &Registry, unique_token: &mut Token, yggdrasil_only: bool) {
|
||||||
for peer in peers_addrs.iter() {
|
for peer in peers_addrs.iter() {
|
||||||
let addresses: Vec<SocketAddr> = match peer.to_socket_addrs() {
|
let addresses: Vec<SocketAddr> = match peer.to_socket_addrs() {
|
||||||
Ok(peers) => { peers.collect() }
|
Ok(peers) => { peers.collect() }
|
||||||
@@ -286,6 +290,10 @@ impl Peers {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for addr in addresses {
|
for addr in addresses {
|
||||||
|
if yggdrasil_only && !is_yggdrasil(&addr.ip()) {
|
||||||
|
info!("Ignoring not Yggdrasil address '{}'", &addr.ip());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
match TcpStream::connect(addr.clone()) {
|
match TcpStream::connect(addr.clone()) {
|
||||||
Ok(mut stream) => {
|
Ok(mut stream) => {
|
||||||
info!("Created connection to peer {}", &addr);
|
info!("Created connection to peer {}", &addr);
|
||||||
|
|||||||
+32
-11
@@ -13,12 +13,8 @@ pub struct Settings {
|
|||||||
pub origin: String,
|
pub origin: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub key_file: String,
|
pub key_file: String,
|
||||||
#[serde(default = "default_listen")]
|
|
||||||
pub listen: String,
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub public: bool,
|
pub net: Net,
|
||||||
#[serde(default)]
|
|
||||||
pub peers: Vec<String>,
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub dns: Dns,
|
pub dns: Dns,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -66,11 +62,9 @@ impl Settings {
|
|||||||
impl Default for Settings {
|
impl Default for Settings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
origin: "".to_string(),
|
origin: String::from("00000102C2F9BFD2803284D93327F089D60FC72A06F19AF2384567F2646B8348"),
|
||||||
key_file: "".to_string(),
|
key_file: String::from("default.key"),
|
||||||
listen: String::from("[::]:4244"),
|
net: Net::default(),
|
||||||
public: false,
|
|
||||||
peers: vec![],
|
|
||||||
dns: Default::default(),
|
dns: Default::default(),
|
||||||
mining: Mining::default()
|
mining: Mining::default()
|
||||||
}
|
}
|
||||||
@@ -88,7 +82,11 @@ pub struct Dns {
|
|||||||
|
|
||||||
impl Default for Dns {
|
impl Default for Dns {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Dns { listen: String::from("0.0.0.0:53"), threads: 20, forwarders: vec!["94.140.14.14:53".to_owned(), "94.140.15.15:53".to_owned()] }
|
Dns {
|
||||||
|
listen: String::from("127.0.0.1:53"),
|
||||||
|
threads: 20,
|
||||||
|
forwarders: vec![String::from("94.140.14.14:53"), String::from("94.140.15.15:53")]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +96,29 @@ pub struct Mining {
|
|||||||
pub threads: usize
|
pub threads: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Net {
|
||||||
|
#[serde(default)]
|
||||||
|
pub peers: Vec<String>,
|
||||||
|
#[serde(default = "default_listen")]
|
||||||
|
pub listen: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub public: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub yggdrasil_only: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Net {
|
||||||
|
fn default() -> Self {
|
||||||
|
Net {
|
||||||
|
peers: vec![String::from("test-ip4.alfis.name:4244"), String::from("test-ip6.alfis.name:4244")],
|
||||||
|
listen: String::from("[::]:4244"),
|
||||||
|
public: true,
|
||||||
|
yggdrasil_only: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn default_listen() -> String {
|
fn default_listen() -> String {
|
||||||
String::from("[::]:4244")
|
String::from("[::]:4244")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user