-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
253 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "optimistic-quic" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
bytes = "1" | ||
mimalloc = { version = "0.1", default-features = false } | ||
s2n-quic = { path = "../../quic/s2n-quic", features = ["provider-event-tracing"] } | ||
tokio = { version = "1", features = ["full"] } | ||
tracing-subscriber = { version = "0.3", features = ["env-filter"] } | ||
|
||
[workspace] | ||
members = ["."] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[toolchain] | ||
channel = "1.71.0" | ||
components = [ "rustc", "clippy", "rustfmt" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
use bytes::Bytes; | ||
use core::time::Duration; | ||
use s2n_quic::{ | ||
client::Connect, | ||
connection, | ||
provider::{event::tracing, limits::Limits, tls}, | ||
Client, | ||
}; | ||
use std::{ | ||
net::SocketAddr, | ||
sync::{ | ||
atomic::{AtomicU64, Ordering}, | ||
Arc, | ||
}, | ||
}; | ||
use tokio::time::sleep; | ||
|
||
#[global_allocator] | ||
static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc; | ||
|
||
type Error = Box<dyn 'static + std::error::Error + Send + Sync>; | ||
type Result<T = (), E = Error> = core::result::Result<T, E>; | ||
|
||
macro_rules! log { | ||
($($tt:tt)*) => { | ||
// println!($($tt)*); | ||
}; | ||
} | ||
|
||
fn main() { | ||
let format = tracing_subscriber::fmt::format() | ||
.with_level(false) // don't include levels in formatted output | ||
.with_timer(tracing_subscriber::fmt::time::uptime()) | ||
.with_ansi(false) | ||
.compact(); // Use a less verbose output format. | ||
|
||
tracing_subscriber::fmt() | ||
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) | ||
.event_format(format) | ||
.init(); | ||
|
||
let counter = Arc::new(AtomicU64::new(0)); | ||
std::thread::spawn({ | ||
let counter = counter.clone(); | ||
move || loop { | ||
std::thread::sleep(Duration::from_secs(1)); | ||
let count = counter.swap(0, Ordering::Relaxed); | ||
println!("{count} RPS"); | ||
} | ||
}); | ||
|
||
let mut threads = vec![]; | ||
|
||
for _ in 0..1 { | ||
let counter = counter.clone(); | ||
threads.push(std::thread::spawn(move || runner(counter))); | ||
} | ||
|
||
for thread in threads { | ||
let _ = thread.join(); | ||
} | ||
} | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
async fn runner(counter: Arc<AtomicU64>) -> Result { | ||
let mut tls = tls::default::Client::builder().with_application_protocols(&[ | ||
"h3", | ||
"hq-interop", | ||
"perf", | ||
])?; | ||
|
||
unsafe { | ||
tls.config_mut().disable_x509_verification()?; | ||
} | ||
|
||
let tls = tls.build()?; | ||
|
||
let limits = Limits::default() | ||
.with_max_open_local_unidirectional_streams(u32::MAX as _)? | ||
.with_max_open_remote_unidirectional_streams(u32::MAX as _)? | ||
.with_max_open_local_bidirectional_streams(u32::MAX as _)? | ||
.with_max_open_remote_bidirectional_streams(u32::MAX as _)?; | ||
|
||
let client = Client::builder() | ||
.with_io("0.0.0.0:0")? | ||
.with_tls(tls)? | ||
.with_event(tracing::Provider::default())? | ||
.with_limits(limits)? | ||
.start()?; | ||
|
||
/* | ||
let host = std::env::args().nth(1).expect("missing server address"); | ||
let addr = tokio::net::lookup_host(&host).await?.next().unwrap(); | ||
dbg!(&host, &addr); | ||
*/ | ||
|
||
let host = "localhost"; | ||
let addr: std::net::SocketAddr = "192.167.1.20:4433".parse()?; | ||
|
||
//let host = "d4fzfzsp0rgmq.gamma.aws100.com"; | ||
//let addr: std::net::SocketAddr = "130.176.161.19:443".parse()?; | ||
|
||
for _ in 0..10000 { | ||
tokio::spawn(actor( | ||
client.clone(), | ||
host.to_string(), | ||
addr, | ||
counter.clone(), | ||
)); | ||
} | ||
|
||
actor(client, host.to_string(), addr, counter).await | ||
} | ||
|
||
async fn actor(client: Client, host: String, addr: SocketAddr, counter: Arc<AtomicU64>) -> Result { | ||
loop { | ||
let Ok(mut conn) = connect(&client, &host, addr).await else { | ||
continue; | ||
}; | ||
|
||
let mut burst = 1; | ||
|
||
log!("probing burst"); | ||
|
||
loop { | ||
let candidate = burst + 1; | ||
log!("trying burst: {candidate}"); | ||
|
||
if let Err(err) = attack(&mut conn, candidate, &counter).await { | ||
log!("{err}"); | ||
break; | ||
} | ||
|
||
burst = candidate; | ||
} | ||
|
||
if burst == 0 { | ||
continue; | ||
} | ||
|
||
log!("selected burst: {burst}"); | ||
|
||
'retry_probe: loop { | ||
if let Ok(mut conn) = connect(&client, &host, addr).await { | ||
for _ in 0..10 { | ||
if let Err(err) = attack(&mut conn, burst, &counter).await { | ||
log!("burst failed; probing again"); | ||
log!("{err}"); | ||
break 'retry_probe; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
async fn connect( | ||
client: &Client, | ||
host: &str, | ||
addr: std::net::SocketAddr, | ||
) -> Result<connection::Handle> { | ||
let connect = Connect::new(addr).with_server_name(host); | ||
log!("connecting: {connect}"); | ||
let conn = client.connect(connect).await?; | ||
|
||
let (conn, mut accept) = conn.split(); | ||
|
||
/* | ||
tokio::spawn(async move { | ||
while let Ok(Some(stream)) = accept.accept().await { | ||
tokio::spawn(retain(stream)); | ||
} | ||
}); | ||
tokio::spawn({ | ||
let mut conn = conn.clone(); | ||
async move { | ||
if let Ok(stream) = conn.open_bidirectional_stream().await { | ||
retain(stream).await; | ||
} | ||
} | ||
}); | ||
for ty in [Bytes::from_static(&[0x00])] { | ||
tokio::spawn({ | ||
let mut conn = conn.clone(); | ||
async move { | ||
if let Ok(mut stream) = conn.open_send_stream().await { | ||
let _ = stream.send(ty).await; | ||
retain(stream).await; | ||
} | ||
} | ||
}); | ||
} | ||
*/ | ||
|
||
Ok(conn) | ||
} | ||
|
||
async fn attack(conn: &mut connection::Handle, burst: usize, counter: &AtomicU64) -> Result { | ||
for _ in 0..1_000 { | ||
for _ in 0..burst { | ||
let mut stream = conn.open_send_stream().await?; | ||
let _ = stream.send(Bytes::from_static(&[4])).await; | ||
let _ = stream.finish(); | ||
} | ||
counter.fetch_add(burst as _, Ordering::Relaxed); | ||
sleep(Duration::from_millis(1)).await; | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
async fn retain<T: 'static + Send>(value: T) { | ||
let _: () = core::future::pending().await; | ||
drop(value); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[toolchain] | ||
channel = "1.70.0" | ||
channel = "1.71.1" | ||
components = [ "rustc", "clippy", "rustfmt" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters