Merge branch 'develop' into feature/poisson_loop_cover_traffic

This commit is contained in:
Jedrzej Stuczynski
2019-12-16 11:46:48 +00:00
26 changed files with 322 additions and 129 deletions
Generated
+49
View File
@@ -816,6 +816,11 @@ name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazycell"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.66"
@@ -911,6 +916,17 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-named-pipes"
version = "0.1.6"
@@ -1024,6 +1040,7 @@ dependencies = [
"sfw-provider-requests 0.1.0",
"sphinx 0.1.0",
"tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1510,6 +1527,17 @@ dependencies = [
"sphinx 0.1.0",
]
[[package]]
name = "sha-1"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "sha2"
version = "0.8.0"
@@ -1975,6 +2003,23 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ws"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
@@ -2081,6 +2126,7 @@ dependencies = [
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum keystream 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
"checksum lioness 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9"
"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586"
@@ -2093,6 +2139,7 @@ dependencies = [
"checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599"
"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
@@ -2155,6 +2202,7 @@ dependencies = [
"checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0"
"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7"
"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
@@ -2207,4 +2255,5 @@ dependencies = [
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9"
"checksum ws 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a2c47b5798ccc774ffb93ff536aec7c4275d722fd9c740c83cdd1af1f2d94"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
+5
View File
@@ -4,6 +4,10 @@ version = "0.1.0"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2018"
[lib]
name = "nym_client"
path = "src/lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
@@ -20,6 +24,7 @@ serde = { version = "1.0", features = ["derive"] }
sphinx = { path = "../sphinx" }
sfw-provider-requests = { path = "../nym-sfw-provider/sfw-provider-requests" }
tokio = { version = "0.2", features = ["full"] }
ws = "0.9.1"
[dev-dependencies]
mockito = "0.22.0"
+7
View File
@@ -22,6 +22,13 @@ pub struct MixNodePresence {
pub struct MixProviderPresence {
pub host: String,
pub pub_key: String,
pub registered_clients: Vec<MixProviderClient>,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MixProviderClient {
pub pub_key: String,
}
// Topology shows us the current state of the overall Nym network
@@ -8,7 +8,7 @@ pub struct Request {
pub trait MetricsMixPoster {
fn new(base_url: String) -> Self;
fn post(&self, metric: MixMetric) -> Result<Response, reqwest::Error>;
fn post(&self, metric: &MixMetric) -> Result<Response, reqwest::Error>;
}
impl MetricsMixPoster for Request {
@@ -19,7 +19,7 @@ impl MetricsMixPoster for Request {
}
}
fn post(&self, metric: MixMetric) -> Result<Response, reqwest::Error> {
fn post(&self, metric: &MixMetric) -> Result<Response, reqwest::Error> {
let url = format!("{}{}", self.base_url, self.path);
let client = reqwest::Client::new();
let mix_metric_vec = client.post(&url).json(&metric).send()?;
@@ -43,7 +43,7 @@ mod metrics_get_request {
let _m = mock("POST", "/api/metrics/mixes").with_status(400).create();
let req = Request::new(mockito::server_url());
let metric = fixtures::new_metric();
let result = req.post(metric);
let result = req.post(&metric);
assert_eq!(400, result.unwrap().status());
_m.assert();
}
@@ -61,7 +61,7 @@ mod metrics_get_request {
.create();
let req = Request::new(mockito::server_url());
let metric = fixtures::new_metric();
let result = req.post(metric);
let result = req.post(&metric);
assert_eq!(true, result.is_ok());
_m.assert();
}
@@ -8,7 +8,7 @@ pub struct Request {
pub trait PresenceCocoNodesPoster {
fn new(base_url: String) -> Self;
fn post(&self, presence: CocoPresence) -> Result<Response, reqwest::Error>;
fn post(&self, presence: &CocoPresence) -> Result<Response, reqwest::Error>;
}
impl PresenceCocoNodesPoster for Request {
@@ -19,7 +19,7 @@ impl PresenceCocoNodesPoster for Request {
}
}
fn post(&self, presence: CocoPresence) -> Result<Response, reqwest::Error> {
fn post(&self, presence: &CocoPresence) -> Result<Response, reqwest::Error> {
let url = format!("{}{}", self.base_url, self.path);
let client = reqwest::Client::new();
let p = client.post(&url).json(&presence).send()?;
@@ -45,7 +45,7 @@ mod metrics_get_request {
.create();
let req = Request::new(mockito::server_url());
let presence = fixtures::new_presence();
let result = req.post(presence);
let result = req.post(&presence);
assert_eq!(400, result.unwrap().status());
_m.assert();
}
@@ -65,7 +65,7 @@ mod metrics_get_request {
.create();
let req = Request::new(mockito::server_url());
let presence = fixtures::new_presence();
let result = req.post(presence);
let result = req.post(&presence);
assert_eq!(true, result.is_ok());
_m.assert();
}
@@ -8,7 +8,7 @@ pub struct Request {
pub trait PresenceMixNodesPoster {
fn new(base_url: String) -> Self;
fn post(&self, presence: MixNodePresence) -> Result<Response, reqwest::Error>;
fn post(&self, presence: &MixNodePresence) -> Result<Response, reqwest::Error>;
}
impl PresenceMixNodesPoster for Request {
@@ -19,7 +19,7 @@ impl PresenceMixNodesPoster for Request {
}
}
fn post(&self, presence: MixNodePresence) -> Result<Response, reqwest::Error> {
fn post(&self, presence: &MixNodePresence) -> Result<Response, reqwest::Error> {
let url = format!("{}{}", self.base_url, self.path);
let client = reqwest::Client::new();
let p = client.post(&url).json(&presence).send()?;
@@ -45,7 +45,7 @@ mod metrics_get_request {
.create();
let req = Request::new(mockito::server_url());
let presence = fixtures::new_presence();
let result = req.post(presence);
let result = req.post(&presence);
assert_eq!(400, result.unwrap().status());
_m.assert();
}
@@ -65,7 +65,7 @@ mod metrics_get_request {
.create();
let req = Request::new(mockito::server_url());
let presence = fixtures::new_presence();
let result = req.post(presence);
let result = req.post(&presence);
assert_eq!(true, result.is_ok());
_m.assert();
}
@@ -8,18 +8,18 @@ pub struct Request {
pub trait PresenceMixProviderPoster {
fn new(base_url: String) -> Self;
fn post(&self, presence: MixProviderPresence) -> Result<Response, reqwest::Error>;
fn post(&self, presence: &MixProviderPresence) -> Result<Response, reqwest::Error>;
}
impl PresenceMixProviderPoster for Request {
fn new(base_url: String) -> Self {
Request {
base_url,
path: "/api/presence/providers".to_string(),
path: "/api/presence/mixproviders".to_string(),
}
}
fn post(&self, presence: MixProviderPresence) -> Result<Response, reqwest::Error> {
fn post(&self, presence: &MixProviderPresence) -> Result<Response, reqwest::Error> {
let url = format!("{}{}", self.base_url, self.path);
let client = reqwest::Client::new();
let p = client.post(&url).json(&presence).send()?;
@@ -40,12 +40,12 @@ mod metrics_get_request {
#[test]
fn it_returns_an_error() {
let _m = mock("POST", "/api/presence/providers")
let _m = mock("POST", "/api/presence/mixproviders")
.with_status(400)
.create();
let req = Request::new(mockito::server_url());
let presence = fixtures::new_presence();
let result = req.post(presence);
let result = req.post(&presence);
assert_eq!(400, result.unwrap().status());
_m.assert();
}
@@ -59,13 +59,13 @@ mod metrics_get_request {
let json = r#"{
"ok": true
}"#;
let _m = mock("POST", "/api/presence/providers")
let _m = mock("POST", "/api/presence/mixproviders")
.with_status(201)
.with_body(json)
.create();
let req = Request::new(mockito::server_url());
let presence = fixtures::new_presence();
let result = req.post(presence);
let result = req.post(&presence);
assert_eq!(true, result.is_ok());
_m.assert();
}
@@ -78,6 +78,7 @@ mod metrics_get_request {
MixProviderPresence {
host: "foo.com".to_string(),
pub_key: "abc".to_string(),
registered_clients: vec![],
}
}
}
+2 -2
View File
@@ -27,8 +27,8 @@ impl MixClient {
#[cfg(test)]
mod sending_a_sphinx_packet {
use super::*;
use sphinx::SphinxPacket;
// use super::*;
// use sphinx::SphinxPacket;
#[test]
fn works() {
+9 -49
View File
@@ -1,60 +1,20 @@
use crate::banner;
use crate::identity::mixnet;
use crate::persistence::pathfinder::Pathfinder;
use crate::persistence::pemstore::PemStore;
use clap::ArgMatches;
use dirs;
use pem::{encode, Pem};
use std::fs::File;
use std::io::prelude::*;
pub fn execute(matches: &ArgMatches) {
println!("{}", banner());
println!("Initialising client...");
let id = matches.value_of("id").unwrap(); // required for now
let id = matches.value_of("id").unwrap().to_string(); // required for now
let pathfinder = Pathfinder::new(id);
// don't unwrap it, pass it as it is, if it's None, choose a random
let _provider_id = matches.value_of("provider");
let _init_local = matches.is_present("local");
let os_config_dir = dirs::config_dir().unwrap();
let nym_client_config_dir = os_config_dir.join("nym").join("clients").join(id);
println!("Writing keypairs to {:?}...", nym_client_config_dir);
write_pem_files(nym_client_config_dir);
println!("Writing keypairs to {:?}...", pathfinder.config_dir);
let mix_keys = mixnet::KeyPair::new();
let pem_store = PemStore::new(pathfinder);
pem_store.write(mix_keys);
println!("Client configuration completed.\n\n\n")
}
fn write_pem_files(nym_client_config_dir: std::path::PathBuf) {
std::fs::create_dir_all(nym_client_config_dir.clone()).unwrap();
let (private, public) = sphinx::crypto::keygen();
write_pem_file(
nym_client_config_dir.clone(),
String::from("private.pem"),
private.to_bytes().to_vec(),
String::from("SPHINX CURVE25519 PRIVATE KEY"),
);
write_pem_file(
nym_client_config_dir.clone(),
String::from("public.pem"),
public.to_bytes().to_vec(),
String::from("SPHINX CURVE25519 PUBLIC KEY"),
);
}
fn write_pem_file(
nym_client_config_dir: std::path::PathBuf,
filename: String,
data: Vec<u8>,
tag: String,
) {
let pem = Pem {
tag,
contents: data,
};
let key = encode(&pem);
let full_path = nym_client_config_dir.join(filename);
let mut file = File::create(full_path).unwrap();
file.write_all(key.as_bytes()).unwrap();
}
+2 -1
View File
@@ -1,3 +1,4 @@
pub mod init;
pub mod run;
pub mod socket;
pub mod tcpsocket;
pub mod websocket;
+12 -9
View File
@@ -1,5 +1,5 @@
use crate::clients::directory;
use crate::clients::directory::presence::{MixNodePresence, Topology};
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;
@@ -16,16 +16,15 @@ use tokio::runtime::Runtime;
use tokio::time::{interval_at, Instant};
pub fn execute(matches: &ArgMatches) {
let custom_cfg = matches.value_of("customCfg");
println!(
"Going to start client with custom config of: {:?}",
custom_cfg
);
let is_local = matches.is_present("local");
println!("Starting client, local: {:?}", is_local);
// todo: to be taken from config or something
let my_address = [42u8; 32];
let client = NymClient::new(my_address);
client.start().unwrap();
// Grab the network topology from the remote directory server
let topology = get_topology(is_local);
// // Grab the network topology from the remote directory server
// let topology = get_topology();
@@ -70,10 +69,14 @@ pub fn execute(matches: &ArgMatches) {
// })
}
fn get_topology() -> Topology {
let directory_config = directory::Config {
base_url: "https://directory.nymtech.net".to_string(),
fn get_topology(is_local: bool) -> Topology {
let url = if is_local {
"http://localhost:8080".to_string()
} else {
"https://directory.nymtech.net".to_string()
};
println!("Using directory server: {:?}", url);
let directory_config = directory::Config { base_url: url };
let directory = directory::Client::new(directory_config);
let topology = directory
-21
View File
@@ -1,21 +0,0 @@
use clap::ArgMatches;
pub fn execute(matches: &ArgMatches) {
let custom_cfg = matches.value_of("customCfg");
let socket_type = match matches.value_of("socketType").unwrap() {
TCP_SOCKET_TYPE => TCP_SOCKET_TYPE,
WEBSOCKET_SOCKET_TYPE => WEBSOCKET_SOCKET_TYPE,
other => panic!("Invalid socket type provided - {}", other),
};
let port = match matches.value_of("port").unwrap().parse::<u16>() {
Ok(n) => n,
Err(err) => panic!("Invalid port value provided - {:?}", err),
};
println!(
"Going to start socket client with custom config of: {:?}",
custom_cfg
);
println!("Using the following socket type: {:?}", socket_type);
println!("On the following port: {:?}", port);
}
+10
View File
@@ -0,0 +1,10 @@
use clap::ArgMatches;
pub fn execute(matches: &ArgMatches) {
let port = match matches.value_of("port").unwrap().parse::<u16>() {
Ok(n) => n,
Err(err) => panic!("Invalid port value provided - {:?}", err),
};
println!("On the following port: {:?}", port);
}
+23
View File
@@ -0,0 +1,23 @@
use crate::banner;
use crate::sockets::ws;
use clap::ArgMatches;
use std::net::ToSocketAddrs;
pub fn execute(matches: &ArgMatches) {
let port = match matches.value_of("port").unwrap().parse::<u16>() {
Ok(n) => n,
Err(err) => panic!("Invalid port value provided - {:?}", err),
};
println!("{}", banner());
println!("Starting websocket 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");
ws::start(socket_address);
}
+35
View File
@@ -0,0 +1,35 @@
use curve25519_dalek::montgomery::MontgomeryPoint;
use curve25519_dalek::scalar::Scalar;
// This keypair serves as the user's identity within the Mixnet
pub struct KeyPair {
pub private: Scalar,
pub public: MontgomeryPoint,
}
impl KeyPair {
pub fn new() -> KeyPair {
let (private, public) = sphinx::crypto::keygen();
KeyPair { private, public }
}
pub fn from_bytes(private_bytes: Vec<u8>, public_bytes: Vec<u8>) -> KeyPair {
let mut bytes = [0; 32];
bytes.copy_from_slice(&private_bytes[..]);
let private = Scalar::from_canonical_bytes(bytes).unwrap();
let mut bytes = [0; 32];
bytes.copy_from_slice(&public_bytes[..]);
let public = MontgomeryPoint(bytes);
KeyPair { private, public }
}
pub fn private_bytes(&self) -> Vec<u8> {
self.private.to_bytes().to_vec()
}
pub fn public_bytes(&self) -> Vec<u8> {
self.public.to_bytes().to_vec()
}
}
+1
View File
@@ -0,0 +1 @@
pub mod mixnet;
+1
View File
@@ -0,0 +1 @@
// TODO types for Validator keys will go in here once we hook this up.
+1
View File
@@ -0,0 +1 @@
pub mod clients;
+21 -28
View File
@@ -3,6 +3,9 @@ use std::process;
mod clients;
mod commands;
mod identity;
mod persistence;
mod sockets;
mod utils;
fn main() {
@@ -24,41 +27,31 @@ fn main() {
.help("Id of the provider we have preference to connect to. If left empty, a random provider will be chosen.")
.takes_value(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(true)
)
)
.subcommand(
SubCommand::with_name("run")
.about("Run a persistent Nym client process")
.arg(
Arg::with_name("customCfg")
.short("cfg")
.long("customCfg")
.help("Path to custom configuration file of the client")
.takes_value(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)
)
)
.subcommand(
SubCommand::with_name("socket")
.about("Run a background Nym client listening on a specified socket")
SubCommand::with_name("tcpsocket")
.about("Run Nym client that listens for bytes on a TCP socket")
.arg(
Arg::with_name("customCfg")
.short("cfg")
.long("customCfg")
.help("Path to custom configuration file of the client")
Arg::with_name("port")
.short("p")
.long("port")
.help("Port to listen on")
.takes_value(true)
.required(true),
)
.arg(
Arg::with_name("socketType")
.short("s")
.long("socketType")
.help("Type of the socket we want to run on (tcp / websocket)")
.takes_value(true)
.required(true)
)
)
.subcommand(
SubCommand::with_name("websocket")
.about("Run Nym client that listens on a websocket")
.arg(
Arg::with_name("port")
.short("p")
@@ -80,14 +73,14 @@ fn execute(matches: ArgMatches) -> Result<(), String> {
match matches.subcommand() {
("init", Some(m)) => Ok(commands::init::execute(m)),
("run", Some(m)) => Ok(commands::run::execute(m)),
("socket", Some(m)) => Ok(commands::socket::execute(m)),
("tcpsocket", Some(m)) => Ok(commands::tcpsocket::execute(m)),
("websocket", Some(m)) => Ok(commands::websocket::execute(m)),
_ => Err(usage()),
}
}
fn usage() -> String {
banner() + "usage: --help to see available options."
banner() + "usage: --help to see available options.\n\n"
}
fn banner() -> String {
+2
View File
@@ -0,0 +1,2 @@
pub mod pathfinder;
pub mod pemstore;
+21
View File
@@ -0,0 +1,21 @@
use std::path::PathBuf;
pub struct Pathfinder {
pub config_dir: PathBuf,
pub private_mix_key: PathBuf,
pub public_mix_key: PathBuf,
}
impl Pathfinder {
pub fn new(id: String) -> Pathfinder {
let os_config_dir = dirs::config_dir().unwrap(); // grabs the OS default config dir
let config_dir = os_config_dir.join("nym").join("clients").join(id);
let private_mix_key = config_dir.join("private.pem");
let public_mix_key = config_dir.join("public.pem");
Pathfinder {
config_dir,
private_mix_key,
public_mix_key,
}
}
}
+65
View File
@@ -0,0 +1,65 @@
use crate::identity::mixnet::KeyPair;
use crate::persistence::pathfinder::Pathfinder;
use pem::{encode, parse, Pem};
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
pub struct PemStore {
config_dir: PathBuf,
private_mix_key: PathBuf,
public_mix_key: PathBuf,
}
impl PemStore {
pub fn new(pathfinder: Pathfinder) -> PemStore {
PemStore {
config_dir: pathfinder.config_dir,
private_mix_key: pathfinder.private_mix_key,
public_mix_key: pathfinder.public_mix_key,
}
}
pub fn read(&self) -> KeyPair {
let private = self.read_file(self.private_mix_key.clone());
let public = self.read_file(self.public_mix_key.clone());
KeyPair::from_bytes(private, public)
}
fn read_file(&self, filepath: PathBuf) -> Vec<u8> {
let mut pem_bytes = File::open(filepath).unwrap();
let mut buf = Vec::new();
pem_bytes.read_to_end(&mut buf).unwrap();
let pem = parse(&buf).unwrap();
pem.contents
}
// This should be refactored and made more generic for when we have other kinds of
// KeyPairs that we want to persist (e.g. validator keypairs, or keys for
// signing vs encryption). However, for the moment, it does the job.
pub fn write(&self, key_pair: KeyPair) {
std::fs::create_dir_all(self.config_dir.clone()).unwrap();
self.write_pem_file(
self.private_mix_key.clone(),
key_pair.private_bytes(),
String::from("SPHINX CURVE25519 PRIVATE KEY"),
);
self.write_pem_file(
self.public_mix_key.clone(),
key_pair.public_bytes(),
String::from("SPHINX CURVE25519 PUBLIC KEY"),
);
}
fn write_pem_file(&self, filepath: PathBuf, data: Vec<u8>, tag: String) {
let pem = Pem {
tag,
contents: data,
};
let key = encode(&pem);
let mut file = File::create(filepath).unwrap();
file.write_all(key.as_bytes()).unwrap();
}
}
+1
View File
@@ -0,0 +1 @@
// TODO: we can put all the TOML config templating code in here once we get to that.
+1
View File
@@ -0,0 +1 @@
pub mod ws;
View File
+34
View File
@@ -0,0 +1,34 @@
use std::net::SocketAddr;
use ws::{listen, CloseCode, Handler, Message, Result, Sender};
struct Server {
out: Sender,
}
impl Handler for Server {
fn on_message(&mut self, msg: Message) -> Result<()> {
foomp(msg.clone());
// Echo the message back
self.out.send(msg)
}
fn on_close(&mut self, code: CloseCode, reason: &str) {
match code {
CloseCode::Normal => println!("The client is done with the connection."),
CloseCode::Away => println!("The client is leaving the site."),
_ => {
println!("The client encountered an error: {}", reason);
}
}
}
}
pub fn start(socket_address: SocketAddr) {
listen(socket_address, |out| Server { out: out }).unwrap()
}
// Proves we can call Rust methods from the websocket listener. Re-route it to wherever JS puts
// the `send_message` functionality.
fn foomp(msg: Message) {
println!("Foomp!: {:?}", msg);
}