Target: 2.6.0 (Tier 4 — AAA & infrastructure services)
Context
STUN helps a host discover its public-facing address/port for NAT
traversal — UDP (or TCP) port 3478. Its attribute encoding is
trickier than RADIUS's flat TLVs (this same tier): STUN attributes
carry addresses XOR'd against a magic cookie, worth calling out as an
explicit design point rather than a gotcha discovered mid-PR.
Deliverable
Add netprotocols.STUN (layer 7, dispatched from udp.port/
tcp.port):
- Decode the 20-byte header (RFC 5389 §6): Message Type (2 bytes, a
Class/Method split across non-contiguous bits — treat as one enum
value rather than trying to split it into two dataclass fields),
Message Length (2 bytes), Magic Cookie (4 bytes, fixed
0x2112A442 — verify it, don't just store it), Transaction ID (12
bytes).
- Decode the Attribute list (Type 2 bytes, Length 2 bytes,
Value padded to a 4-byte boundary) via _tlv.py's
walk_kind_length_value, adapting for the padding.
- Name MAPPED-ADDRESS (0x0001) and XOR-MAPPED-ADDRESS (0x0020) —
the two attributes any STUN response actually needs. XOR-MAPPED-
ADDRESS's address/port are obscured by XORing against the Magic
Cookie and Transaction ID (RFC 5389 §15.2) — implement the
un-XOR as a display/accessor property, the same convention this
library already uses for hex/enum helpers, so the raw on-wire bytes
still round-trip untouched.
- Register
udp.port 3478 and tcp.port 3478 → STUN.
Acceptance criteria
References
RFC 5389 · TLV walker: _tlv.py
Part of #174
Target: 2.6.0 (Tier 4 — AAA & infrastructure services)
Context
STUN helps a host discover its public-facing address/port for NAT
traversal — UDP (or TCP) port 3478. Its attribute encoding is
trickier than RADIUS's flat TLVs (this same tier): STUN attributes
carry addresses XOR'd against a magic cookie, worth calling out as an
explicit design point rather than a gotcha discovered mid-PR.
Deliverable
Add
netprotocols.STUN(layer 7, dispatched fromudp.port/tcp.port):Class/Method split across non-contiguous bits — treat as one enum
value rather than trying to split it into two dataclass fields),
Message Length (2 bytes), Magic Cookie (4 bytes, fixed
0x2112A442— verify it, don't just store it), Transaction ID (12bytes).
Value padded to a 4-byte boundary) via
_tlv.py'swalk_kind_length_value, adapting for the padding.the two attributes any STUN response actually needs. XOR-MAPPED-
ADDRESS's address/port are obscured by XORing against the Magic
Cookie and Transaction ID (RFC 5389 §15.2) — implement the
un-XOR as a display/accessor property, the same convention this
library already uses for hex/enum helpers, so the raw on-wire bytes
still round-trip untouched.
udp.port3478 andtcp.port3478 →STUN.Acceptance criteria
STUNdecodes the header (with Magic Cookie verification) andattribute list;
bytes(STUN.decode(x)) == x.address/port against a known-good fixture.
STUN.References
RFC 5389 · TLV walker:
_tlv.pyPart of #174