quinn-rs / quinn

Async-friendly QUIC implementation in Rust
Apache License 2.0
3.76k stars 380 forks source link

Can we explore that quinn is in persist congestion/congestion state? #1325

Closed Rouzip closed 2 years ago

Rouzip commented 2 years ago

I am trying to rebind the socket of quinn endpoint when network is in persist congestion. Is it a good idea which explore the congestion state? I wrote some code like this:

// 1. endpoint in quinn endpoint.rs
// add option in endpoint
pub fn new(
    config: EndpointConfig,
    server_config: Option<ServerConfig>,
    socket: std::net::UdpSocket,
    path_chan: mpsc::UnboundedSender<Instant>,
)
// 2. add send in quinn_proto connection mod.rs
// some personal detect in network congestion
match self.path_chan.send(now) {
    Ok(()) => {
        info!("successful send");
     }
    Err(e) => {
        error!("{:#?}", e);
    }
}
Ralith commented 2 years ago

What are you trying to accomplish by doing that? If you're trying to use multiple network paths to improve performance, then https://multipath-quic.org/ may be of interest.

Rouzip commented 2 years ago

What are you trying to accomplish by doing that? If you're trying to use multiple network paths to improve performance, then https://multipath-quic.org/ may be of interest.

I am trying to change the path I use in quinn endpoint when it found origianl path was in persistent congestion too long or unable to recover since this path was bad. And I just want to change the path instead of transferring data in multipath. Should I use rebind in this way?

Ralith commented 2 years ago

If you want to experiment with this, you could write a custom implementation of quinn::congestion::Controller (perhaps largely derived from one of the provided implementations) then inspect its state using quinn::Connection::congestion_state. Be aware that congestion control is a complex subject and it's easy to make things worse, and that migration is not designed for this use. I would recommend studying the multipath QUIC effort rather than attempting to implement an ad-hoc solution from scratch.

Rouzip commented 2 years ago

If you want to experiment with this, you could write a custom implementation of quinn::congestion::Controller (perhaps largely derived from one of the provided implementations) then inspect its state using quinn::Connection::congestion_state. Be aware that congestion control is a complex subject and it's easy to make things worse, and that migration is not designed for this use. I would recommend studying the multipath QUIC effort rather than attempting to implement an ad-hoc solution from scratch.

Thanks for your advice. I will try both ways in my experiment if I have enough time. Further, in my test, with 100ms delay network, quinn's speed is about 85Mb/s (one connection one stream), and TCP is about 200Mb/s, is it normal?

Ralith commented 2 years ago

That depends on many factors. For example: are you bound by congestion control, flow control, CPU load, or something else? Are you using encryption on your TCP stream? QUIC is encrypted and plain TCP is not, which has major implications for CPU consumption.

Rouzip commented 2 years ago

That depends on many factors. For example: are you bound by congestion control, flow control, CPU load, or something else? Are you using encryption on your TCP stream? QUIC is encrypted and plain TCP is not, which has major implications for CPU consumption.

Yes,I use same network to test the performance. Compared with the TCP proxy with tls encryption, quinn proxy only have about half performance. The TCP proxy is written in golang, but I just use one request so goroutine is not the problem? I am new in rust, I will try to learn something like flamegraph to check my problem.