Change:
This will help interop efforts before publication.
I think we can address many of the complexity concerns with the H3 Datagrams draft by adjusting the architecture to focus more on WebTransport. Here's a sketch of the required changes: In WebTransport, Datagrams are associated with Streams, not Sessions. This requires simplifying H3 Datagram's "Quarter Stream ID" to just "Stream ID". Get rid of "Datagram Contexts". The context for a Datagram is its associated Stream. Run the MASQUE services over WebTransport. The URL must distinguish the service in use (e.g. UDP vs. IP proxying). The value is . UDP and IP proxy services only use Datagrams and Bidirectional Streams. The stream contains messages in a simple TLV format ("capsules"). There are three basic capsule types: No payload Contains an integer success/error code Arbitrary payload Equivalent to an associated Datagram, but reliable and in-order "False Start" is supported by sending a capsule (or a Datagram) immediately after . Non-default datagram formats can be enabled later by defining an capsule type, which would elicit an error from basic implementations. Intermediaries that relay between H2 and H3 need to understand WebTransport, but do not need to know anything about MASQUE or the Stream contents. More aggressive variations: Use the "CONNECT stream" for the default format. Avoids the need for , but may not be compatible with the expected WebTransport APIs and use patterns. Move target host and port specification from the URL to an capsule. Perhaps clearer, but would deviate from the current CONNECT-IP and CONNECT-UDP consensus plans. Reuse HTTP/3 frames instead of capsules (/ -> , -> ). Simpler and more flexible, but possibly confusing.
This sounds more complicated than the current design, and much more complicated than the . In what way does this simplify things?
Using that PR as a baseline, this change would eliminate most of the text in the H3 Datagrams document. All mention of contexts, Sec-Use-Datagram-Contexts, etc. (Sections 2.1, 2.2, 6, and 9.2) would be deleted. All discussion of Capsules (Sections 4 and 9.3) would be extracted to a separate document, as Capsules are now a framing layer used only by MASQUE, inside WebTransport. All discussion of intermediary processing (Section 4.3, much of Section 4.4) would be deleted. We could also consider eliminating the H3_DATAGRAM setting (Sections 5 and 9.1), as there would no longer be any active use case for it independent of WebTransport. It would also be dramatically simpler to implement for any parties that already carry a WebTransport implementation.
Remember that the complexity that we care about is the aggregate complexity of what needs to be implemented, not the complexity of this one draft in isolation. This proposal removes some complexity from this draft but introduces a large dependency; this increases overall complexity.
I disagree. The total amount of specification text is greatly reduced. The total amount of code in a typical participating intermediary, client, or server is reduced in each case. The complexity of reasoning about the system is greatly reduced, as the behavior of each component is simpler and can be analyzed independently (e.g. intermediaries don't interact with capsules and don't need to know anything about MASQUE). Perhaps a relevant question here is: do you believe a typical MASQUE implementation will live in a codebase that also carries a WebTransport implementation? I do, so we can simplify the MASQUE design by using it. I also think there are positive ecosystem effects to consider. If we can agree on a single thing that intermediaries have to do ("implement WebTransport relaying"), we are likely to get to much broader compatibility than if intermediaries have to take distinct actions for compatibility with WebTransport and MASQUE.
On first inspection of this proposal, I do not like the idea of coupling MASQUE to WebTransport.
I think this is intriguing and should be explored further. I've often found it confusing that both WebTransport and masque are defining similar concepts like the CONNECT stream and how to associate datagrams with it. Deferring those concepts to WebTransport means there's only one way to do this. For example, I think connect-udp implemented with this proposal would result in almost identical bits being sent on the wire, so it's hard to argue that it's more complex. It also establishes clear boundaries about where the contexts, etc, belong -- in the protocols that are layered on top. Intermediaries that are not participating in those protocols just have to know how to relay WebTransport (translating between HTTP versions) as Ben says. And intermediaries that are participating aren't HTTP intermediaries at all, they are WebTransport servers. In a way, datagrams never really belonged in HTTP itself, as they have no semantic meaning to HTTP, any more than server initiated bidirectional streams do. In the early days it wasn't clear that WebTransport would be over HTTP, so there was less similarity. But now that it is, having WebTransport be the single way for HTTP to access QUIC transport features beyond request/response is appealing. A couple notes on the proposal itself: WebTransport -02 uses HTTP Datagram, so the "Quarter Stream ID" is implicit. It doesn't preclude you from attaching datagrams to WebTransport client initiated bidi-streams that are not HTTP request streams, but that's most likely an oversight. I believe the intent is for datagrams to only associated with the CONNECT stream (Session). Why can they not also send datagrams?
That's not the case today. Capsules and how to send datagrams are defined in draft-ietf-masque-h3-datagram, and both WebTransport and CONNECT-UDP have a dependency on it. There is only one way to do this and there's no concept that is defined twice. Implementing a WebTransport-supporting intermediary is much more complex than implementing a datagram-supporting intermediary. You now need to implement all of the stream logic form WebTransport which CONNECT-UDP doesn't need. In the Privacy Proxy space there's interest in building CONNECT-UDP intermediaries that have no interest in WebTransport.
Yes. I'm proposing a modification to HTTP Datagram, replacing "Quarter Stream ID" with "Stream ID". Yes, they can. I meant that they don't use unidirectional streams. Sorry if that was confusingly worded.
The extended CONNECT setup and how to translate between protocol versions is defined twice, right? Maybe the latter would be reduced to once if the H2 version of WebTransport adopts Capsules. Can you clarify "intermediary" here? Are they looking to build an endpoint that terminates the CONNECT-UDP request and forwards raw UDP datagrams? If this is all you do, you do not need to be a full WebTransport proxy, and the code is basically the same. If they want to have a chain of proxies, then the non-terminating "intermediaries" would need to understand how to translate datagrams via WebTransport across HTTP/3 datagrams capable and non-HTTP/3 capable transports. If they have no interest beyond datagrams, you can make a minimal WebTransport proxy that sets the stream limits to 0 and only handles datagrams, and again -- same code. Where'd you run into trouble is that these layered protocols may need a control channel, and the Capsule protocol has been created to allow them to use the CONNECT stream for this. The WebTransporty design would be a protocol specific control stream. There you'd need the WebTransport machinery for streams, which is pretty simple over H3 but heavierweight over H2.
You're right, I was assuming a world where WebTransport-over-h2 uses capsules. I was using the definition from , which would be the "non-terminating intermediary" from your last comment. So you're saying we put MASQUE over WebTransport and then have MASQUE only implement a part of WebTransport. What's the value in pulling in WebTransport then? WebTransport and CONNECT-IP both need a control stream for operation of their base protocol, and CONNECT-UDP will most likely need one for extensibility. If you're suggesting we scrap capsules and have them all build their own control stream, that's not going to improve complexity.
I can believe that there may be a need for single-purpose CONNECT-UDP intermediaries. However, if we believe these intermediaries will normally be implemented using a general-purpose H3 server framework (e.g. Envoy), then the codebase will likely already contain a WebTransport forwarder, and we aren't helping anyone by not using it. I also don't see a lot of complexity in H3->H3 WebTransport forwarding, especially if we fully remove Capsules from WebTransport-H3. H3H2 forwarding is complicated, but basically similar in all the different proposals. The important thing (it seems we agree) is to avoid specifying it twice. This works fine within the proposal here. The default stream type for CONNECT-IP (created by ) would allow some more capsule types for all the address management stuff. If you don't like , you could possibly send all those capsules on the CONNECT stream (in H3), and use its associated Datagrams for packets. The other WebTransport streams would be used for extensibility, i.e. non-default format types, As NAME noted, this would allow a baseline-only MASQUE service to implement a subset of WebTransport.
You're saying you get simplicity by removing capsules, and then you add TLVs which are basically capsules. So it's unclear to me what complexity is saved by removing capsules, which probably means I'm not understanding the proposal here. NAME could I ask to show me the wire interactions (something like what we have in the ) for these two scenarios? "vanilla" CONNECT-UDP without any extensions CONNECT-UDP with an extension such as your PMTUD extension
No, I'm saying you get overall simplicity by removing Contexts, which duplicate the functionality of WebTransport Streams. Capsules are relocated from H3 Datagram to "MASQUE", simplifying H3 Datagrams but not MASQUE. Both and this proposal start with 3 capsule types and expect more to be defined. Here are some interaction diagrams. These show interaction on top of the WebTransport layer. That could be considered cheating, but I'm assuming that a WebTransport implementation is available. Vanilla CONNECT-UDP CONNECT-UDP with the PING extension
I don't understand how this proposal allows a simple way to run multiple tunnels over a single QUIC connection. Can you explain how it would be supported to, for example, open multiple independent connections to e.g. conn-URL for N up to 10? How can errors the server encounters opening tunnels be reflected back to the client (e.g. NXDOMAIN, or other such problems)?
NAME In this proposal, each tunnel would be a separate WebTransport "session". WebTransport supports multiplexing many sessions over a single HTTP/3 connection. (I'm not sure if this was always true, but it's true in the latest draft.) Errors could be reflected in the HTTP status code. (This proposal does not alter the URL format used for CONNECT-UDP or CONNECT-IP.)
Thanks for the clarification. I have concerns on how easy it would be to conflate webtransport for application services and for proxying services, that might be able to be solved with design changes, not sure. I would also be concerned about how many resources an HTTP/3 server might need to allocate to allowing sufficient bidirectional streams for WebTransport sessions, and conventional CONNECT streams. In contrast, the current design of HTTP datagrams and CONNECT-UDP mean is more straightforward to add CONNECT(-UDP) to an extant form of proxy server.
What's the memory cost of an idle stream? Is it significant?
My concern is more that, right now I can bound the number of concurrent CONNECT(-UDP) streams easily by managing the concurrent stream limit (in either H2 or H3). In a WebTransport server, I would need to possibily also accomodate the additional bidi streams that can be latched onto web transport sessions. I'm assuming that in this proposal, MASQUE would actually need them. But if I'm standing up a webtransport service, then it isn't clear to me how clients might need to mix different actual usage of the webtransport sessions. That makes capacity planning harder that it is already for this use case. This concern probably reflects more on the WebTransport design more than anything, but illustrates a concern we would place on proxy deployments that don't even have to worry about it today.
Interesting. However, as you hint, a better solution might be to make SETTINGSENABLEWEBTRANSPORT an integer, the maximum number of open WebTransport sessions allowed. That would allow improved control over proxy resource usage.
NAME your second example from URL is incomplete. "CONNECT-UDP with the PING extension" needs the ability to send both UDP payloads and pings, not just pings. I'm interested in understanding how demultiplexing works
NAME It's just Example 1 again, unmodified, so I didn't want to duplicate it. Demultiplexing within a Session is by Stream ID.
I see, thanks for explaining. I think I understand the proposal now. If one accepts your premise that "WebTransport is deployed everywhere, MASQUE arrives after that", then your solution makes sense. I completely reject the premise though, as it doesn't match reality.
This issue has reframed for me the way I think about CONNECT-UDP and CONNECT-IP. CONNECT-UDP is a subset of the WebTransport functionality that piggybacks a control stream on the CONNECT stream, and disallows other kinds of streams. WebTransport could certainly provide required functionality. David may be right that coupling could slow adoption because WebTransport has more moving pieces. Lucas raises a good point that managing resources for those pieces is more complex too. I wonder how we think about what other applications might try to use H3-Datagram rather than WebTransport to leverage datagrams within an HTTP connection, and if we think any of those are good ideas.
This has been supplanted by the proposal in .

Discussion:
the connection with error H3_SETTINGS_ERROR.  In all cases, the maximum permitted value of the H3_DATAGRAM SETTINGS parameter is 1. <ins> 6.1. [[RFC editor: please remove this section before publication.]] Some revisions of this draft specification use a different value for the H3_DATAGRAM Settings Parameter.  This allows new draft revisions to make incompatible changes.  Multiple draft versions MAY be supported by either endpoint in a connection.  Such endpoints MUST send multiple values for H3_DATAGRAM.  Once an endpoint has sent and received SETTINGS, it MUST compute the intersection of the values it has sent and received, and then it MUST select and use the most recent draft version from the intersection set.  This ensures that both endpoints negotiate the same draft version. </ins> 7. Prioritization of HTTP/3 datagrams is not defined in this document.