Add SPI for binding multiple datagram sockets per HTTP/3 bind target - #139
Open
simonjbeaumont wants to merge 1 commit into
Open
simonjbeaumont wants to merge 1 commit into
simonjbeaumont wants to merge 1 commit into
Conversation
simonjbeaumont
requested review from
FranzBusch,
aryan-25 and
gjcairo
as code owners
September 21, 2026 16:59
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.
Motivation
Each HTTP/3 bind target currently binds a single UDP socket and installs one QUIC channel handler, tied to the next available event loop. As a result each bound address is served by one event loop so HTTP/3 throughput is single-threaded.
It's possible to bind multiple sockets to the same port with
SO_REUSEPORTand have the system load-balance incoming traffic between the sockets in the group.By default, the kernel will route datagrams based on a stable hash of the 4-tuple, so UDP traffic with a stable 4-tuple will arrive at the same socket.
Unlike TCP, where connections are identified by their 4-tuple, QUIC connection IDs are part of the UDP payload, which allows for QUIC connections to migrate between paths, so serving multithreaded QUIC with a simple
SO_REUSEPORTgroup, will not support connection migration.While userspace packet steering is possible, high-performance multithreaded QUIC servers take advantage of platform-specific kernel mechanisms to route datagrams by QUIC Connection ID instead of 4-tuple (e.g.
sk_reuseporton Linux).This PR adds support for binding multiple sockets in an
SO_REUSEPORTgroup with an SPI for such a mechanism to participate in the server bootstrap.Modifications
protocol QUICDatagramSocketGroup(behind@_spi(QUICDatagramSockets)): conforming types provide a hook called on socket bind, and a connection ID generator for each socket.QUICDatagramSocketGroupFactory(behind@_spi(QUICDatagramSockets)): called during bootstrap for adopters to provide a socket group implementation, ornil.QUICConfiguration.datagramSocketGroupFactory(behind@_spi(QUICDatagramSockets)): Note, this is code-only config because it can't be expressed in Swift Configuration.serveto calladdHTTP3Listeners(plural) (wasaddHTTP3Listener), which binds one socket per event loop in the event loop group usingSO_REUSEPORT. ThedatagramSocketGroupFactoryis consulted to determine the socket group implementation, if any, which is called with each bound socket and to provide a connection ID generator.datagramSocketGroupFactoryis not configured, the behavior remains as-was: only one socket is bound and tied to the next available event loop in the event loop group.connectionIDGeneratorparameter..so_reuseportsocket option.Result
A bind target can serve HTTP/3 across several event loops, with an optional socket group mechanism provided via SPI.
When no factory is configured, nothing is changed: one socket is used per bind target (without
SO_REUSEPORT), tied to the next available event loop, with the default (random) connection ID generator.