Make pooled virtual L4 streams reusable - #971
Open
nbarbier-265 wants to merge 2 commits into
Open
Conversation
Virtual streams report fd -1, so the fd-based reuse check in reused_stream() always fails at getpeername() and pooled virtual streams can never be reused. The -1 fd also collides in the pool: ConnectionMeta keys connections by (group, id), and PoolNode stores them in a HashMap by id, so pooling a second virtual stream under the same group silently overwrites the first. Give every virtual stream a unique ID from a range no real fd can occupy (counting down from -2 on unix; from usize::MAX - 1 on windows). as_raw_fd() still returns -1 since there is no real fd. In reused_stream(), a negative ID routes to an address comparison instead of getpeername(): the peer address recorded in the stream's socket digest must equal the peer's address. Streams without a recorded peer address are never reused, so existing virtual streams keep today's behavior unless their creator opts in by setting SocketDigest::peer_addr. Fixes cloudflare#883
h2 0.3.27 comes in through the same legacy aws chain as the existing rustls-webpki ignores: dial9-tokio-telemetry -> aws-sdk-s3-transfer-manager -> aws-config -> aws-smithy-http-client, which still uses hyper 0.14. The advisory's only fix is h2 >= 0.4.16 and no 0.3.x patch exists, so this cannot be resolved from this workspace's manifests. The vulnerable code needs a malicious HTTP/2 peer; in this chain h2 is only a TLS client to AWS endpoints. Every CI run has failed the cargo audit step since the advisory was published on 2026-08-17.
nbarbier-265
force-pushed
the
virtual-stream-reuse
branch
from
August 20, 2026 21:25
a826670 to
8495a8c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #883.
Virtual streams report fd -1, so the fd-based reuse check in
reused_stream()always fails atgetpeername()and pooled virtual streams can never be reused. The shared -1 id also breaks pool bookkeeping:ConnectionMetakeys connections by (group, id) andPoolNodestores them in aHashMapby id, so pooling a second virtual stream under the same group key silently overwrites the first.Two changes:
usize::MAX - 1on windows (usize::MAXis INVALID_SOCKET).as_raw_fd()still returns -1 since there is no real fd.reused_stream(), a negative ID routes to an address comparison instead ofgetpeername(): the peer address recorded in the stream's socket digest must equal the peer's address.SocketDigest::peer_addris a publicOnceCell, so creators of virtual streams opt in by presetting it (e.g.SocketDigest::from_raw_fd(-1)+peer_addr.set(...)), which also keeps the lazygetpeernamefrom running. Streams without a recorded peer address are never reused, so existing virtual streams keep today's behavior.The address comparison is unix-only; on windows virtual streams remain non-reusable as today (the
matches_sockcheck fails on the synthetic handle), but the unique IDs fix the pool overwrite there too.Tests: unique/negative IDs; a pooled virtual stream with a matching recorded peer address is reused exactly once; a stream pooled under another peer's key (as a
reuse_hashcollision would) is rejected; a stream without a digest is rejected.