nquic_packet (nquic v1.0.0)
View SourceQUIC packet parsing and encoding per RFC 9000 Section 17.
Handles long headers (Initial, Handshake, 0-RTT, Retry), short headers (1-RTT), and version negotiation packets. Provides the combined unmask-and-decrypt pipeline for received packets.
Summary
Functions
Map header bits to packet type atom for the given QUIC version.
Phase 2 of the receive pipeline: AEAD-decrypt and decode frames. Pair with unmask_header/6.
Encode a QUIC packet header to binary.
Encode a Version Negotiation packet with DCID/SCID swapped per RFC 9000 Section 17.2.1.
Check whether a QUIC version is supported.
Map packet type atom to header bits for the given QUIC version.
Parse a QUIC packet header from binary.
Parse a QUIC packet header with a known DCID length for short headers.
Parse a Retry packet's token payload into {RetryToken, IntegrityTag}. The raw token field from parse_header contains both the retry token and the 16-byte integrity tag appended at the end.
Return the list of supported QUIC versions (preferred first).
Remove header protection and decrypt a QUIC packet in one pass.
Phase 1 of the receive pipeline: strip header protection and recover the full packet number, returning the unmasked header alongside the recovered packet number, AAD, and ciphertext+tag. The caller is responsible for choosing AEAD keys (e.g. based on the unmasked short-header key_phase) and then calling decrypt_unmasked/5 to finish the AEAD step.
Types
-type header() :: #long_header{type :: initial | handshake | rtt0 | retry | version_negotiation, version :: 0..4294967295, dcid :: nquic:connection_id(), scid :: nquic:connection_id(), token :: binary() | undefined, payload_len :: non_neg_integer() | undefined, packet_number :: nquic_packet_number:t() | undefined, pn_len :: 1..4 | undefined} | #short_header{dcid :: nquic:connection_id(), packet_number :: nquic_packet_number:t() | undefined, key_phase :: boolean(), spin :: 0..1, pn_len :: 1..4 | undefined}.
-type space() :: initial | handshake | application.
Functions
-spec bits_to_packet_type(0..3, non_neg_integer()) -> initial | rtt0 | handshake | retry.
Map header bits to packet type atom for the given QUIC version.
-spec decrypt_unmasked(aes_128_gcm | aes_256_gcm | chacha20_poly1305, map(), non_neg_integer(), binary(), binary()) -> {ok, [nquic_frame:t()]} | {error, term()}.
Phase 2 of the receive pipeline: AEAD-decrypt and decode frames. Pair with unmask_header/6.
Encode a QUIC packet header to binary.
-spec encode_version_negotiation(nquic:connection_id(), nquic:connection_id(), [non_neg_integer()]) -> binary().
Encode a Version Negotiation packet with DCID/SCID swapped per RFC 9000 Section 17.2.1.
-spec is_supported_version(non_neg_integer()) -> boolean().
Check whether a QUIC version is supported.
-spec maybe_extract_key_phase(header(), non_neg_integer()) -> header().
-spec packet_type_bits(atom(), non_neg_integer()) -> 0..3.
Map packet type atom to header bits for the given QUIC version.
-spec parse_header(binary()) -> {ok, header(), binary()} | {error, nquic_error:any_reason()}.
Parse a QUIC packet header from binary.
-spec parse_header(binary(), non_neg_integer()) -> {ok, header(), binary()} | {error, nquic_error:any_reason()}.
Parse a QUIC packet header with a known DCID length for short headers.
-spec parse_retry(binary(), binary()) -> {ok, binary(), nquic:connection_id(), binary()} | {error, term()}.
Parse a Retry packet's token payload into {RetryToken, IntegrityTag}. The raw token field from parse_header contains both the retry token and the 16-byte integrity tag appended at the end.
-spec supported_versions() -> [non_neg_integer()].
Return the list of supported QUIC versions (preferred first).
-spec unmask_and_decrypt(binary(), binary(), header(), aes_128_gcm | aes_256_gcm | chacha20_poly1305, map(), non_neg_integer()) -> {ok, header(), [nquic_frame:t()]} | {error, term()}.
Remove header protection and decrypt a QUIC packet in one pass.
-spec unmask_header(binary(), binary(), header(), aes_128_gcm | aes_256_gcm | chacha20_poly1305, map(), non_neg_integer()) -> {ok, header(), non_neg_integer(), binary(), binary()} | {error, term()}.
Phase 1 of the receive pipeline: strip header protection and recover the full packet number, returning the unmasked header alongside the recovered packet number, AAD, and ciphertext+tag. The caller is responsible for choosing AEAD keys (e.g. based on the unmasked short-header key_phase) and then calling decrypt_unmasked/5 to finish the AEAD step.