From be77501f14e41855e1a9b04903a90d0418c4ef6a Mon Sep 17 00:00:00 2001 From: Wade Simmons Date: Thu, 3 Sep 2026 14:10:35 -0400 Subject: [PATCH] header: show the lane field in the version 1 header diagram The lane byte was described in prose wedged between the first and second rows of the table, which both broke up the diagram and left the wire layout still claiming a single Reserved (uint16). Make it a field: widen the table to fit Reserved (uint8) and Lane (uint8) with their types, and move the explanation below the whole diagram. The prose now covers what the picture can't: lane 0 is what a lanes-unaware sender and every non-lane packet carry, so the field is compatible in both directions; the remaining 8 bits stay reserved and zero; the H struct still stores the pair as one Reserved field, so callers reach the low byte through H.Lane and EncodeLane; and lane is part of the AEAD's associated data, so it cannot be altered in flight. --- header/header.go | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/header/header.go b/header/header.go index 19cc7011..a619e0bf 100644 --- a/header/header.go +++ b/header/header.go @@ -8,19 +8,28 @@ import ( ) //Version 1 header: -// 0 31 -// |-----------------------------------------------------------------------| -// | Version (uint4) | Type (uint4) | Subtype (uint8) | Reserved (uint16) | 32 -// |-----------------------------------------------------------------------| -// The low 8 bits of Reserved carry the multiport lane index (0 is the base -// tunnel, which is what every non-multiport sender emits). The high 8 bits -// remain reserved and are always sent as zero. -// | Remote index (uint32) | 64 -// |-----------------------------------------------------------------------| -// | Message counter | 96 -// | (uint64) | 128 -// |-----------------------------------------------------------------------| -// | payload... | +// 0 31 +// |------------------------------------------------------------------------------------| +// | Version (uint4) | Type (uint4) | Subtype (uint8) | Reserved (uint8) | Lane (uint8) | 32 +// |------------------------------------------------------------------------------------| +// | Remote index (uint32) | 64 +// |------------------------------------------------------------------------------------| +// | Message counter | 96 +// | (uint64) | 128 +// |------------------------------------------------------------------------------------| +// | payload... | +// +// Lane is the multiport lane index, carved out of the low 8 bits of what was a +// single Reserved (uint16) before multiport. Lane 0 is the base tunnel, which is +// what every sender that does not know about lanes emits and what every non-lane +// packet — handshakes, lighthouse, relays, close — carries, so the field is +// compatible in both directions with a peer that has never heard of it. The +// remaining 8 bits stay reserved and are always sent as zero. The H struct still +// holds the pair as one Reserved field; use H.Lane and EncodeLane to reach the +// low byte. +// +// Lane is part of the AEAD's associated data, so a lane index cannot be altered +// in flight: a packet decrypts on the lane it claims or not at all. type m = map[string]any