Birthday attack for random symmetric NATs:
- birthday.rs: open_acceptor_ports() opens N sockets, STUN-probes
each to learn external ports. generate_dialer_targets() builds
hit list (known ports first, then random fill). spray_dialer()
sprays QUIC connects with rate limiting, first success wins.
- Default: 32 acceptor ports, 128 dialer probes, 20ms interval
Signal coordination:
- HardNatBirthdayStart { acceptor_ports, external_ip } sent by
Acceptor when peer's HardNatProbe shows random/sequential NAT
- Relay forwards it like other call signals
- Desktop recv loop handles and logs it
Hybrid waterfall integration:
- On receiving HardNatProbe with non-cone allocation, Acceptor
auto-opens birthday ports and sends BirthdayStart
- Sockets kept alive 10s for NAT mapping persistence
- Dialer spray integration into race() pending (needs transport
hot-swap for background upgrade)
6 new tests, 599 total, 0 regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -967,6 +967,19 @@ pub enum SignalMessage {
|
||||
external_ip: String,
|
||||
},
|
||||
|
||||
/// Birthday attack coordination — Acceptor tells Dialer which
|
||||
/// ports it has open. The Dialer then sprays QUIC connects to
|
||||
/// these ports (and optionally random ports) on the Acceptor's IP.
|
||||
HardNatBirthdayStart {
|
||||
call_id: String,
|
||||
/// Number of sockets the Acceptor opened.
|
||||
acceptor_port_count: u16,
|
||||
/// External ports discovered via STUN (the "hit list").
|
||||
acceptor_ports: Vec<u16>,
|
||||
/// Acceptor's external IP.
|
||||
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