#[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,
}Expand description
Packet header — 47 bytes on the wire (the AEAD AAD).
Serialised by PacketHeader::to_wire as an explicit, fixed big-endian
(network byte order) image, version first. WIRE_VERSION 4 (T4.6) reorders
the fields so the 14 HP-protected bytes are a contiguous span at [33..47],
after the cleartext routing prefix:
off 0 version u8 (= WIRE_VERSION = 4) CLEARTEXT
off 1 session_id [u8;32] (routing CID) CLEARTEXT
off 33 packet_number u64 be (① per-direction monotonic) HP-MASKED ┐
off 41 flags u16 be HP-MASKED │
off 43 stream_id u16 be HP-MASKED │ [33..47]
off 45 epoch u8 HP-MASKED │
off 46 path_id u8 HP-MASKED ┘The to_wire image (the cleartext 47-byte header) is the AEAD AAD, so
flipping any byte (version included) fails decryption. On the wire the
[33..47] 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: u8Multi-path leg identifier (Phase 4.2). 0 = single-leg default.
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 — used by the multi-path scheduler (Phase 4.2).
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 ==.