NAT-traversal simulation (Covalence direct, SYNC_PROTOCOL §3.3)
Drives the real STUN + hole-punch core (Sources/NucleicProtocol/Sync/Direct, via the
nucleic-punch-harness executable) across Linux network namespaces joined by NAT gateways —
so results are evidence about the shipping punch logic, not a mock.
Running
Needs root (netns + nftables), iproute2, nftables, and a built harness. Run inside a
privileged Linux container or VM:
swift build --product nucleic-punch-harness
sudo scripts/nat-sim/run.sh cone # both NATs port-preserving → punch should succeed
sudo scripts/nat-sim/run.sh symmetric # both NATs random-port → detect symmetric, give up
Topology: peerA ── natA ── inet(STUN) ── natB ── peerB, private home subnets deliberately
not cross-routed so the only path between peers is through their public reflexive
addresses (a genuine punch).
What it validates
- STUN discovery + NAT classification against real NATs:
conemode is detected ascone(same mapped port from both STUN servers),symmetricmode assymmetric(differing ports). This is the signal the punch policy keys off (punchWorthAttempting), and it passes. - Candidate gathering: each peer produces its reflexive + local candidates with the correct ports (cone preserves the port; the reflexive port equals the local port).
Punch-through caveat
The reflexive punch-through leg in the netns sandbox depends on the host's
nf_conntrack module behaving as an endpoint-independent-mapping / address-restricted-
filtering NAT — which not every CI kernel/container exposes identically. The punch logic
itself is proven directly and deterministically elsewhere and does not depend on this
harness:
PunchEngineTests— the state machine, incl. lossy convergence, over injected I/O.PunchEngineTests.liveLoopbackPunchValidatesBothSides— two real UDP sockets, real round-trip validation.DirectPathLoopbackTests(macOS) — the full punch → QUIC port-handoff → framed transfer.
Treat this harness as the STUN/classification check and a manual punch-through probe on a kernel you control; the automated punch-correctness guarantee lives in the unit + loopback tests above.