#[repr(C)]pub struct PacketHeader {
pub version: u8,
pub session_id: SessionId,
pub stream_id: StreamId,
pub packet_number: PacketNumber,
pub flags: PacketFlags,
pub epoch: u8,
pub path_id: u8,
}std only.Expand description
Packet header — 15 bytes on the wire (PacketHeader::SIZE); the AEAD AAD is
the separate, larger 47-byte image (PacketHeader::AAD_SIZE).
Serialised by PacketHeader::to_wire as an explicit, fixed big-endian
(network byte order) image, version first (no serialization library). The
WIRE v6 (anti-fingerprint) wire layout is a contiguous 15-byte span, the WHOLE
of which is HP-masked on the wire (HP_PROTECTED_OFFSET = 0 — no constant
cleartext byte). The 32-byte session_id is off-wire: it is a struct field
bound into the AEAD AAD but never transmitted (dropped from the wire in v5 / the
ε CID collapse), reconstructed by the receiver from session context.
off 0 version u8 (= WIRE_VERSION = 6) HP-MASKED ┐
off 1 packet_number u64 be (① per-direction monotonic) HP-MASKED │
off 9 flags u16 be HP-MASKED │ [0..15]
off 11 stream_id u16 be HP-MASKED │
off 13 epoch u8 HP-MASKED │
off 14 path_id u8 HP-MASKED ┘The 47-byte AEAD AAD image (Self::to_aad_image) is the cleartext header
reconstructed off-wire (it additionally binds the off-wire session_id), so
flipping any authenticated byte (version / session_id included) fails
decryption. On the wire the whole [0..15] span is XOR-masked by the
per-session HeaderProtector (a wire mutation of the masked region unmasks to
a wrong header → wrong AAD → AEAD fails — no new oracle); the recv path
reconstructs the cleartext header via RawPacket::unmask_header before
computing the AAD. epoch/stream_id/path_id are authenticated in the AAD
but NOT in the nonce (which is prefix‖packet_number). The recv path also drops
a frame whose version != WIRE_VERSION. Frozen by
core/tests/wire_vectors/packet_header.bin; grammar in
docs/protocol/PROTOCOL.md § 4.2.
Fields§
§version: u8On-wire packet-format version. Pinned to WIRE_VERSION; the first wire
byte (see PacketHeader::to_wire).
session_id: SessionId256-bit session identifier, used as encryption salt
stream_id: StreamIdStream within session (0 = control)
packet_number: PacketNumberPer-direction monotonic AEAD packet number (① — Phase 4). Feeds the AEAD nonce and the per-direction replay window; assigned at send time.
flags: PacketFlagsPacket flags
epoch: u8Rekey generation. Zero at session establishment, incremented in lock- step on each in-band rekey (Phase 1.5).
path_id: u8Connection-migration path identifier (Phase 4.2). 0 = the implicit,
always-validated handshake path; bumped per migrate() so the peer
challenges the new path.
Implementations§
Source§impl PacketHeader
impl PacketHeader
Sourcepub const SIZE: usize = 15
pub const SIZE: usize = 15
On-wire header size in bytes (ε / WIRE v5: version(1) + the 14 HP-masked
fields; session_id is off-wire). The AEAD AAD is the larger
Self::AAD_SIZE image (which still binds session_id).
Sourcepub const AAD_SIZE: usize = 47
pub const AAD_SIZE: usize = 47
Size of the AEAD AAD header image: the byte-identical 47-byte v4 logical
header (version ‖ session_id ‖ packet_number ‖ flags ‖ stream_id ‖ epoch ‖ path_id), reconstructed off-wire by Self::to_aad_image. Kept at 47
so the v4 AEAD security argument carries over unchanged (design §2.2).
Sourcepub fn new(
session_id: SessionId,
stream_id: StreamId,
packet_number: PacketNumber,
flags: PacketFlags,
) -> Self
pub fn new( session_id: SessionId, stream_id: StreamId, packet_number: PacketNumber, flags: PacketFlags, ) -> Self
Create a new packet header (version = WIRE_VERSION, epoch = 0,
path_id = 0).
Sourcepub fn with_epoch(self, epoch: u8) -> Self
pub fn with_epoch(self, epoch: u8) -> Self
Set the rekey epoch — used by Session::rekey (Phase 1.5).
Sourcepub fn with_path_id(self, path_id: u8) -> Self
pub fn with_path_id(self, path_id: u8) -> Self
Set the path id — stamped by the connection-migration path machinery (Phase 4.2; 0 = the implicit handshake path).
Sourcepub fn to_wire(&self) -> [u8; 15]
pub fn to_wire(&self) -> [u8; 15]
Serialise to the fixed 15 on-wire bytes (big-endian, version first;
ε / WIRE v5). session_id is not emitted — it is off-wire and lives
only in the AEAD AAD (Self::to_aad_image) and the session context.
Sourcepub fn to_aad_image(&self) -> [u8; 47]
pub fn to_aad_image(&self) -> [u8; 47]
The AEAD AAD image: the byte-identical 47-byte v4 logical header
(version ‖ session_id ‖ packet_number ‖ flags ‖ stream_id ‖ epoch ‖ path_id). session_id is off-wire, so the data plane reconstructs it
from the session context (Session::id) into self.session_id before
computing the AAD; this keeps the AEAD binding (and its security
argument) byte-identical to v4 (design §2.2).
Sourcepub fn from_wire(bytes: &[u8]) -> Result<Self, WireError>
pub fn from_wire(bytes: &[u8]) -> Result<Self, WireError>
Parse a header from the first Self::SIZE (= 15) bytes of bytes. Does
not validate version — the recv path gates on it separately. session_id
is off-wire (ε / WIRE v5): it is left the placeholder zero here and set by
Session::parse_protected from the routed session context.
Trait Implementations§
Source§impl Clone for PacketHeader
impl Clone for PacketHeader
Source§fn clone(&self) -> PacketHeader
fn clone(&self) -> PacketHeader
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for PacketHeader
Source§impl Debug for PacketHeader
impl Debug for PacketHeader
impl Eq for PacketHeader
Source§impl PartialEq for PacketHeader
impl PartialEq for PacketHeader
Source§fn eq(&self, other: &PacketHeader) -> bool
fn eq(&self, other: &PacketHeader) -> bool
self and other values to be equal, and is used by ==.