mirror of
https://github.com/n0-computer/noq.git
synced 2026-10-13 08:11:39 +00:00
7c04a155c8
squashed messages: fixup for docs and removing extra braces add downcasting hatch pretty print should be Display, not Debug un-needed export fmt and clippy re-expose CCAs to public API reorder constants inline bbr_state remove extra param refactor bbr into its own module refactor bbr into its own module no threadlocal rng, use genrange rename fields for review Update quinn/src/connection.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> Update quinn-proto/src/connection/mod.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> Update quinn-proto/src/connection/mod.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> fill() now supported clippy in cubic was covered by the rebase add links to BBR info refactor to hide internal PathData clarify BBR usage reduce struct scope collapse update_last_sent into on_sent collapse on_loss into on_congestion_event remove dead code Update quinn/src/connection.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> Update quinn-proto/src/congestion/bbr.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> Update quinn-proto/src/congestion.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> Update quinn-proto/src/congestion/cubic.rs Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com> clippy safer duration comparison backwards compatibility fill add docs, rename stats cca to congestion remove PacketNumber and bbr_ prefixes rename constants to rust style fix packet number typing enable drain to target bdp mode during probe bw add ack aggregation for better target growth fix not entering growth mode remove extra debug printing enable rtt probe and track min rtt track max bandwidth with minmax filter use minmax filter for max bandwidth estimation switch minmax filter to use round counts instead of times port minmax filter to rust fix: count lost packet size instead of their id fix bw estimation not updating current bw expose congestion configs split bytes acked from end ack method simplify full bandwidth check remove some unused variables add 125% of target full bandwidth condition as per docs fix loss resetting too early, fix bandwidth target units of measurement check if full bw reached calculate recovery window calculate cwnd calculate pacing rate maybe_enter_or_exit_probe_rtt update gain cycle phase refactor bandwidth estimation add cca into stats for debugging add target window add recovery state transitions loss recording bandwidth estimation
104 lines
4.4 KiB
Rust
104 lines
4.4 KiB
Rust
//! QUIC transport protocol support for Tokio
|
|
//!
|
|
//! [QUIC](https://en.wikipedia.org/wiki/QUIC) is a modern transport protocol addressing
|
|
//! shortcomings of TCP, such as head-of-line blocking, poor security, slow handshakes, and
|
|
//! inefficient congestion control. This crate provides a portable userspace implementation. It
|
|
//! builds on top of quinn-proto, which implements protocol logic independent of any particular
|
|
//! runtime.
|
|
//!
|
|
//! The entry point of this crate is the [`Endpoint`](generic/struct.Endpoint.html).
|
|
//!
|
|
//! # About QUIC
|
|
//!
|
|
//! A QUIC connection is an association between two endpoints. The endpoint which initiates the
|
|
//! connection is termed the client, and the endpoint which accepts it is termed the server. A
|
|
//! single endpoint may function as both client and server for different connections, for example
|
|
//! in a peer-to-peer application. To communicate application data, each endpoint may open streams
|
|
//! up to a limit dictated by its peer. Typically, that limit is increased as old streams are
|
|
//! finished.
|
|
//!
|
|
//! Streams may be unidirectional or bidirectional, and are cheap to create and disposable. For
|
|
//! example, a traditionally datagram-oriented application could use a new stream for every
|
|
//! message it wants to send, no longer needing to worry about MTUs. Bidirectional streams behave
|
|
//! much like a traditional TCP connection, and are useful for sending messages that have an
|
|
//! immediate response, such as an HTTP request. Stream data is delivered reliably, and there is no
|
|
//! ordering enforced between data on different streams.
|
|
//!
|
|
//! By avoiding head-of-line blocking and providing unified congestion control across all streams
|
|
//! of a connection, QUIC is able to provide higher throughput and lower latency than one or
|
|
//! multiple TCP connections between the same two hosts, while providing more useful behavior than
|
|
//! raw UDP sockets.
|
|
//!
|
|
//! Quinn also exposes unreliable datagrams, which are a low-level primitive preferred when
|
|
//! automatic fragmentation and retransmission of certain data is not desired.
|
|
//!
|
|
//! QUIC uses encryption and identity verification built directly on TLS 1.3. Just as with a TLS
|
|
//! server, it is useful for a QUIC server to be identified by a certificate signed by a trusted
|
|
//! authority. If this is infeasible--for example, if servers are short-lived or not associated
|
|
//! with a domain name--then as with TLS, self-signed certificates can be used to provide
|
|
//! encryption alone.
|
|
#![warn(missing_docs)]
|
|
|
|
use std::time::Duration;
|
|
|
|
mod broadcast;
|
|
mod connection;
|
|
mod endpoint;
|
|
mod mutex;
|
|
mod recv_stream;
|
|
mod send_stream;
|
|
mod work_limiter;
|
|
|
|
pub use proto::{
|
|
congestion, crypto, ApplicationClose, Chunk, ClientConfig, ConfigError, ConnectError,
|
|
ConnectionClose, ConnectionError, EndpointConfig, IdleTimeout, ServerConfig, StreamId,
|
|
Transmit, TransportConfig, VarInt,
|
|
};
|
|
|
|
pub use crate::connection::{
|
|
Connecting, Connection, Datagrams, IncomingBiStreams, IncomingUniStreams, NewConnection,
|
|
OpenBi, OpenUni, SendDatagramError, ZeroRttAccepted,
|
|
};
|
|
pub use crate::endpoint::{Endpoint, Incoming};
|
|
pub use crate::recv_stream::{
|
|
Read, ReadChunk, ReadChunks, ReadError, ReadExact, ReadExactError, ReadToEnd, ReadToEndError,
|
|
RecvStream,
|
|
};
|
|
pub use crate::send_stream::{SendStream, StoppedError, WriteError};
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
#[derive(Debug)]
|
|
enum ConnectionEvent {
|
|
Close {
|
|
error_code: VarInt,
|
|
reason: bytes::Bytes,
|
|
},
|
|
Proto(proto::ConnectionEvent),
|
|
Ping,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
enum EndpointEvent {
|
|
Proto(proto::EndpointEvent),
|
|
Transmit(proto::Transmit),
|
|
}
|
|
|
|
/// Maximum number of datagrams processed in send/recv calls to make before moving on to other processing
|
|
///
|
|
/// This helps ensure we don't starve anything when the CPU is slower than the link.
|
|
/// Value is selected by picking a low number which didn't degrade throughput in benchmarks.
|
|
const IO_LOOP_BOUND: usize = 160;
|
|
|
|
/// The maximum amount of time that should be spent in `recvmsg()` calls per endpoint iteration
|
|
///
|
|
/// 50us are chosen so that an endpoint iteration with a 50us sendmsg limit blocks
|
|
/// the runtime for a maximum of about 100us.
|
|
/// Going much lower does not yield any noticeable difference, since a single `recvmmsg`
|
|
/// batch of size 32 was observed to take 30us on some systems.
|
|
const RECV_TIME_BOUND: Duration = Duration::from_micros(50);
|
|
|
|
/// The maximum amount of time that should be spent in `sendmsg()` calls per endpoint iteration
|
|
const SEND_TIME_BOUND: Duration = Duration::from_micros(50);
|