feat(nat): hard NAT port allocation detection + prediction + HardNatProbe signal (#29)
Phase A of hard NAT traversal (PRD-hard-nat.md):
- PortAllocation enum: PortPreserving / Sequential{delta} / Random / Unknown
- detect_port_allocation(): sequential STUN probes from single socket,
analyzes port sequence for allocation pattern
- classify_port_allocation(): pure function with jitter tolerance,
wraparound handling, 60% threshold for noisy sequences
- predict_ports(): generates target port range from last_port + delta
- HardNatProbe signal message: carries port_sequence, allocation
pattern, external_ip for peer coordination
- Relay forwards HardNatProbe to call peer
- Netcheck gains port_allocation field + format_report display
588 tests pass (17 new), 0 regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -947,6 +947,26 @@ pub enum SignalMessage {
|
||||
generation: u32,
|
||||
},
|
||||
|
||||
// ── Hard NAT traversal (port prediction) ──────────────────────
|
||||
|
||||
/// Hard NAT probe coordination — exchanged when both peers
|
||||
/// detect symmetric NAT. Carries the port allocation pattern
|
||||
/// and recent port sequence so the peer can predict which port
|
||||
/// to dial.
|
||||
HardNatProbe {
|
||||
call_id: String,
|
||||
/// Last observed external ports (most recent first).
|
||||
/// Typically 3-5 entries from sequential STUN probes.
|
||||
port_sequence: Vec<u16>,
|
||||
/// Detected allocation pattern as string:
|
||||
/// "sequential:N" (N=delta), "random", "preserving"
|
||||
allocation: String,
|
||||
/// Probe timestamp (ms since epoch) for synchronization.
|
||||
probe_time_ms: u64,
|
||||
/// External IP from STUN.
|
||||
external_ip: String,
|
||||
},
|
||||
|
||||
// ── Phase 4: cross-relay direct-call signaling ────────────────────
|
||||
|
||||
/// Phase 4: relay-to-relay envelope for forwarding direct-call
|
||||
|
||||
Reference in New Issue
Block a user