test(e2e): NatProfile::PortRestrictedConeAutoNATOk variant - #52
Merged
Conversation
3 tasks
Adds an AutoNAT-permissive variant of the NAT shape so libp2p's reachability-verification protocol can succeed inside the harness: - New `NatProfile::PortRestrictedConeAutoNATOk` whitelists the AutoNAT server's bridge IP (the relay container, which also runs `autonat::v2::server`) for unsolicited inbound, while keeping the conntrack-based filter for arbitrary peer-to-peer unsolicited inbound. - The harness resolves the relay's bridge IP via `ContainerAsync::get_bridge_ip_address()` after starting the relay, and threads it through `apply_nat_to_container`. - DCUtR validation bench updated to use the new variant. ## Verified empirically Under `cellular_fair + PortRestrictedConeAutoNATOk`: - Whitelist applied correctly (harness logs the IP). - AutoNAT now reports the peer address as **reachable** (it was "NOT reachable" with plain PortRestrictedCone). Engine sees its NAT status as Public, so it advertises direct addresses. - Sync still works. But `dcutr_upgrades_attempted = 0`. Root cause traced: the relay introduces peers via `PeerList`/`PeerJoined` near-simultaneously, and both peers fire dial-outs immediately. Each side's outbound creates a conntrack entry; the other side's inbound packet then matches as ESTABLISHED — peers form a direct connection without DCUtR's coordination ever being needed. This is the right behaviour for a port-restricted cone NAT in real life (it's why hole-punching works on most home networks). It's just not a useful shape for *exercising* DCUtR specifically. To require DCUtR coordination, the bench needs a symmetric-NAT shape where source ports are rotated per-destination so simultaneous- dial doesn't catch the same flow tuple. Filed as #51. The `PortRestrictedConeAutoNATOk` variant is still useful infrastructure independent of the DCUtR question — it's the shape needed for any future bench that wants AutoNAT-verified peers behind realistic NAT. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pvg13
force-pushed
the
feat/nat-autonat-permissive
branch
from
May 7, 2026 21:35
1113b8f to
f47c42b
Compare
pvg13
added a commit
that referenced
this pull request
May 12, 2026
Adds an AutoNAT-permissive variant of the NAT shape so libp2p's reachability-verification protocol can succeed inside the harness: - New `NatProfile::PortRestrictedConeAutoNATOk` whitelists the AutoNAT server's bridge IP (the relay container, which also runs `autonat::v2::server`) for unsolicited inbound, while keeping the conntrack-based filter for arbitrary peer-to-peer unsolicited inbound. - The harness resolves the relay's bridge IP via `ContainerAsync::get_bridge_ip_address()` after starting the relay, and threads it through `apply_nat_to_container`. - DCUtR validation bench updated to use the new variant. ## Verified empirically Under `cellular_fair + PortRestrictedConeAutoNATOk`: - Whitelist applied correctly (harness logs the IP). - AutoNAT now reports the peer address as **reachable** (it was "NOT reachable" with plain PortRestrictedCone). Engine sees its NAT status as Public, so it advertises direct addresses. - Sync still works. But `dcutr_upgrades_attempted = 0`. Root cause traced: the relay introduces peers via `PeerList`/`PeerJoined` near-simultaneously, and both peers fire dial-outs immediately. Each side's outbound creates a conntrack entry; the other side's inbound packet then matches as ESTABLISHED — peers form a direct connection without DCUtR's coordination ever being needed. This is the right behaviour for a port-restricted cone NAT in real life (it's why hole-punching works on most home networks). It's just not a useful shape for *exercising* DCUtR specifically. To require DCUtR coordination, the bench needs a symmetric-NAT shape where source ports are rotated per-destination so simultaneous- dial doesn't catch the same flow tuple. Filed as #51. The `PortRestrictedConeAutoNATOk` variant is still useful infrastructure independent of the DCUtR question — it's the shape needed for any future bench that wants AutoNAT-verified peers behind realistic NAT.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an AutoNAT-permissive NAT shape so libp2p's reachability-verification protocol can succeed inside the harness — closes the immediate "DCUtR doesn't fire because AutoNAT is blocked" finding from #50, surfaces a deeper finding that's now filed as #51.
Stacks on top of #50 (NAT-topology shapes); merge that first.
What's new
Empirical findings
Under `cellular_fair + PortRestrictedConeAutoNATOk`:
Root cause traced: the relay introduces peers via `PeerList` / `PeerJoined` near-simultaneously, both peers fire dial-outs immediately, each side's outbound creates a conntrack entry, the other's inbound matches as ESTABLISHED — peers form a direct connection naturally without DCUtR's coordination.
This is realistic NAT behaviour (it's why hole-punching works on most home networks), but it's not useful for exercising DCUtR specifically. Forcing DCUtR requires a symmetric-NAT shape that rotates source ports per-destination so simultaneous dial can't catch the same flow tuple. Filed as #51.
What lands here, what doesn't
✅ `PortRestrictedConeAutoNATOk` is useful infrastructure independent of the DCUtR question — any future bench that wants AutoNAT-verified peers behind realistic NAT can use it.
✅ The harness now correctly resolves and passes through container IPs at NAT-rule application time.
❌ DCUtR end-to-end validation still pending — needs #51 (symmetric NAT). The acceptance criterion 3 of #40 ("partition-recovery drops 30% on cellular_fair via DCUtR") therefore remains open until #51 lands.
Test plan
Related