Skip to content

Implement receive-side WebTransport per-session stream flow control (draft-15 §5.6.2) #3751

Description

@jesup

Implement receive-side WebTransport per-session stream flow control (draft-15 §5.6.2)

Background

draft-ietf-webtrans-http3-15 §5.6.2 defines a cumulative per-session stream limit, analogous to QUIC's MAX_STREAMS: the total number of streams of a given type an endpoint may open over the session's lifetime, including
closed streams
. The limit starts at the peer's SETTINGS_WT_INITIAL_MAX_STREAMS_{UNI,BIDI} and is raised over time by
WT_MAX_STREAMS capsules.

Today neqo only partially implements this:

  • It enforces the peer's initial SETTINGS value when we open streams (one-way send enforcement), but that value is static — we never process WT_MAX_STREAMS, so the limit can never grow.
  • It does not enforce, against incoming streams, the limit we advertised to the peer. Note: right now we always send 0, which means no limit, so this is not a current problem. In the Draft-15 patches I plan to expose settings for the max streams values, and this could come into play. If we decide not the implement the settings values, then this issue becomes moot until we do

This issue covers the receive side. Sending WT_MAX_STREAMS (the flow-control provider that grows a peer's limit) is tracked separately.

Tasks

1. WT_MAX_STREAMS capsule

  • Add the capsule to WebTransportFrame with the two type codepoints (§9.3): 0x190B4D3F (bidi), 0x190B4D40 (uni). Decode the Maximum Streams varint.
  • On receipt, raise our send limit for that stream type. The effective send limit becomes max(peer SETTINGS initial value, highest WT_MAX_STREAMS received), and the existing stream-creation check must use it.

2. WT_MAX_STREAMS validation (§5.6.2)

  • Maximum Streams > 2^60 MUST be treated as H3_DATAGRAM_ERROR (connection error). Requires an H3_DATAGRAM_ERROR (0x33, RFC 9297 §5.5) error code.
  • A Maximum Streams value less than a previously received one MUST close the WebTransport session with WT_FLOW_CONTROL_ERROR.

3. Receiver-side enforcement (§5.6.2)

  • Track the cumulative count of remote-initiated streams per type (never decremented on close — the limit is cumulative).
  • When an incoming stream would exceed the limit we advertised (wt_initial_max_streams_*; 0 = not advertised = unlimited), close the WebTransport session with WT_FLOW_CONTROL_ERROR. This means tearing down the session's sub-streams, notifying the application (session_end with the error reason), and resetting the CONNECT stream so the peer learns.

4. Error codes

  • WT_FLOW_CONTROL_ERROR = 0x045d4487 (draft-15 §9.5).
  • H3_DATAGRAM_ERROR = 0x33.

Acceptance criteria

  • A peer that sends WT_MAX_STREAMS raising the limit lets us open more streams than its initial SETTINGS value permitted; the cumulative semantics hold (closing a stream does not free a slot).
  • An incoming stream beyond our advertised limit closes the session with WT_FLOW_CONTROL_ERROR, surfaced to the application.
  • A decreasing WT_MAX_STREAMS closes the session with WT_FLOW_CONTROL_ERROR; a value > 2^60 is an H3_DATAGRAM_ERROR. Unit tests cover capsule round-trip, the limit being raised, and the receiver enforcement path. (A test-only injection helper is acceptable for exercising the receive path, since we don't yet send these capsules.)

Out of scope

  • Sending WT_MAX_STREAMS / WT_STREAMS_BLOCKED (this should be a separate "flow-control provider" issue).
  • Exact decrease detection against the SETTINGS-advertised initial value when the very first capsule is received (the session may not retain that baseline); acceptable to compare only against prior capsules initially, and note it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions