transport=tls: single-connection pump — completed-idle slot hold + silent multi-peer drop (3c.2 follow-up) #61
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
femboy/yip#61
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The
transport=tlsmimicry pump (bin/yipd/src/tls.rs, 3c.2) serves one TCP+TLS connection at a time (documented in the module header —Epollwatches exactly two fds; onlypeers.first()is served). PR #60-era review hardened the cheapest availability gap (a stalled handshake can no longer pin the slot —HANDSHAKE_TIMEOUT+ both-role backoff, shipped in 3c.2), but two related limitations remain, both rooted in the single-connection design:1. A completed-but-idle zero-auth TLS connection still holds the slot
Because the outer TLS is zero-auth by design, an attacker (or a random internet scanner on a public
listen, especially once yip defaults to 443) can complete the TLS handshake and then never drive the inner Noise-IK handshake.pump()tears down only on I/O/framing errors, not on "inner handshake never completed" — so the connection sits inpumpservicing ticks while the real peer is locked out. Severity is lower than the pre-fix stalled-handshake DoS (it costs the attacker a full TLS handshake per attempt, which backoff rate-limits) but it is still an availability gap unique to this transport (the QUIC sibling accepts many connections concurrently).Fix directions: an inner-handshake-completion deadline in
pump(drop the connection ifPeerManagerreports no established session within N seconds), and/or accept concurrently and let the inner handshake pick the winner.2. Multi-peer
transport=tlssilently serves only the first peerrun_tlsservespeers.first()and ignores the rest with no runtime warning (in-codeTODO(3c.2 follow-up)). A config with >1 peer undertransport=tlslooks like it works but silently drops all but one peer.Fix directions: one
run_tlsper peer on distinct threads/ports, or a multiplexing pump analogous toquic.rs'sQuicEndpoint. At minimum, log a warning whenpeers.len() > 1.Scope
Both fit a multi-connection TLS transport refactor (or the relay-tier REALITY milestone 3c.3), not the 3c.2 costume milestone. Filing to track; not a blocker for 3c.2 (opt-in, last-resort, single-peer-direct path).