Module quic

Source
Expand description

async-ified QUIC connections powered by [quiche].

Hooking up a [quiche::Connection] to [tokio]’s executor and IO primitives requires an ApplicationOverQuic to control the connection. The application exposes a small number of callbacks which are executed whenever there is work to do with the connection.

The primary entrypoints to set up a connection are listen for servers and connect for clients. listen_with_capabilities and connect_with_config exist for scenarios that require more in-depth configuration. Lastly, the raw submodule allows users to take full control over connection creation and its ingress path.

§QUIC Connection Internals

QUIC Worker Setup

Note: Internal details are subject to change between minor versions.

tokio-quiche conceptually separates a network socket into a recv half and a send half. The recv half can only sensibly be used by one async task at a time, while many tasks can send packets on the socket concurrently. Thus, we spawn a dedicated InboundPacketRouter task for each socket which becomes the sole owner of the socket’s recv half. It decodes the QUIC header in each packet, looks up the destination connection ID (DCID), and forwards the packet to the connection’s IoWorker task.

If the packet initiates a new connection, it is passed to an InitialPacketHandler with logic for either the client- or server-side connection setup. The purple ConnectionAcceptor depicted above is the server-side implementation. It optionally validates the client’s IP address with a RETRY packet before packaging the nascent connection into an InitialQuicConnection and sending it to the QuicConnectionStream returned by listen.

At this point the caller of listen has control of the InitialQuicConnection (IQC). Now an IoWorker task needs to be spawned to continue driving the connection. This is possible with IQC::handshake or IQC::start (see the InitialQuicConnection docs). Client-side connections use the same infrastructure (except for the InitialPacketHandler), but connect immediately consumes the QuicConnectionStream and calls IQC::start.

IoWorker is responsible for feeding inbound packets into the underlying [quiche::Connection], executing the ApplicationOverQuic callbacks, and flushing outbound packets to the network via the socket’s shared send half. It loops through these operations in the order shown above, yielding only when sending packets and on wait_for_data calls. New inbound packets or a timeout can also restart the loop while wait_for_data is pending. This continues until the connection is closed or the ApplicationOverQuic returns an error.

Modules§

raw
Helper to wrap existing [quiche::Connection]s.

Structs§

ConnectionShutdownBehaviour
Parameters to close a [quiche::Connection].
HandshakeInfo
Details about a connection’s QUIC handshake.
Incoming
A received network packet with additional metadata.
QuicConnectionStats
Wrapper for connection statistics recorded by [quiche].
SimpleConnectionIdGenerator
A ConnectionIdGenerator which creates random 20-byte connection IDs.

Enums§

HandshakeError
Additional error types that can occur during a QUIC handshake.
QuicCommand
A command to execute on a [quiche::Connection] in the context of an ApplicationOverQuic.

Traits§

ConnectionHook
A set of hooks executed at the level of a [quiche::Connection].

Functions§

connect
Connects to an HTTP/3 server using socket and the default client configuration.
connect_with_config
Connects to a QUIC server using socket and the provided ApplicationOverQuic.

Type Aliases§

QuicheConnection
Alias of [quiche::Connection] used internally by the crate.