From a95efd9ed8b6f4dd2a67760c02e5a3574d3f147c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Eng=C3=A9libert?= Date: Tue, 17 Mar 2026 11:12:44 +0100 Subject: [PATCH] Clean readme, replace Arcs with leaked Boxes --- Cargo.toml | 5 +++-- README.md | 22 +++++++--------------- src/client.rs | 23 +++++++---------------- src/server.rs | 4 ++-- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8136b02..57ed7c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,12 +27,13 @@ rustls-symcrypt = { version = "0.2.1", optional = true, features = ["chacha", "x [features] default = [ - "aws-lc", - #"record", + "aws-lc",# Change this to the wanted cryptographic backend (list below) + "record",# It may be needed to remove the record feature when building with openssl ] record = ["sslrelay"] +# Available cryptographic backends aws-lc = ["tokio-rustls/aws-lc-rs", "rustls-post-quantum", "rustls-post-quantum/aws-lc-rs-unstable", "aws-lc-rs"] boring = ["boring-rustls-provider"] graviola = ["rustls-graviola"] diff --git a/README.md b/README.md index 5cb5ec8..cced279 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,7 @@ This program has two modes: * recording proxy: relays trafic with or without TLS and record requests and responses in clear. It is a TLS termination thus a certificate is needed. -* trafic replay: run a client that sends the recorded requests, and a server that responds with the corresponding recorded responses. A proxy can be placed in between. The proxy can even alter the plain data, because the server uses hash distance to identify the requests. - -It has been tested with HTTP trafic only. Other protocols which are not request/response (or even websocket) may not be recorded properly. +* trafic replay: run a client that sends the recorded requests, and a server that responds with the corresponding recorded responses. Responses are replaced with the same amount of random bytes for performance. It relies on the server name extension in TLS (SNI). Requests without server name may not be recorded. @@ -12,27 +10,21 @@ For experimental purpose. Do not use on an open network where security matters. ## Build +[Install Rust nightly.](https://rustup.rs) + +Choose a cryptographic backend in `Cargo.toml`. + ```bash -RUSTFLAGS="--cfg tokio_unstable" cargo build --release +cargo build --release ``` -## Record file format - -The record file is a list of records. Each record follows this format: -* [1 byte] direction: ASCII 'C' for client-to-server, 'S' for server-to-client -* [8 bytes] connection id, big endian -* [1 byte] server name length -* server name (TLS's SNI or HTTP's Host) -* [8 bytes] data length, big endian -* data - ## SSLKEYLOGFILE The `SSLKEYLOGFILE` environment variable can be set to a file path to which the connection secrets will be exported, enabling decrypting the traffic in Wireshark. ## License -GNU AGPL v3, CopyLeft 2025 Pascal EngĂ©libert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/) +GNU AGPL v3, CopyLeft 2025-2026 Pascal EngĂ©libert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. diff --git a/src/client.rs b/src/client.rs index b0d6df7..5d0d9b3 100644 --- a/src/client.rs +++ b/src/client.rs @@ -102,25 +102,24 @@ pub async fn play( ) { // Semaphore used to limit the number of concurrent clients. // Its handle is released when the task panics. - let limiter = Arc::new(Semaphore::new(concurrency)); - let counter = Arc::new(AtomicU32::new(0)); - let running = Arc::new(Mutex::new(HashSet::new())); + let limiter: &'static _ = Box::leak(Box::new(Semaphore::new(concurrency))); + let counter: &'static _ = Box::leak(Box::new(AtomicU32::new(0))); + let running: &'static _ = Box::leak(Box::new(Mutex::new(HashSet::new()))); let total = records.len() * repeat as usize; let connect_to = connect_to.to_socket_addrs().unwrap().next().unwrap(); - let dummy_bytes = Arc::new(vec![0x42u8; 16 * 1024 * 1024]); + let dummy_bytes: &'static _ = Box::leak(Box::new(vec![0x42u8; 16 * 1024 * 1024])); let notify_socket = notify_addr.map(|notify_addr| { let socket = std::net::UdpSocket::bind("0.0.0.0:48567").unwrap(); socket.connect(notify_addr).unwrap(); - Arc::new(socket) + let socket: &'static _ = Box::leak(Box::new(socket)); + socket }); tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; tokio::spawn({ - let running = running.clone(); - let counter = counter.clone(); async move { let mut last_count = 0; loop { @@ -197,11 +196,7 @@ pub async fn play( let mut handles = Vec::new(); for (conn_id, (server_name, records)) in records.iter() { let connector = TlsConnector::from(config.clone()); - let counter = counter.clone(); - let limiter = limiter.clone(); - let running = running.clone(); let dummy_bytes = dummy_bytes.clone(); - let notify_socket = notify_socket.clone(); handles.push(tokio::spawn(async move { let mut running_guard = running.lock().await; running_guard.insert(*conn_id); @@ -294,11 +289,7 @@ pub async fn play( for _i in 0..repeat { let mut handles = Vec::new(); for (conn_id, (_server_name, records)) in records.iter() { - let counter = counter.clone(); - let limiter = limiter.clone(); - let running = running.clone(); let dummy_bytes = dummy_bytes.clone(); - let notify_socket = notify_socket.clone(); handles.push(tokio::spawn(async move { let mut running_guard = running.lock().await; running_guard.insert(*conn_id); @@ -366,7 +357,7 @@ pub async fn play( println!("Client: {} / {}", cnt, total); } drop(limiter); - if let Some(notify_socket) = ¬ify_socket { + if let Some(notify_socket) = notify_socket { notify_socket.send(&cnt.to_be_bytes()).unwrap(); } let mut running_guard = running.lock().await; diff --git a/src/server.rs b/src/server.rs index 92c44a7..63bf580 100644 --- a/src/server.rs +++ b/src/server.rs @@ -48,8 +48,8 @@ pub async fn play( } } - let response_map = Arc::new(response_map); - let dummy_bytes = Arc::new(vec![0x42u8; 16 * 1024 * 1024]); + let response_map: &'static _ = Box::leak(Box::new(response_map)); + let dummy_bytes: &'static _ = Box::leak(Box::new(vec![0x42u8; 16 * 1024 * 1024])); if use_tls { let mut resolver = ResolvesServerCertUsingSni::new();