Custom Congestion Controller

This folder contains an example of implementing and configuring a custom congestion controller in s2n-quic. s2n-quic includes CUBIC and BBRv2 congestion controller implementations, but you may implement the CongestionController trait, found in congestion_controller.rs, to provide your own.

Set-up

The CongestionController trait is considered unstable and may be subject to change in a future release. In order to build it you must add this line to your Cargo.toml file:

[dependencies]
s2n-quic = { version = "1", features = ["unstable-congestion-controller"]}

Example

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Build an `s2n_quic::Server`
    let mut server = Server::builder()
        .with_tls((CERT_PEM, KEY_PEM))?
        .with_io("127.0.0.1:4433")?
        // Specify the custom congestion controller endpoint defined in `custom-congestion-controller/src/lib.rs`
        .with_congestion_controller(MyCongestionControllerEndpoint::default())?
        .start()?;

    while let Some(mut connection) = server.accept().await {
        // spawn a new task for the connection
        tokio::spawn(async move {
            eprintln!("Connection accepted from {:?}", connection.remote_addr());

            while let Ok(Some(mut stream)) = connection.accept_bidirectional_stream().await {
                // spawn a new task for the stream
                tokio::spawn(async move {
                    eprintln!("Stream opened from {:?}", stream.connection().remote_addr());

                    // echo any data back to the stream
                    while let Ok(Some(data)) = stream.receive().await {
                        stream.send(data).await.expect("stream should be open");
                    }
                });
            }
        });
    }

    Ok(())
}