From b741c23a7cf7d3e140188bc98a19445655104597 Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 11:30:16 +0000 Subject: [PATCH 1/8] presence: adding comparison and debug to presence models --- src/clients/directory/presence.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/clients/directory/presence.rs b/src/clients/directory/presence.rs index 0410479a8d..1d2e56f7e1 100644 --- a/src/clients/directory/presence.rs +++ b/src/clients/directory/presence.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct CocoPresence { pub host: String, @@ -8,7 +8,7 @@ pub struct CocoPresence { pub last_seen: i64, } -#[derive(Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct MixNodePresence { pub host: String, @@ -17,7 +17,7 @@ pub struct MixNodePresence { pub last_seen: u64, } -#[derive(Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct MixProviderPresence { pub host: String, @@ -25,14 +25,14 @@ pub struct MixProviderPresence { pub registered_clients: Vec, } -#[derive(Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct MixProviderClient { pub pub_key: String, } // Topology shows us the current state of the overall Nym network -#[derive(Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Topology { pub coco_nodes: Vec, From c508d1518dac571723221175ab1e9683c40b53d8 Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 12:42:10 +0000 Subject: [PATCH 2/8] provider: using provider from topology instead of hardcoded --- src/clients/provider.rs | 5 +++-- src/commands/run.rs | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/clients/provider.rs b/src/clients/provider.rs index 2abeb43cce..e0b03dbaec 100644 --- a/src/clients/provider.rs +++ b/src/clients/provider.rs @@ -1,6 +1,7 @@ use sfw_provider_requests::requests::{ProviderRequest, PullRequest}; use sfw_provider_requests::responses::{ProviderResponse, PullResponse}; use std::net::Shutdown; +use std::net::SocketAddrV4; use tokio::prelude::*; use tokio::time::Duration; @@ -13,13 +14,13 @@ impl ProviderClient { pub async fn retrieve_messages( &self, - // provider: &MixNode, + provider: &SocketAddrV4, ) -> Result<(), Box> { let address = [42; 32]; let pull_request = PullRequest::new(address); let bytes = pull_request.to_bytes(); - let mut socket = tokio::net::TcpStream::connect("127.0.0.1:9000").await?; + let mut socket = tokio::net::TcpStream::connect(provider).await?; println!("keep alive: {:?}", socket.keepalive()); socket.set_keepalive(Some(Duration::from_secs(2))).unwrap(); socket.write_all(&bytes[..]).await?; diff --git a/src/commands/run.rs b/src/commands/run.rs index d9ee52a977..f1e7218fdf 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -21,6 +21,13 @@ pub fn execute(matches: &ArgMatches) { // Grab the network topology from the remote directory server let topology = get_topology(is_local); + let provider_address: SocketAddrV4 = topology + .mix_provider_nodes + .first() + .unwrap() + .host + .parse() + .unwrap(); // Create the runtime, probably later move it to Client struct itself? let mut rt = Runtime::new().unwrap(); @@ -59,7 +66,10 @@ pub fn execute(matches: &ArgMatches) { interval.tick().await; println!("going to retrieve messages!"); let provider_client = ProviderClient::new(); - provider_client.retrieve_messages().await.unwrap(); + provider_client + .retrieve_messages(&provider_address) + .await + .unwrap(); } } }) @@ -106,7 +116,10 @@ fn socket_bytes_from_string(address: String) -> [u8; 32] { let host_bytes = socket.ip().octets(); let port_bytes = socket.port().to_be_bytes(); let mut address_bytes = [0u8; 32]; - address_bytes.copy_from_slice(&host_bytes); + address_bytes[0] = host_bytes[0]; + address_bytes[1] = host_bytes[1]; + address_bytes[2] = host_bytes[2]; + address_bytes[3] = host_bytes[3]; address_bytes[4] = port_bytes[0]; address_bytes[5] = port_bytes[1]; address_bytes From 8bf9dabdf138400b63a417456edef4bda85e10cf Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 14:09:41 +0000 Subject: [PATCH 3/8] Import cleanup --- src/clients/mix.rs | 3 +-- src/commands/run.rs | 26 +------------------------- src/utils/topology.rs | 2 -- 3 files changed, 2 insertions(+), 29 deletions(-) diff --git a/src/clients/mix.rs b/src/clients/mix.rs index 65480bf539..2dcc178182 100644 --- a/src/clients/mix.rs +++ b/src/clients/mix.rs @@ -1,6 +1,5 @@ -use sphinx::route::{Node as MixNode, NodeAddressBytes}; +use sphinx::route::NodeAddressBytes; use sphinx::SphinxPacket; -use std::net::SocketAddr; use std::net::{Ipv4Addr, SocketAddrV4}; use tokio::prelude::*; diff --git a/src/commands/run.rs b/src/commands/run.rs index 5f3e5af77f..9fcb99fe41 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -1,37 +1,13 @@ -use crate::clients::directory; -use crate::clients::directory::presence::Topology; -use crate::clients::directory::requests::presence_topology_get::PresenceTopologyGetRequester; -use crate::clients::directory::DirectoryClient; -use crate::clients::mix::MixClient; -use crate::clients::provider::ProviderClient; use crate::clients::NymClient; -use crate::utils::bytes; -use base64; use clap::ArgMatches; -use curve25519_dalek::montgomery::MontgomeryPoint; -use sphinx::route::Destination; -use sphinx::route::Node as SphinxNode; -use std::net::SocketAddrV4; -use std::time::Duration; -use tokio::runtime::Runtime; -use tokio::time::{interval_at, Instant}; pub fn execute(matches: &ArgMatches) { let is_local = matches.is_present("local"); println!("Starting client, local: {:?}", is_local); - // todo: to be taken from config or something + // TODO: to be taken from config or something let my_address = [42u8; 32]; let is_local = true; let client = NymClient::new(my_address, is_local); client.start().unwrap(); - // Grab the network topology from the remote directory server -} - -// TODO: where do we retrieve this guy from? -fn get_destination() -> Destination { - Destination { - address: [42u8; 32], - identifier: [1u8; 16], - } } diff --git a/src/utils/topology.rs b/src/utils/topology.rs index 35ee9c2f1f..6bc8e59169 100644 --- a/src/utils/topology.rs +++ b/src/utils/topology.rs @@ -2,8 +2,6 @@ use crate::clients::directory; use crate::clients::directory::presence::Topology; use crate::clients::directory::requests::presence_topology_get::PresenceTopologyGetRequester; use crate::clients::directory::DirectoryClient; -use crate::clients::mix::MixClient; -use crate::clients::provider::ProviderClient; use crate::utils::bytes; use curve25519_dalek::montgomery::MontgomeryPoint; use sphinx::route::Node as SphinxNode; From a42dd55320dd9b5dbc8b6771bbc480ea46b2da9d Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 14:47:45 +0000 Subject: [PATCH 4/8] main: adding "id" parameter back onto "run" command --- src/main.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main.rs b/src/main.rs index 6dc3ea6c3e..2c45340ff3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,6 +31,12 @@ fn main() { .subcommand( SubCommand::with_name("run") .about("Run a persistent Nym client process") + .arg(Arg::with_name("id") + .long("id") + .help("Id of the nym-mixnet-client we want to run.") + .takes_value(true) + .required(true) + ) .arg(Arg::with_name("local") .long("local") .help("Flag to indicate whether the client is expected to run on the local deployment.") From 74e0fb849be3dcf79233501217673a9192dbc16d Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 14:48:20 +0000 Subject: [PATCH 5/8] keys: relying on the type system to ensure keys are 32 byte arrays --- src/identity/mixnet.rs | 8 ++++---- src/persistence/pemstore.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/identity/mixnet.rs b/src/identity/mixnet.rs index 3783dffd97..10e081a4fa 100644 --- a/src/identity/mixnet.rs +++ b/src/identity/mixnet.rs @@ -23,11 +23,11 @@ impl KeyPair { KeyPair { private, public } } - pub fn private_bytes(&self) -> Vec { - self.private.to_bytes().to_vec() + pub fn private_bytes(&self) -> [u8; 32] { + self.private.to_bytes() } - pub fn public_bytes(&self) -> Vec { - self.public.to_bytes().to_vec() + pub fn public_bytes(&self) -> [u8; 32] { + self.public.to_bytes() } } diff --git a/src/persistence/pemstore.rs b/src/persistence/pemstore.rs index c935fab437..02c1f5db00 100644 --- a/src/persistence/pemstore.rs +++ b/src/persistence/pemstore.rs @@ -52,10 +52,10 @@ impl PemStore { ); } - fn write_pem_file(&self, filepath: PathBuf, data: Vec, tag: String) { + fn write_pem_file(&self, filepath: PathBuf, data: [u8; 32], tag: String) { let pem = Pem { tag, - contents: data, + contents: data.to_vec(), }; let key = encode(&pem); From 127f6b4047a48c709974b79b733a1f1292a33f0d Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 14:48:44 +0000 Subject: [PATCH 6/8] run: reading the client's keypair from disk whenever it's run --- src/commands/run.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/commands/run.rs b/src/commands/run.rs index 9fcb99fe41..e6eec43bdd 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -1,13 +1,23 @@ use crate::clients::NymClient; +use crate::identity::mixnet; +use crate::persistence::pathfinder::Pathfinder; +use crate::persistence::pemstore::PemStore; use clap::ArgMatches; pub fn execute(matches: &ArgMatches) { let is_local = matches.is_present("local"); + + let id = matches.value_of("id").unwrap().to_string(); println!("Starting client, local: {:?}", is_local); - // TODO: to be taken from config or something - let my_address = [42u8; 32]; - let is_local = true; - let client = NymClient::new(my_address, is_local); + let keypair = read_keypair_from_disk(id); + let client = NymClient::new(keypair.public_bytes(), is_local); client.start().unwrap(); } + +fn read_keypair_from_disk(id: String) -> mixnet::KeyPair { + let pathfinder = Pathfinder::new(id); + let pem_store = PemStore::new(pathfinder); + let keypair = pem_store.read(); + keypair +} From ddaf4b6a863eb3507803b2a74012e5855ca3cdad Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 14:50:36 +0000 Subject: [PATCH 7/8] commands: using Nym banner on client start --- src/commands/run.rs | 3 +++ src/commands/websocket.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/commands/run.rs b/src/commands/run.rs index e6eec43bdd..fa9d16728b 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -1,3 +1,4 @@ +use crate::banner; use crate::clients::NymClient; use crate::identity::mixnet; use crate::persistence::pathfinder::Pathfinder; @@ -5,6 +6,8 @@ use crate::persistence::pemstore::PemStore; use clap::ArgMatches; pub fn execute(matches: &ArgMatches) { + println!("{}", banner()); + let is_local = matches.is_present("local"); let id = matches.value_of("id").unwrap().to_string(); diff --git a/src/commands/websocket.rs b/src/commands/websocket.rs index 7d9889019c..dcf80afc06 100644 --- a/src/commands/websocket.rs +++ b/src/commands/websocket.rs @@ -4,6 +4,8 @@ use clap::ArgMatches; use std::net::ToSocketAddrs; pub fn execute(matches: &ArgMatches) { + println!("{}", banner()); + let port = match matches.value_of("port").unwrap().parse::() { Ok(n) => n, Err(err) => panic!("Invalid port value provided - {:?}", err), From e1822495a64f099d2f76508a8366e2522bb1ef8a Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Tue, 17 Dec 2019 15:04:25 +0000 Subject: [PATCH 8/8] socket clients: setting up with id and local parameters --- src/commands/run.rs | 16 +++------------- src/commands/tcpsocket.rs | 27 +++++++++++++++++++++++++-- src/commands/websocket.rs | 12 ++++++++++-- src/main.rs | 25 +++++++++++++++++++++++-- src/persistence/pemstore.rs | 7 +++++++ src/sockets/mod.rs | 1 + src/sockets/tcp.rs | 5 +++++ 7 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/commands/run.rs b/src/commands/run.rs index fa9d16728b..dc19422b96 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -1,26 +1,16 @@ use crate::banner; use crate::clients::NymClient; -use crate::identity::mixnet; -use crate::persistence::pathfinder::Pathfinder; -use crate::persistence::pemstore::PemStore; +use crate::persistence::pemstore; use clap::ArgMatches; pub fn execute(matches: &ArgMatches) { println!("{}", banner()); let is_local = matches.is_present("local"); - let id = matches.value_of("id").unwrap().to_string(); - println!("Starting client, local: {:?}", is_local); + println!("Starting client..."); - let keypair = read_keypair_from_disk(id); + let keypair = pemstore::read_keypair_from_disk(id); let client = NymClient::new(keypair.public_bytes(), is_local); client.start().unwrap(); } - -fn read_keypair_from_disk(id: String) -> mixnet::KeyPair { - let pathfinder = Pathfinder::new(id); - let pem_store = PemStore::new(pathfinder); - let keypair = pem_store.read(); - keypair -} diff --git a/src/commands/tcpsocket.rs b/src/commands/tcpsocket.rs index 79adfb29e6..1e3a21f1d1 100644 --- a/src/commands/tcpsocket.rs +++ b/src/commands/tcpsocket.rs @@ -1,10 +1,33 @@ +use crate::banner; +use crate::clients::NymClient; +use crate::persistence::pemstore; +use crate::sockets::tcp; + use clap::ArgMatches; +use std::net::ToSocketAddrs; pub fn execute(matches: &ArgMatches) { - let port = match matches.value_of("port").unwrap().parse::() { + println!("{}", banner()); + + let is_local = matches.is_present("local"); + let id = matches.value_of("id").unwrap().to_string(); + let port = match matches.value_of("port").unwrap_or("9001").parse::() { Ok(n) => n, Err(err) => panic!("Invalid port value provided - {:?}", err), }; - println!("On the following port: {:?}", port); + println!("Starting TCP socket on port: {:?}", port); + println!("Listening for messages..."); + + let socket_address = ("127.0.0.1", port) + .to_socket_addrs() + .expect("Failed to combine host and port") + .next() + .expect("Failed to extract the socket address from the iterator"); + + let keypair = pemstore::read_keypair_from_disk(id); + let _client = NymClient::new(keypair.public_bytes(), is_local); + // Question: should we be passing the client into the TCP socket somehow next? + + tcp::start(socket_address); } diff --git a/src/commands/websocket.rs b/src/commands/websocket.rs index dcf80afc06..cdad955d2a 100644 --- a/src/commands/websocket.rs +++ b/src/commands/websocket.rs @@ -1,17 +1,21 @@ use crate::banner; +use crate::clients::NymClient; +use crate::persistence::pemstore; use crate::sockets::ws; + use clap::ArgMatches; use std::net::ToSocketAddrs; pub fn execute(matches: &ArgMatches) { println!("{}", banner()); - let port = match matches.value_of("port").unwrap().parse::() { + let is_local = matches.is_present("local"); + let id = matches.value_of("id").unwrap().to_string(); + let port = match matches.value_of("port").unwrap_or("9001").parse::() { Ok(n) => n, Err(err) => panic!("Invalid port value provided - {:?}", err), }; - println!("{}", banner()); println!("Starting websocket on port: {:?}", port); println!("Listening for messages..."); @@ -21,5 +25,9 @@ pub fn execute(matches: &ArgMatches) { .next() .expect("Failed to extract the socket address from the iterator"); + let keypair = pemstore::read_keypair_from_disk(id); + let _client = NymClient::new(keypair.public_bytes(), is_local); + // Question: should we be passing the client into the websocket somehow next? + ws::start(socket_address); } diff --git a/src/main.rs b/src/main.rs index 2c45340ff3..c6ae48c2f5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,9 +50,19 @@ fn main() { Arg::with_name("port") .short("p") .long("port") - .help("Port to listen on") + .help("Port for TCP socket to listen on") .takes_value(true) .required(true), + ).arg(Arg::with_name("local") + .long("local") + .help("Flag to indicate whether the client is expected to run on the local deployment.") + .takes_value(false) + ) + .arg(Arg::with_name("id") + .long("id") + .help("Id of the nym-mixnet-client we want to run.") + .takes_value(true) + .required(true) ) ) .subcommand( @@ -62,10 +72,21 @@ fn main() { Arg::with_name("port") .short("p") .long("port") - .help("Port to listen on") + .help("Port for websocket to listen on") .takes_value(true) .required(true), ) + .arg(Arg::with_name("local") + .long("local") + .help("Flag to indicate whether the client is expected to run on the local deployment.") + .takes_value(false) + ) + .arg(Arg::with_name("id") + .long("id") + .help("Id of the nym-mixnet-client we want to run.") + .takes_value(true) + .required(true) + ) ) .get_matches(); diff --git a/src/persistence/pemstore.rs b/src/persistence/pemstore.rs index 02c1f5db00..037c6ab58a 100644 --- a/src/persistence/pemstore.rs +++ b/src/persistence/pemstore.rs @@ -5,6 +5,13 @@ use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; +pub fn read_keypair_from_disk(id: String) -> KeyPair { + let pathfinder = Pathfinder::new(id); + let pem_store = PemStore::new(pathfinder); + let keypair = pem_store.read(); + keypair +} + pub struct PemStore { config_dir: PathBuf, private_mix_key: PathBuf, diff --git a/src/sockets/mod.rs b/src/sockets/mod.rs index 6757c99679..86dd43f872 100644 --- a/src/sockets/mod.rs +++ b/src/sockets/mod.rs @@ -1 +1,2 @@ +pub mod tcp; pub mod ws; diff --git a/src/sockets/tcp.rs b/src/sockets/tcp.rs index e69de29bb2..a9475ab1cb 100644 --- a/src/sockets/tcp.rs +++ b/src/sockets/tcp.rs @@ -0,0 +1,5 @@ +use std::net::SocketAddr; + +pub fn start(_socket_address: SocketAddr) { + println!("TCP server time!!!"); +}