Introduce dual-stack endpoint candidates with IPv6-preferred traversal #31

Open
opened 2026-08-22 23:28:32 +02:00 by Kyuubi · 0 comments
Owner

Parent: #1
Related: #24 (relay decision — competes on the same failure evidence)
Identified by: real-world consumer networks (DS-Lite/CGNAT ISPs) where IPv4 paths are degraded or unpunchable while native IPv6 is end-to-end clean.

Classification

Post-v1. The v1 UDP contract was deliberately frozen address-family aware so this lands without a wire-format break; v1 mediation remains IPv4-first.

Motivation

Under DS-Lite/CGNAT, customers hold no real public IPv4: carrier translation frequently defeats hole punching outright (the documented symmetric-NAT failure), while IPv6 requires no address translation at all — only a firewall pinhole, which the existing simultaneous-send introduction opens far more reliably. Preferring IPv6 when both peers have it is expected to be the largest single improvement to direct-connect success, at a fraction of the cost of a relay. Typed connection outcomes from live consumers provide the failure-rate evidence; this issue and #24 are decided against that same data.

Outcome

Hosts and clients with dual-stack sockets register endpoint candidates in both address families; the mediator introduces an ordered candidate set (global IPv6 first, public IPv4 second, same-NAT private last) and peers attempt candidates in order until an authenticated connection succeeds or the attempt times out with the existing typed outcome.

Design constraints

  • Public candidates remain observation-only: a peer proves each family by sending its authenticated presence over that family's socket path; the mediator never accepts a self-reported public endpoint in either family.
  • Existing scope, replay, expiry, one-shot-introduction, and amplification invariants apply per attempt, not per family — adding a family must not multiply the response-byte budget beyond the documented ceiling.
  • Private-endpoint disclosure rules stay family-symmetric: RFC1918 ⇄ ULA, released only on matching observed public identity.
  • Introduction payload change is additive-optional (v1 peers ignore unknown candidates) or an explicit UDP contract v2 with the compatibility gate extended to both.
  • LiteNetLib IPv6 punch/connect behavior verified against the pinned 2.x release before the contract is committed.

Acceptance criteria

  • Deterministic topology harness covers: v6+v6 (pinhole, no punch), v6-only vs v4-only (no shared family → correct fallback/typed failure), dual-stack vs v4-only, DS-Lite-emulated v4 degradation, and same-LAN in both families.
  • Mediator deploys dual-stack (v4 and v6 listeners) with both advertised endpoints validated at startup; single-family deployments remain valid and advertise accordingly.
  • Candidate ordering is server-policy, not client choice; clients cannot force v4-only downgrade of a peer that proved v6.
  • Aggregate outcome metrics record per-family attempt/success so the #24 relay decision can be made on measured data.
  • No raw endpoint of either family appears in browser responses or retained telemetry beyond existing short-lived attempt records.
  • SDK exposes dual-stack participation without new game-side configuration beyond binding a dual-stack socket; single-stack callers work unchanged.
Parent: #1 Related: #24 (relay decision — competes on the same failure evidence) Identified by: real-world consumer networks (DS-Lite/CGNAT ISPs) where IPv4 paths are degraded or unpunchable while native IPv6 is end-to-end clean. ## Classification Post-v1. The v1 UDP contract was deliberately frozen address-family aware so this lands without a wire-format break; v1 mediation remains IPv4-first. ## Motivation Under DS-Lite/CGNAT, customers hold no real public IPv4: carrier translation frequently defeats hole punching outright (the documented symmetric-NAT failure), while IPv6 requires no address translation at all — only a firewall pinhole, which the existing simultaneous-send introduction opens far more reliably. Preferring IPv6 when both peers have it is expected to be the largest single improvement to direct-connect success, at a fraction of the cost of a relay. Typed connection outcomes from live consumers provide the failure-rate evidence; this issue and #24 are decided against that same data. ## Outcome Hosts and clients with dual-stack sockets register endpoint candidates in both address families; the mediator introduces an ordered candidate set (global IPv6 first, public IPv4 second, same-NAT private last) and peers attempt candidates in order until an authenticated connection succeeds or the attempt times out with the existing typed outcome. ## Design constraints - Public candidates remain **observation-only**: a peer proves each family by sending its authenticated presence over that family's socket path; the mediator never accepts a self-reported public endpoint in either family. - Existing scope, replay, expiry, one-shot-introduction, and amplification invariants apply per attempt, not per family — adding a family must not multiply the response-byte budget beyond the documented ceiling. - Private-endpoint disclosure rules stay family-symmetric: RFC1918 ⇄ ULA, released only on matching observed public identity. - Introduction payload change is additive-optional (v1 peers ignore unknown candidates) or an explicit UDP contract v2 with the compatibility gate extended to both. - LiteNetLib IPv6 punch/connect behavior verified against the pinned 2.x release before the contract is committed. ## Acceptance criteria - Deterministic topology harness covers: v6+v6 (pinhole, no punch), v6-only vs v4-only (no shared family → correct fallback/typed failure), dual-stack vs v4-only, DS-Lite-emulated v4 degradation, and same-LAN in both families. - Mediator deploys dual-stack (v4 and v6 listeners) with both advertised endpoints validated at startup; single-family deployments remain valid and advertise accordingly. - Candidate ordering is server-policy, not client choice; clients cannot force v4-only downgrade of a peer that proved v6. - Aggregate outcome metrics record per-family attempt/success so the #24 relay decision can be made on measured data. - No raw endpoint of either family appears in browser responses or retained telemetry beyond existing short-lived attempt records. - SDK exposes dual-stack participation without new game-side configuration beyond binding a dual-stack socket; single-stack callers work unchanged.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: HeiKyu/Rendezvous#31