diff --git a/Cargo.lock b/Cargo.lock index 6a1dee22fe..49e150649a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -924,6 +924,7 @@ dependencies = [ name = "nym-mixnode" version = "0.1.0" dependencies = [ + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "curve25519-dalek 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "nym-client 0.1.0", diff --git a/Cargo.toml b/Cargo.toml index 737f97603a..47f4f140e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +base64 = "0.11.0" clap = "2.33.0" curve25519-dalek = "1.2.3" nym-client = { path = "../nym-client" } diff --git a/src/main.rs b/src/main.rs index 86882ebce0..a7f299ab5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,12 +32,6 @@ fn main() { .takes_value(true) .required(true), ) - .arg( - Arg::with_name("keyfile") - .long("keyfile") - .help("Optional path to the persistent keyfile of the node") - .takes_value(true), - ) .arg( Arg::with_name("local") .long("local") diff --git a/src/mix_peer.rs b/src/mix_peer.rs index 6573c448f7..c2fbde8477 100644 --- a/src/mix_peer.rs +++ b/src/mix_peer.rs @@ -1,18 +1,20 @@ use std::error::Error; +use std::net::{Ipv4Addr, SocketAddrV4}; use tokio::prelude::*; pub struct MixPeer { - connection: String, + connection: SocketAddrV4, } impl MixPeer { // note that very soon `next_hop_address` will be changed to `next_hop_metadata` pub fn new(next_hop_address: [u8; 32]) -> MixPeer { - let address = String::from_utf8_lossy(&next_hop_address) - .trim_end_matches(char::from(0)) - .to_string(); + let b = next_hop_address; + let host = Ipv4Addr::new(b[0], b[1], b[2], b[3]); + let port: u16 = u16::from_be_bytes([b[4], b[5]]); + let socket_address = SocketAddrV4::new(host, port); MixPeer { - connection: address, + connection: socket_address, } } @@ -22,4 +24,8 @@ impl MixPeer { stream.write_all(&bytes).await?; Ok(()) } + + pub fn to_string(&self) -> String { + self.connection.to_string() + } } diff --git a/src/node/mod.rs b/src/node/mod.rs index 2e0ff0ed38..36b1674b44 100644 --- a/src/node/mod.rs +++ b/src/node/mod.rs @@ -2,6 +2,7 @@ use std::net::SocketAddr; use std::sync::{Arc, RwLock}; use std::time::Duration; +use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::scalar::Scalar; use sphinx::header::delays::Delay as SphinxDelay; use sphinx::{ProcessedPacket, SphinxPacket}; @@ -13,6 +14,22 @@ use crate::mix_peer::MixPeer; mod presence; pub mod runner; +pub struct Config { + directory_server: String, + layer: usize, + public_key: MontgomeryPoint, + secret_key: Scalar, + socket_address: SocketAddr, +} + +impl Config { + pub fn public_key_string(&self) -> String { + let key_bytes = self.public_key.to_bytes().to_vec(); + let b64 = base64::encode_config(&key_bytes, base64::URL_SAFE); + b64.to_string() + } +} + // TODO: this will probably need to be moved elsewhere I imagine #[derive(Debug)] pub enum MixProcessingError { @@ -113,11 +130,11 @@ pub struct MixNode { } impl MixNode { - pub fn new(network_address: SocketAddr, secret_key: Scalar, layer: usize) -> Self { + pub fn new(config: &Config) -> Self { MixNode { - network_address, - secret_key, - layer, + network_address: config.socket_address, + secret_key: config.secret_key, + layer: config.layer, } } diff --git a/src/node/presence.rs b/src/node/presence.rs index dac82d66cc..c2acff1fc2 100644 --- a/src/node/presence.rs +++ b/src/node/presence.rs @@ -1,3 +1,4 @@ +use crate::node; use nym_client::clients::directory; use nym_client::clients::directory::presence::MixNodePresence; use nym_client::clients::directory::requests::presence_mixnodes_post::PresenceMixNodesPoster; @@ -11,17 +12,14 @@ pub struct Notifier { } impl Notifier { - pub fn new(is_local: bool) -> Notifier { - let url = if is_local { - "http://localhost:8080".to_string() - } else { - "https://directory.nymtech.net".to_string() + pub fn new(node_config: &node::Config) -> Notifier { + let config = directory::Config { + base_url: node_config.directory_server.clone(), }; - let config = directory::Config { base_url: url }; let net_client = directory::Client::new(config); let presence = MixNodePresence { - host: "halpin.org:6666".to_string(), - pub_key: "superkey".to_string(), + host: node_config.socket_address.to_string(), // note: the directory server formats the real incoming IP itself + pub_key: node_config.public_key_string(), layer: 666, last_seen: 666, }; diff --git a/src/node/runner.rs b/src/node/runner.rs index e91f0c53cd..c841069dd9 100644 --- a/src/node/runner.rs +++ b/src/node/runner.rs @@ -1,9 +1,9 @@ use crate::banner; +use crate::node; use crate::node::presence; use crate::node::MixNode; use clap::ArgMatches; -use curve25519_dalek::scalar::Scalar; use std::net::ToSocketAddrs; use std::thread; @@ -11,6 +11,20 @@ pub fn start(matches: &ArgMatches) { println!("{}", banner()); println!("Starting mixnode..."); + let config = new_config(matches); + + // println!("Startup on: {}", config.socket_address); + println!("Listening for incoming packets..."); + + let mix = MixNode::new(&config); + thread::spawn(move || { + let notifier = presence::Notifier::new(&config); + notifier.run(); + }); + mix.start_listening().unwrap(); +} + +fn new_config(matches: &ArgMatches) -> node::Config { let host = matches.value_of("host").unwrap_or("0.0.0.0"); let port = match matches.value_of("port").unwrap().parse::() { @@ -23,17 +37,6 @@ pub fn start(matches: &ArgMatches) { Err(err) => panic!("Invalid layer value provided - {:?}", err), }; - let secret_key: Scalar = match matches.value_of("keyfile") { - Some(keyfile) => { - // println!("TODO: load keyfile from <{:?}>", keyfile); - Default::default() - } - None => { - // println!("TODO: generate fresh sphinx keypair"); - Default::default() - } - }; - let is_local = matches.is_present("local"); let socket_address = (host, port) @@ -42,15 +45,19 @@ pub fn start(matches: &ArgMatches) { .next() .expect("Failed to extract the socket address from the iterator"); - thread::spawn(move || { - let notifier = presence::Notifier::new(is_local.clone()); - notifier.run(); - }); + let (secret_key, public_key) = sphinx::crypto::keygen(); - println!("Startup complete on: {}", socket_address); - println!("Listening for incoming packets..."); - // make sure our socket_address is equal to our predefined-hardcoded value - // assert_eq!("127.0.0.1:8080", socket_address.to_string()); - let mix = MixNode::new(socket_address, secret_key, layer); - mix.start_listening().unwrap(); + let directory_server = if is_local { + "http://localhost:8080".to_string() + } else { + "https://directory.nymtech.net".to_string() + }; + + node::Config { + directory_server, + layer, + public_key, + socket_address, + secret_key, + } }