moonquic quic transport

capture · interactive

A packet, opened

One client Initial as this library seals it: a 1200-byte datagram with a four-byte packet number, a PING, and the padding RFC 9000 §14.1 requires. The bytes below are printed by the library compiled to JavaScript for this page — nothing here is a drawing of the thing.

bytes —fields ——

field selected AEAD tag padding

Pick a byte, or a field; the other side follows.

what the three views share

One packet, three readings

The header is what a router can read without keys. The frames are what the peer reads once it has them. The parameters are never in a packet at all: they ride the handshake and are what 0-RTT is allowed to spend.

The header is public

Form, version, both connection ids, the length and the packet number are readable by anything on the path; the first byte and the number are masked, but the mask is derived from the ciphertext, so removing it takes no key beyond the one the receiver already has.

The tag is the seal

Sixteen bytes at the end authenticate the whole packet with the header as associated data. Change a bit anywhere before them and the packet does not open — which is why a connection only moves for a packet that authenticated.

The parameters outlive it

A ticket carries the parameters it was issued under, so 0-RTT knows the credit before a single byte of the handshake arrives. The block in the third view is the one this library declares, encoded by @conn.encode.