fix(p2p): connection cleanup — 4 fixes for stale/dead connections

PRD 4: Disable IPv6 direct dial/accept temporarily. IPv6 QUIC
handshakes succeed but connections die immediately on datagram
send ("connection lost"). IPv4 candidates work reliably. IPv6
candidates still gathered but filtered at dial time.

PRD 1: Close losing transport after Phase 6 negotiation. The
non-selected transport now gets an explicit QUIC close frame
instead of silently dropping after 30s idle timeout. Prevents
phantom connections from polluting future accept() calls.

PRD 2: Harden accept loop with max 3 stale retries. Stale
connections are explicitly closed (conn.close) and counted.
After 3 stale connections, the accept loop aborts instead of
spinning until the race timeout.

PRD 3: Resource cleanup — close old IPv6 endpoint before
creating a new one in place_call/answer_call. Add Drop impl
to CallEngine so tasks are signalled to stop on ungraceful
shutdown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-12 15:11:50 +04:00
parent 4d66d3769d
commit 29cd23fe39
3 changed files with 70 additions and 45 deletions

View File

@@ -1493,3 +1493,12 @@ impl CallEngine {
}
}
}
impl Drop for CallEngine {
fn drop(&mut self) {
// Safety net: if stop() was never called (crash, app
// backgrounding), signal tasks to exit so they don't
// spin on a dropped transport.
self.running.store(false, Ordering::SeqCst);
}
}