lib/quic/src/root.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 //! QUIC version 1 carries encrypted, numbered packets over UDP. State machines in the package run
2 //! on bytes the caller owns. The package holds a connection, wire codecs for headers and frames,
3 //! packet protection, a TLS 1.3 handshake, and a simulated path for tests.
4 //!
5 //! A program speaking this protocol must number, encrypt, and authenticate every packet it sends,
6 //! recover packets that were lost, and run a key exchange whose messages travel inside its own
7 //! frames. The protocol engine must execute all of these operations inside whatever event loop and
8 //! memory budget the host program already has.
9 //!
10 //! The state one connection keeps is large and lives as long as the connection, so an
11 //! implementation that asks for memory as it runs makes its own footprint a function of what the
12 //! peer chooses to send. Key exchange and packet encryption join through one key schedule and
13 //! through rules about when keys are thrown away, so both parts must be settled together. Loss
14 //! recovery and timeouts depend on when packets arrive, and a real network does not reproduce that
15 //! timing on demand.
16 //!
17 //! RFC 9000 fixes the wire format, and the codecs here read and write exactly those forms: the
18 //! variable-length integers, the long and short header layouts, and the packet number truncation.
19 //! RFC 9001 fixes how TLS keys protect QUIC packets, and this code derives the Initial secrets from
20 //! the client connection ID, builds each nonce from the packet number, applies the masking of a
21 //! packet's first byte and packet number from a sample of the encrypted payload as *header
22 //! protection*, tags Retry packets, and updates keys under the same labels. RFC 9002 fixes loss
23 //! detection and the probe timeout, and the recovery code declares losses by the same two rules and
24 //! backs the probe period off the same way.
25 //!
26 //! The package reaches for no allocator, so a caller derives an exact byte count from the
27 //! capacities it chooses and hands over one aligned block, and every buffer a connection keeps
28 //! lives inside that block. The connection opens no socket and runs no loop. The bytes of one UDP
29 //! payload, which may hold more than one packet end to end, form a *datagram*: receiving means
30 //! handing the connection those bytes, and sending means letting it write one datagram into the
31 //! caller's bytes. The connection carries one bidirectional stream. The simulated path answers the
32 //! timing problem by delivering datagrams on a schedule a test fixes, reproducing loss,
33 //! duplication, reordering, and delay from one seed. The wire codecs, packet protection, key
34 //! discard, and key update rules are written a second time as Lean definitions carrying proofs, and
35 //! property tests compare the two implementations on drawn inputs.
36 //!
37 //! - *packet number space*: one of three, Initial, Handshake, and application, each numbering its
38 //! own packets from zero.
39 //! - *handshake confirmation*: the point at which the handshake is complete for both endpoints,
40 //! after which the Handshake keys go and the retained handshake traffic secrets are erased at
41 //! once.
42 //! - *traffic secret*: the 32 bytes from which one direction's packet keys derive.
43
44 pub const connection = @import("connection/root.zig");
45 pub const crypto = @import("crypto/root.zig");
46 pub const cursor = @import("cursor.zig");
47 pub const frame = @import("frame/root.zig");
48 pub const packet = @import("packet/root.zig");
49 pub const sim = @import("sim/root.zig");
50 pub const tls = @import("tls/root.zig");
51 pub const transport = @import("transport.zig");
52 pub const varint = @import("varint.zig");