QUIC connect address racing (Happy Eyeballs)
This is a tracking issue for the sequential QUIC address-fallback defect.
PR #28 is the primary fix.
Child issue
| Issue |
Locus |
Status |
| #27 — QUIC waits on each resolved address before trying next |
lore-transport/src/quic/client.rs:764–793 |
PR #28 open |
Defect detail
lore-transport/src/quic/client.rs:764–793 — connect() iterates resolved
addresses sequentially:
for remote_addr in remote_addrs {
// ...
match connecting.await {
Ok(connection) => { return Ok(connection); }
Err(err) => { /* log, try next */ }
}
}
Each connecting.await blocks on the full OS/QUIC handshake timeout before
the next address is attempted. On dual-stack hosts or multi-address DNS records
where the first address is unreachable, each failed attempt can stall for
30–75 seconds before the fallback activates.
IDLE_TIMEOUT_MS = 30000 (line 71) is max_idle_timeout for an established
connection, not a per-handshake deadline. It does not bound the stall.
PR #28 fix direction
PR #28 implements Happy Eyeballs (RFC 8305): concurrent staggered connection
attempts, 250 ms inter-attempt delay, max 10 concurrent, first-success-wins
cancellation. This reduces the worst-case fallback latency from
N × OS_timeout to approximately (N−1) × 250ms + handshake_latency.
A complementary per-attempt tokio::time::timeout would bound the total stall
when all addresses are unreachable (RFC 8305 §5 recommends a
connection attempt delay timeout), but is not part of PR #28.
Background
Identified in the open-bug theme analysis (triage/2026-06-bug-theme-analysis.md,
branch valentina2509:docs/bug-theme-analysis).
QUIC connect address racing (Happy Eyeballs)
This is a tracking issue for the sequential QUIC address-fallback defect.
PR #28 is the primary fix.
Child issue
lore-transport/src/quic/client.rs:764–793Defect detail
lore-transport/src/quic/client.rs:764–793—connect()iterates resolvedaddresses sequentially:
Each
connecting.awaitblocks on the full OS/QUIC handshake timeout beforethe next address is attempted. On dual-stack hosts or multi-address DNS records
where the first address is unreachable, each failed attempt can stall for
30–75 seconds before the fallback activates.
IDLE_TIMEOUT_MS = 30000(line 71) ismax_idle_timeoutfor an establishedconnection, not a per-handshake deadline. It does not bound the stall.
PR #28 fix direction
PR #28 implements Happy Eyeballs (RFC 8305): concurrent staggered connection
attempts, 250 ms inter-attempt delay, max 10 concurrent, first-success-wins
cancellation. This reduces the worst-case fallback latency from
N × OS_timeoutto approximately(N−1) × 250ms + handshake_latency.A complementary per-attempt
tokio::time::timeoutwould bound the total stallwhen all addresses are unreachable (RFC 8305 §5 recommends a
connection attempt delaytimeout), but is not part of PR #28.Background
Identified in the open-bug theme analysis (triage/2026-06-bug-theme-analysis.md,
branch
valentina2509:docs/bug-theme-analysis).