#[repr(C, align(8))]pub struct NetHeader {Show 19 fields
pub magic: u16,
pub version: u8,
pub flags: PacketFlags,
pub priority: u8,
pub hop_ttl: u8,
pub hop_count: u8,
pub frag_flags: u8,
pub subprotocol_id: u16,
pub channel_hash: u16,
pub nonce: [u8; 12],
pub session_id: u64,
pub stream_id: u64,
pub sequence: u64,
pub origin_hash: u64,
pub subnet_id: u32,
pub fragment_id: u16,
pub fragment_offset: u16,
pub payload_len: u16,
pub event_count: u16,
}Expand description
Net packet header - 68 bytes, 8-byte aligned.
Wire format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MAGIC (0x4E45) | VER | FLAGS | 4
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PRIORITY | HOP_TTL | HOP_COUNT | FRAG_FLAGS | 8
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SUBPROTOCOL_ID | CHANNEL_HASH | 12
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ NONCE (12 bytes) + 24
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SESSION_ID (8 bytes) | 32
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| STREAM_ID (8 bytes) | 40
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SEQUENCE (8 bytes) | 48
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ ORIGIN_HASH (8 bytes) + 56
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SUBNET_ID (4 bytes) | 60
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FRAGMENT_ID | FRAGMENT_OFFSET | 64
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PAYLOAD_LEN | EVENT_COUNT | 68
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ORIGIN_HASH precedes SUBNET_ID so the u64 sits at offset
48 (naturally 8-aligned) — putting SUBNET_ID first would
force a 4-byte padding gap and grow the struct to 72 bytes.
Fields§
§magic: u16Magic: “NE” (0x4E45)
version: u8Protocol version (1)
flags: PacketFlagsFlags (reliability, priority, etc.)
priority: u8Priority level (0 = lowest, 255 = highest)
hop_ttl: u8Maximum hops before packet is dropped
hop_count: u8Current hop count (incremented by forwarding nodes)
frag_flags: u8Fragmentation flags
subprotocol_id: u16Subprotocol identifier for capability-aware routing
channel_hash: u16Truncated channel name hash for wire-speed filtering
nonce: [u8; 12]ChaCha20-Poly1305 nonce (12 bytes) - counter-based
session_id: u64Session identifier (from handshake)
stream_id: u64Stream identifier (for multiplexing)
sequence: u64Per-stream sequence number (monotonic)
origin_hash: u64Full 64-bit blake2 hash of the origin node identity, matching
EntityKeypair::origin_hash(). The reverse index
(mesh.rs::origin_hash_to_node) maps this u64 to the
publisher’s NodeId — unambiguously, even under adversarial
collision-grinding (~2^32 work per target).
Declared before subnet_id so the u64 sits at a naturally
8-aligned offset.
subnet_id: u32Subnet identifier for gateway routing
fragment_id: u16Fragment group identifier
fragment_offset: u16Byte offset within original packet
payload_len: u16Payload length (after encryption, before tag)
event_count: u16Number of events in payload
Implementations§
Source§impl NetHeader
impl NetHeader
Sourcepub const MAX_EVENTS_PER_PACKET: u16
pub const MAX_EVENTS_PER_PACKET: u16
Maximum events per packet. Each event needs at least a 4-byte length prefix, so this is bounded by MAX_PAYLOAD_SIZE / LEN_SIZE.
Sourcepub fn new(
session_id: u64,
stream_id: u64,
sequence: u64,
nonce: [u8; 12],
payload_len: u16,
event_count: u16,
flags: PacketFlags,
) -> Self
pub fn new( session_id: u64, stream_id: u64, sequence: u64, nonce: [u8; 12], payload_len: u16, event_count: u16, flags: PacketFlags, ) -> Self
Create a new header with default values.
New routing/mesh fields default to zero. Use the with_* methods
to set them when needed.
Sourcepub fn with_priority(self, priority: u8) -> Self
pub fn with_priority(self, priority: u8) -> Self
Set priority level
Sourcepub fn with_subprotocol(self, id: u16) -> Self
pub fn with_subprotocol(self, id: u16) -> Self
Set subprotocol identifier
Sourcepub fn with_channel_hash(self, hash: u16) -> Self
pub fn with_channel_hash(self, hash: u16) -> Self
Set channel hash
Sourcepub fn with_subnet(self, subnet_id: u32) -> Self
pub fn with_subnet(self, subnet_id: u32) -> Self
Set subnet identifier
Sourcepub fn with_origin(self, origin_hash: u64) -> Self
pub fn with_origin(self, origin_hash: u64) -> Self
Set origin node hash. Carries the full u64 from
EntityKeypair::origin_hash(); the per-packet wire field
matches the application-layer width.
Sourcepub fn with_fragment(self, id: u16, offset: u16, flags: u8) -> Self
pub fn with_fragment(self, id: u16, offset: u16, flags: u8) -> Self
Set fragmentation fields
Sourcepub fn aad(&self) -> [u8; 56]
pub fn aad(&self) -> [u8; 56]
Get AAD (Additional Authenticated Data) for AEAD construction.
Authenticates all header fields except:
- nonce (used as the AEAD IV)
- hop_count (mutable in transit — incremented by forwarding nodes)
This binds the encrypted payload to the immutable header fields, preventing an attacker from modifying any field without breaking AEAD verification.
Sourcepub fn from_bytes(data: &[u8]) -> Option<Self>
pub fn from_bytes(data: &[u8]) -> Option<Self>
Parse header from bytes