+26
-26
@@ -1,6 +1,7 @@
|
||||
use crate::provider::presence;
|
||||
use crate::provider::ServiceProvider;
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use nym_client::identity::mixnet::KeyPair;
|
||||
use std::net::ToSocketAddrs;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
@@ -40,20 +41,12 @@ fn main() {
|
||||
.help("The port on which the service provider will be listening for client sfw-provider-requests")
|
||||
.takes_value(true)
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("keyfile")
|
||||
.short("k")
|
||||
.long("keyfile")
|
||||
.help("Optional path to the persistent keyfile of the node")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("storeDir")
|
||||
.short("s")
|
||||
.long("storeDir")
|
||||
.help("Directory storing all packets for the clients")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("registeredLedger")
|
||||
@@ -61,7 +54,6 @@ fn main() {
|
||||
.long("registeredLedger")
|
||||
.help("Directory of the ledger of registered clients")
|
||||
.takes_value(true)
|
||||
.required(true),
|
||||
).arg(Arg::with_name("local")
|
||||
.long("local")
|
||||
.help("Flag to indicate whether the provider should run on a local deployment.")
|
||||
@@ -89,13 +81,6 @@ fn run(matches: &ArgMatches) {
|
||||
provider.start().unwrap()
|
||||
}
|
||||
|
||||
fn execute(matches: ArgMatches) -> Result<(), String> {
|
||||
match matches.subcommand() {
|
||||
("run", Some(m)) => Ok(run(m)),
|
||||
_ => Err(usage()),
|
||||
}
|
||||
}
|
||||
|
||||
fn new_config(matches: &ArgMatches) -> provider::Config {
|
||||
println!("Running the service provider!");
|
||||
let is_local = matches.is_present("local");
|
||||
@@ -109,7 +94,7 @@ fn new_config(matches: &ArgMatches) -> provider::Config {
|
||||
let mix_host = matches.value_of("mixHost").unwrap_or("0.0.0.0");
|
||||
let mix_port = match matches.value_of("mixPort").unwrap_or("8085").parse::<u16>() {
|
||||
Ok(n) => n,
|
||||
Err(err) => panic!("Invalid port value provided - {:?}", err),
|
||||
Err(err) => panic!("Invalid mix host port value provided - {:?}", err),
|
||||
};
|
||||
|
||||
let client_host = matches.value_of("clientHost").unwrap_or("0.0.0.0");
|
||||
@@ -119,18 +104,26 @@ fn new_config(matches: &ArgMatches) -> provider::Config {
|
||||
.parse::<u16>()
|
||||
{
|
||||
Ok(n) => n,
|
||||
Err(err) => panic!("Invalid port value provided - {:?}", err),
|
||||
Err(err) => panic!("Invalid client port value provided - {:?}", err),
|
||||
};
|
||||
|
||||
let store_dir = PathBuf::from(matches.value_of("storeDir").unwrap_or("/tmp/nym-provider"));
|
||||
let registered_client_ledger_dir = PathBuf::from(matches.value_of("registeredLedger").unwrap());
|
||||
let (secret_key, public_key) = sphinx::crypto::keygen();
|
||||
let key_pair = KeyPair::new(); // TODO: persist this so keypairs don't change every restart
|
||||
let store_dir = PathBuf::from(
|
||||
matches
|
||||
.value_of("storeDir")
|
||||
.unwrap_or("/tmp/nym-provider/inboxes"),
|
||||
);
|
||||
let registered_client_ledger_dir = PathBuf::from(
|
||||
matches
|
||||
.value_of("registeredLedger")
|
||||
.unwrap_or("/tmp/nym-provider/registered_clients"),
|
||||
);
|
||||
|
||||
println!("The value of mix_host is: {:?}", mix_host);
|
||||
println!("The value of mix_port is: {:?}", mix_port);
|
||||
println!("The value of client_host is: {:?}", client_host);
|
||||
println!("The value of client_port is: {:?}", client_port);
|
||||
println!("The value of key is: {:?}", secret_key);
|
||||
println!("The value of key is: {:?}", key_pair.private.clone());
|
||||
println!("The value of store_dir is: {:?}", store_dir);
|
||||
println!(
|
||||
"The value of registered_client_ledger_dir is: {:?}",
|
||||
@@ -159,15 +152,22 @@ fn new_config(matches: &ArgMatches) -> provider::Config {
|
||||
);
|
||||
|
||||
provider::Config {
|
||||
directory_server,
|
||||
public_key,
|
||||
client_socket_address,
|
||||
mix_socket_address,
|
||||
secret_key,
|
||||
directory_server,
|
||||
public_key: key_pair.public,
|
||||
client_socket_address,
|
||||
secret_key: key_pair.private,
|
||||
store_dir: PathBuf::from(store_dir),
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(matches: ArgMatches) -> Result<(), String> {
|
||||
match matches.subcommand() {
|
||||
("run", Some(m)) => Ok(run(m)),
|
||||
_ => Err(usage()),
|
||||
}
|
||||
}
|
||||
|
||||
fn usage() -> String {
|
||||
banner() + "usage: --help to see available options.\n\n"
|
||||
}
|
||||
|
||||
@@ -4,15 +4,14 @@ use curve25519_dalek::scalar::Scalar;
|
||||
use futures::lock::Mutex as FMutex;
|
||||
use hmac::{Hmac, Mac};
|
||||
use sfw_provider_requests::requests::{
|
||||
ProviderRequestError, ProviderRequests, PullRequest,
|
||||
RegisterRequest,
|
||||
ProviderRequestError, ProviderRequests, PullRequest, RegisterRequest,
|
||||
};
|
||||
use sfw_provider_requests::responses::{ProviderResponse, PullResponse, RegisterResponse};
|
||||
use sfw_provider_requests::AuthToken;
|
||||
use sha2::Sha256;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use sfw_provider_requests::AuthToken;
|
||||
|
||||
type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
@@ -88,11 +87,14 @@ impl ClientRequestProcessor {
|
||||
ProviderRequests::Register(req) => Ok(ClientRequestProcessor::register_new_client(
|
||||
req,
|
||||
processing_data,
|
||||
).await?.to_bytes()),
|
||||
ProviderRequests::PullMessages(req) => Ok(ClientRequestProcessor::process_pull_messages_request(
|
||||
req,
|
||||
processing_data,
|
||||
).await?.to_bytes())
|
||||
)
|
||||
.await?
|
||||
.to_bytes()),
|
||||
ProviderRequests::PullMessages(req) => Ok(
|
||||
ClientRequestProcessor::process_pull_messages_request(req, processing_data)
|
||||
.await?
|
||||
.to_bytes(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,8 +111,10 @@ impl ClientRequestProcessor {
|
||||
let store_dir_clone = unlocked.store_dir.clone();
|
||||
// drop the mutex so that we could do IO without blocking others wanting to get the lock
|
||||
drop(unlocked);
|
||||
let retrieved_messages =
|
||||
ClientStorage::retrieve_client_files(req.destination_address, store_dir_clone.as_path())?;
|
||||
let retrieved_messages = ClientStorage::retrieve_client_files(
|
||||
req.destination_address,
|
||||
store_dir_clone.as_path(),
|
||||
)?;
|
||||
Ok(PullResponse::new(retrieved_messages))
|
||||
} else {
|
||||
Err(ClientProcessingError::WrongToken)
|
||||
@@ -129,8 +133,13 @@ impl ClientRequestProcessor {
|
||||
unlocked.secret_key,
|
||||
);
|
||||
if !unlocked.registered_clients_ledger.has_token(auth_token) {
|
||||
unlocked.registered_clients_ledger.insert_token(auth_token, req.destination_address);
|
||||
ClientRequestProcessor::create_storage_dir(req.destination_address, unlocked.store_dir.as_path())?;
|
||||
unlocked
|
||||
.registered_clients_ledger
|
||||
.insert_token(auth_token, req.destination_address);
|
||||
ClientRequestProcessor::create_storage_dir(
|
||||
req.destination_address,
|
||||
unlocked.store_dir.as_path(),
|
||||
)?;
|
||||
}
|
||||
Ok(RegisterResponse::new(auth_token))
|
||||
}
|
||||
@@ -156,66 +165,66 @@ impl ClientRequestProcessor {
|
||||
|
||||
#[cfg(test)]
|
||||
mod register_new_client {
|
||||
use super::*;
|
||||
// use super::*;
|
||||
|
||||
// TODO: those tests require being called in async context. we need to research how to test this stuff...
|
||||
// #[test]
|
||||
// fn registers_new_auth_token_for_each_new_client() {
|
||||
// let req1 = RegisterRequest {
|
||||
// destination_address: [1u8; 32],
|
||||
// };
|
||||
// let registered_client_ledger = ClientLedger::new();
|
||||
// let store_dir = PathBuf::from("./foo/");
|
||||
// let key = Scalar::from_bytes_mod_order([1u8; 32]);
|
||||
// let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex();
|
||||
//
|
||||
//
|
||||
// // need to do async....
|
||||
// client_processing_data.lock().await;
|
||||
// assert_eq!(0, registered_client_ledger.0.len());
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req1,
|
||||
// client_processing_data.clone(),
|
||||
// );
|
||||
//
|
||||
// assert_eq!(1, registered_client_ledger.0.len());
|
||||
//
|
||||
// let req2 = RegisterRequest {
|
||||
// destination_address: [2u8; 32],
|
||||
// };
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req2,
|
||||
// client_processing_data,
|
||||
// );
|
||||
// assert_eq!(2, registered_client_ledger.0.len());
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn registers_given_token_only_once() {
|
||||
// let req1 = RegisterRequest {
|
||||
// destination_address: [1u8; 32],
|
||||
// };
|
||||
// let registered_client_ledger = ClientLedger::new();
|
||||
// let store_dir = PathBuf::from("./foo/");
|
||||
// let key = Scalar::from_bytes_mod_order([1u8; 32]);
|
||||
// let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex();
|
||||
//
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req1,
|
||||
// client_processing_data.clone(),
|
||||
// );
|
||||
// let req2 = RegisterRequest {
|
||||
// destination_address: [1u8; 32],
|
||||
// };
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req2,
|
||||
// client_processing_data.clone(),
|
||||
// );
|
||||
//
|
||||
// client_processing_data.lock().await;
|
||||
//
|
||||
// assert_eq!(1, registered_client_ledger.0.len())
|
||||
// }
|
||||
// #[test]
|
||||
// fn registers_new_auth_token_for_each_new_client() {
|
||||
// let req1 = RegisterRequest {
|
||||
// destination_address: [1u8; 32],
|
||||
// };
|
||||
// let registered_client_ledger = ClientLedger::new();
|
||||
// let store_dir = PathBuf::from("./foo/");
|
||||
// let key = Scalar::from_bytes_mod_order([1u8; 32]);
|
||||
// let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex();
|
||||
//
|
||||
//
|
||||
// // need to do async....
|
||||
// client_processing_data.lock().await;
|
||||
// assert_eq!(0, registered_client_ledger.0.len());
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req1,
|
||||
// client_processing_data.clone(),
|
||||
// );
|
||||
//
|
||||
// assert_eq!(1, registered_client_ledger.0.len());
|
||||
//
|
||||
// let req2 = RegisterRequest {
|
||||
// destination_address: [2u8; 32],
|
||||
// };
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req2,
|
||||
// client_processing_data,
|
||||
// );
|
||||
// assert_eq!(2, registered_client_ledger.0.len());
|
||||
// }
|
||||
//
|
||||
// #[test]
|
||||
// fn registers_given_token_only_once() {
|
||||
// let req1 = RegisterRequest {
|
||||
// destination_address: [1u8; 32],
|
||||
// };
|
||||
// let registered_client_ledger = ClientLedger::new();
|
||||
// let store_dir = PathBuf::from("./foo/");
|
||||
// let key = Scalar::from_bytes_mod_order([1u8; 32]);
|
||||
// let client_processing_data = ClientProcessingData::new(store_dir, registered_client_ledger, key).add_arc_futures_mutex();
|
||||
//
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req1,
|
||||
// client_processing_data.clone(),
|
||||
// );
|
||||
// let req2 = RegisterRequest {
|
||||
// destination_address: [1u8; 32],
|
||||
// };
|
||||
// ClientRequestProcessor::register_new_client(
|
||||
// req2,
|
||||
// client_processing_data.clone(),
|
||||
// );
|
||||
//
|
||||
// client_processing_data.lock().await;
|
||||
//
|
||||
// assert_eq!(1, registered_client_ledger.0.len())
|
||||
// }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -227,7 +236,7 @@ mod create_storage_dir {
|
||||
fn it_creates_a_correct_storage_directory() {
|
||||
let client_address: DestinationAddressBytes = [1u8; 32];
|
||||
let store_dir = Path::new("./foo/");
|
||||
ClientRequestProcessor::create_storage_dir(client_address, store_dir);
|
||||
ClientRequestProcessor::create_storage_dir(client_address, store_dir).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-17
@@ -1,19 +1,19 @@
|
||||
use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor};
|
||||
use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData};
|
||||
use crate::provider::storage::ClientStorage;
|
||||
use curve25519_dalek::montgomery::MontgomeryPoint;
|
||||
use curve25519_dalek::scalar::Scalar;
|
||||
use futures::io::Error;
|
||||
use futures::lock::Mutex as FMutex;
|
||||
use sfw_provider_requests::AuthToken;
|
||||
use sphinx::route::DestinationAddressBytes;
|
||||
use std::collections::HashMap;
|
||||
use std::net::{Shutdown, SocketAddr};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use curve25519_dalek::montgomery::MontgomeryPoint;
|
||||
use curve25519_dalek::scalar::Scalar;
|
||||
use tokio::prelude::*;
|
||||
use tokio::runtime::Runtime;
|
||||
use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor};
|
||||
use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData};
|
||||
use crate::provider::storage::ClientStorage;
|
||||
use futures::io::Error;
|
||||
use sfw_provider_requests::AuthToken;
|
||||
use sphinx::route::DestinationAddressBytes;
|
||||
use std::collections::HashMap;
|
||||
use futures::lock::Mutex as FMutex;
|
||||
|
||||
mod client_handling;
|
||||
mod mix_handling;
|
||||
@@ -75,10 +75,14 @@ impl ClientLedger {
|
||||
}
|
||||
|
||||
fn has_token(&self, auth_token: AuthToken) -> bool {
|
||||
return self.0.contains_key(&auth_token)
|
||||
return self.0.contains_key(&auth_token);
|
||||
}
|
||||
|
||||
fn insert_token(&mut self, auth_token: AuthToken, client_address: DestinationAddressBytes) -> Option<DestinationAddressBytes>{
|
||||
fn insert_token(
|
||||
&mut self,
|
||||
auth_token: AuthToken,
|
||||
client_address: DestinationAddressBytes,
|
||||
) -> Option<DestinationAddressBytes> {
|
||||
self.0.insert(auth_token, client_address)
|
||||
}
|
||||
|
||||
@@ -137,10 +141,10 @@ impl ServiceProvider {
|
||||
store_data,
|
||||
processing_data.read().unwrap().store_dir.as_path(),
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("failed to store processed sphinx message; err = {:?}", e);
|
||||
return;
|
||||
});
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("failed to store processed sphinx message; err = {:?}", e);
|
||||
return;
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("failed to read from socket; err = {:?}", e);
|
||||
@@ -183,7 +187,9 @@ impl ServiceProvider {
|
||||
match ClientRequestProcessor::process_client_request(
|
||||
buf[..n].as_ref(),
|
||||
processing_data,
|
||||
).await {
|
||||
)
|
||||
.await
|
||||
{
|
||||
Err(e) => {
|
||||
eprintln!("failed to process client request; err = {:?}", e);
|
||||
Err(())
|
||||
|
||||
@@ -5,7 +5,6 @@ use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use nym_client::clients::directory::presence::MixProviderPresence;
|
||||
|
||||
use nym_client::clients::directory::requests::presence_providers_post::PresenceMixProviderPoster;
|
||||
|
||||
pub struct Notifier {
|
||||
|
||||
Reference in New Issue
Block a user