Added config option to ignore all nodes except from Yggdrasil.

pull/13/head
Revertron 3 years ago
parent 118c021d99
commit e806cf5612

@ -1,6 +1,6 @@
[package]
name = "alfis"
version = "0.3.6"
version = "0.3.7"
authors = ["Revertron <alfis@revertron.com>"]
edition = "2018"
build = "build.rs"

@ -1,35 +1,33 @@
# Main settings
# The hash of first block in a chain to know with which nodes to work
origin = "00000102C2F9BFD2803284D93327F089D60FC72A06F19AF2384567F2646B8348"
# A path to your key file to load autamatically
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
listen = "[::]:4244"
# Set true if you want your IP to participate in peer-exchange, or false otherwise
public = true
# Bootstrap nodes
# All bootstap nodes
#peers = ["test-ip4.alfis.name:4244", "test-ip6.alfis.name:4244"]
# Yggdrasil nodes only
peers = ["test-ip6.alfis.name:4244"]
# Allow connections to/from Yggdrasil only (https://yggdrasil-network.github.io)
yggdrasil_only = false
# DNS server options
[dns]
# 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
threads = 20
# 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
forwarders = ["[301:2522::53]:53", "[303:8b1a::53]:53"]
#forwarders = ["[301:2522::53]:53", "[303:8b1a::53]:53"]
# Cloudflare servers
#forwarders = ["1.1.1.1:53", "1.0.0.1:53"]
#Mining options
[mining]
# How many CPU threads to spawn for mining
# How many CPU threads to spawn for mining, zero = number of cores
threads = 0

@ -3,6 +3,7 @@ use rand::Rng;
pub mod constants;
pub use constants::*;
use std::net::IpAddr;
/// Convert bytes array to HEX format
pub fn to_hex(buf: &[u8]) -> String {
@ -80,9 +81,20 @@ pub fn random_string(length: usize) -> String {
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)]
mod test {
use crate::check_domain;
use crate::{check_domain, is_yggdrasil};
use std::net::IpAddr;
#[test]
fn test_check_domain() {
@ -98,4 +110,20 @@ mod test {
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));
}
}

@ -15,7 +15,7 @@ use log::{trace, debug, info, warn, error};
use std::net::{SocketAddr, IpAddr, SocketAddrV4, Shutdown};
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::commons::CHAIN_VERSION;
use std::sync::atomic::{AtomicBool, Ordering};
@ -36,9 +36,9 @@ impl Network {
}
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();
(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));
@ -61,7 +61,7 @@ impl Network {
// States of peer connections, and some data to send when sockets become writable
let mut peers = Peers::new();
// 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 {
// 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
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() {
@ -104,7 +111,7 @@ impl Network {
}
Err(_) => {}
}
poll.registry().reregister(&mut server, SERVER, Interest::READABLE).expect("Error reregistering server");
let _ = poll.registry().reregister(&mut server, SERVER, Interest::READABLE);
}
token => {
if !handle_connection_event(Arc::clone(&context), &mut peers, &poll.registry(), &event) {
@ -130,7 +137,7 @@ impl Network {
};
mine_locker_block(Arc::clone(&context));
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");
});
@ -209,7 +216,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
debug!("Sending hello to {}", &peer.get_addr());
let data: String = {
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()
};
send_message(peer.get_stream(), &data.into_bytes()).unwrap_or_else(|e| warn!("Error sending hello {}", e));

@ -9,7 +9,7 @@ use rand::random;
use rand::seq::IteratorRandom;
#[allow(unused_imports)]
use log::{trace, debug, info, warn, error};
use crate::Bytes;
use crate::{Bytes, is_yggdrasil};
use crate::commons::MAX_RECONNECTS;
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() {
return;
}
@ -260,6 +260,10 @@ impl Peers {
if self.ignored.contains(&addr.ip()) {
continue;
}
if yggdrasil_only && !is_yggdrasil(&addr.ip()) {
info!("Ignoring not Yggdrasil address '{}'", &addr.ip());
continue;
}
match TcpStream::connect(addr.clone()) {
Ok(mut stream) => {
info!("Created connection to peer {}", &addr);
@ -278,7 +282,7 @@ impl 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() {
let addresses: Vec<SocketAddr> = match peer.to_socket_addrs() {
Ok(peers) => { peers.collect() }
@ -286,6 +290,10 @@ impl Peers {
};
for addr in addresses {
if yggdrasil_only && !is_yggdrasil(&addr.ip()) {
info!("Ignoring not Yggdrasil address '{}'", &addr.ip());
continue;
}
match TcpStream::connect(addr.clone()) {
Ok(mut stream) => {
info!("Created connection to peer {}", &addr);

@ -13,12 +13,8 @@ pub struct Settings {
pub origin: String,
#[serde(default)]
pub key_file: String,
#[serde(default = "default_listen")]
pub listen: String,
#[serde(default)]
pub public: bool,
#[serde(default)]
pub peers: Vec<String>,
pub net: Net,
#[serde(default)]
pub dns: Dns,
#[serde(default)]
@ -66,11 +62,9 @@ impl Settings {
impl Default for Settings {
fn default() -> Self {
Self {
origin: "".to_string(),
key_file: "".to_string(),
listen: String::from("[::]:4244"),
public: false,
peers: vec![],
origin: String::from("00000102C2F9BFD2803284D93327F089D60FC72A06F19AF2384567F2646B8348"),
key_file: String::from("default.key"),
net: Net::default(),
dns: Default::default(),
mining: Mining::default()
}
@ -88,7 +82,11 @@ pub struct Dns {
impl Default for Dns {
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
}
#[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 {
String::from("[::]:4244")
}

Loading…
Cancel
Save