Expand description
CONNECT-UDP tunnels (RFC 9298) over HTTP Datagrams (RFC 9297).
§Shape of a session
A CONNECT-UDP request opens a session: one request stream plus one connected UDP socket. Unlike a TCP tunnel, the payload does not travel on the request stream — it travels in QUIC DATAGRAM frames shared by every session on the connection, each tagged with the Quarter Stream ID of its request stream. So a session needs three things pumped at once:
- inbound datagrams, delivered by the HTTP/3 connection’s router through the channel this session claimed for its Quarter Stream ID;
- outbound packets read from the UDP socket;
- the request stream itself, which carries capsules and the close signal.
§Deliberate asymmetries
- The 2xx is sent immediately after the socket is ready (RFC 9298 §3.1): UDP has no handshake, so waiting for the target to answer would hang.
- Name resolution happens before the 2xx, so an unresolvable target is refused rather than becoming a silent black hole.
- The session is registered for datagram delivery before that resolution, so the packets a client is allowed to send optimistically (RFC 9298 §5) are buffered instead of dropped, and discarded with the session if the request is refused.
- An oversized outbound packet is dropped, never downgraded to a capsule (RFC 9298 §6.1).
- On the capsule fallback, a write to the client that does not complete
within one idle timeout ends the session by resetting the request
stream rather than finishing it — see
Session::forward_to_client, which is also why the idle timeout covers only the wait for work and not the work. - Closing the socket also closes the request stream, and vice versa (RFC 9298 §3.1) — a half-open UDP session has no meaning.
Constants§
- WELL_
KNOWN_ PREFIX - Path prefix of the RFC 9298 §2 default URI template.
Functions§
- parse_
target - Parses the RFC 9298 §2 default URI template.
- run
- Establishes a UDP tunnel for a
connect-udprequest and runs it.