Browse Source

client: add some timing noise to first connection

Justin Tracey 2 months ago
parent
commit
958648ce92
3 changed files with 14 additions and 2 deletions
  1. 1 0
      Cargo.toml
  2. 12 1
      src/bin/mgen-client.rs
  3. 1 1
      src/bin/mgen-server.rs

+ 1 - 0
Cargo.toml

@@ -15,6 +15,7 @@ hyper-socks2 = { version = "0.8.0", default-features = false, features = ["rustl
 rand = "0.8.5"
 rand_distr = { version = "0.4.3", features = ["serde1"] }
 rand_xoshiro = "0.6.0"
+rustc-hash = "1.1.0"
 rustls-pemfile = "1.0.3"
 serde = { version = "1.0.158", features = ["derive"] }
 serde_yaml = "0.9.21"

+ 12 - 1
src/bin/mgen-client.rs

@@ -5,13 +5,14 @@ use mgen::{log, updater::Updater, HandshakeRef, MessageHeader, SerializedMessage
 use futures::future::try_join_all;
 use rand_xoshiro::{rand_core::SeedableRng, Xoshiro256PlusPlus};
 use serde::Deserialize;
+use std::hash::{Hash, Hasher};
 use std::result::Result;
 use std::sync::Arc;
 use tokio::io::{split, AsyncWriteExt, ReadHalf, WriteHalf};
 use tokio::net::TcpStream;
 use tokio::spawn;
 use tokio::sync::mpsc;
-use tokio::time::Duration;
+use tokio::time::{sleep, Duration};
 use tokio_rustls::{client::TlsStream, TlsConnector};
 
 mod messenger;
@@ -293,6 +294,7 @@ async fn socket_updater(
     let tls_server_str = str_params.target.split(':').next().unwrap();
     let tls_server_name =
         tokio_rustls::rustls::ServerName::try_from(tls_server_str).expect("invalid server name");
+
     loop {
         let stream: TcpStream = match connect(&str_params).await {
             Ok(stream) => stream,
@@ -395,6 +397,15 @@ async fn manage_conversation(
 
 /// Spawns all other threads for this conversation.
 async fn spawn_threads(config: FullConfig) -> Result<(), MessengerError> {
+    // without noise during Shadow's bootstrap period, we can overload the SOMAXCONN of the server,
+    // so we wait a small(ish) pseudorandom amount of time to spread things out
+    let mut hasher = rustc_hash::FxHasher::default();
+    config.user.hash(&mut hasher);
+    config.group.hash(&mut hasher);
+    let hash = hasher.finish() % 10_000;
+    log!("{},{},waiting,{}", config.user, config.group, hash);
+    sleep(Duration::from_millis(hash)).await;
+
     let message_server_params = SocksParams {
         socks: config.socks.clone(),
         target: config.message_server.clone(),

+ 1 - 1
src/bin/mgen-server.rs

@@ -65,7 +65,7 @@ async fn main_worker() -> Result<(), Box<dyn Error>> {
 
     let listen_addr = args.next().unwrap_or("127.0.0.1:6397".to_string());
 
-    let reg_time = args.next().unwrap_or("5".to_string()).parse()?;
+    let reg_time = args.next().unwrap_or("30".to_string()).parse()?;
     let reg_time = Instant::now() + Duration::from_secs(reg_time);
 
     let certfile = std::fs::File::open(cert_filename).expect("cannot open certificate file");