jiebi/CodeConvo huggingface dataset:
Change:
In Sec. 4 it says: If negotiation of HTTP Datagrams fails (for example if an HTTP/3 SETTINGS frame was received without the H3_DATAGRAM SETTINGS Parameter), the client MUST consider its CONNECT-UDP request as failed. IIUC it is entirely possible to do CONNECT-UDP entirely with CAPSULE frames, so I don't see why a client should fail the attempt because the first hop is H/2 only, or whatever.
Thanks for writing this up. I think this is the right solution. I'll leave this open for some time to see if anyone else would like to comment. To add context: this text predates the creation of capsules, and now CONNECT-UDP works even if QUIC datagram frames aren't available. We'll want to pick a solution for URL though. If the H3_DATAGRAM setting also covers capsules we might still need this text. But for now we can remove it.

Discussion:
Since HTTP Datagrams require prior negotiation (for example, in HTTP/3 it is necessary to both send and receive the H3_DATAGRAM SETTINGS Parameter), clients MUST NOT send any HTTP Datagrams until <del> they have established support on a given connection.  If negotiation of HTTP Datagrams fails (for example if an HTTP/3 SETTINGS frame was received without the H3_DATAGRAM SETTINGS Parameter), the client MUST consider its CONNECT-UDP request as failed. </del> <ins> they have established support on a given connection. </ins> The proxy that is creating the UDP socket to the destination responds to the CONNECT-UDP request with a 2xx (Successful) response.
Change:
This is partly related to URL but seems to fit its own issue. Let's assume a CONNECT-UDP request succeeds with a 2xx and a flow of datagrams is merrily exchanged. How do endpoints indicate they are done with the stream and associated flows? The spec doesn't really say anything. The main example I can think of is where a server decides to perform housekeeping on UDP connections (maybe as part of runtime garbage collection, or in reaction to the network stack throwing errors) after a 2xx was been sent. H3 CONNECT says ends the request stream (that is, the receive stream at the proxy enters the "Data Recvd" state), the proxy will set the FIN bit on its connection to the TCP server. When the proxy receives a packet with the FIN bit set, it will close the send stream that it sends to the client. TCP connections that remain half-closed in a single direction are not invalid, but are often handled poorly by servers, so clients SHOULD NOT close a stream for sending while they still expect to receive data from the target of the CONNECT. stream. A proxy treats any error in the TCP connection, which includes receiving a TCP segment with the RST bit set, as a stream error of type H3CONNECTERROR; see Section 8. Correspondingly, if a proxy detects an error with the stream or the QUIC connection, it MUST close the TCP connection. If the underlying TCP implementation permits it, the proxy SHOULD send a TCP segment with the RST bit set. Not all of that guidance directly translates but I think it would be helpful to set some expectations for endpoints wrt how stream read or write states might change during the lifetime of a CONNECT-UDP request - especially in the cases where no stream data is being exchanged.
I took "FIN or RESET = done" as a given, but it's worth stating. Proxy behavior will likely be identical in both the graceful and abrupt closure cases.

Discussion:
proxy MUST keep the socket open while the CONNECT-UDP stream is open. Proxies MAY choose to close sockets due to a period of inactivity, but they MUST close the CONNECT-UDP stream before closing the socket. <ins> If a proxy is notified by its operating system that its socket is no longer usable, it MUST close the CONNECT-UDP stream. </ins> 6.
Change:
RFC 4787 (URL) does define some default timeouts for NAT bindings for UDP. Over general Internet I would not expect that UDP flow state is mainstained longer than these default values. Thus, I think it makes sense to indicate that if the MASQUE server is recovering state for inactive UDP flows, it SHOULD NOT recover them faster than the timeout recommendation in the behave UDP RFC.
That makes sense to me, can you send a PR? Otherwise I'll add it in the next batch.

Discussion:
proxy. The lifetime of the socket is tied to the request stream.  The proxy <del> MUST keep the socket open while the request stream is open.  Proxies MAY choose to close sockets due to a period of inactivity, but they MUST close the request stream before closing the socket.  If a proxy is notified by its operating system that its socket is no longer usable, it MUST close the request stream. </del> <ins> MUST keep the socket open while the request stream is open.  If a proxy is notified by its operating system that its socket is no longer usable, it MUST close the request stream.  Proxies MAY choose to close sockets due to a period of inactivity, but they MUST close the request stream before closing the socket.  Proxies that close sockets after a period of inactivity SHOULD NOT use a period lower than two minutes, see Section 4.3 of BEHAVE. </ins> A successful response (as defined in resp1 and resp23) indicates that the proxy has opened a socket to the requested target and is willing
Change:
Can you elaborate on what the motivation for this is? Introducing the "context ID allocation service" concept means that extensions can conveniently say "Then request a context ID from the allocation service and doo foo with it". If we remove this text, it'll make extension specs harder to write.
Occam's Razor. It's unnecessary complication that makes this text harder to read. I don't agree. The job of the specification is to document external behavior. I don't agree that it makes future specs more difficult. They can just say "allocate a context ID". It's an internal detail of the implementation that there is a context ID allocation service.
How about the following? It removes the concept but keeps the requirements we need.
I prefer removing the allocation service as a concept and specifying the requirements. I did find this a bit confusing in David's proposed text I think the point is clear already and the rationale is not required. Maybe remove this clause?
This text still has the problem that it first says you can allocate each context ID once and then later it says actually you can allocate it once per namespace. Why not say this upfront as in my PR?
My apologies NAME I think I had missed the added sentence in the middle when looking at this the first time. This LGTM modulo removal of the optional sentence at the end.

Discussion:
Section 16 of QUIC.  The context ID value of 0 is reserved for UDP payloads, while non-zero values are dynamically allocated: non-zero even-numbered context IDs are client-allocated, and odd-numbered <del> context IDs are server-allocated.  Implementations will provide a context ID allocation service.  That service will allow extensions to request a unique context ID that they can subsequently use for their own purposes.  This means that an HTTP client implementation of the context ID allocation service MUST only provide even-numbered IDs, while a server implementation MUST only provide odd-numbered IDs. The context allocation service MUST NOT return the same context ID twice, however it MAY return IDs in any order.  Once allocated, any context ID can be used by both client and server - only allocation carries separate namespaces to avoid requiring synchronization. Additionally, note that the context ID namespace is tied to a given HTTP request: it is possible for a context ID with the same numeric value to be simultaneously assigned different semantics in distinct requests, potentially with different semantics. </del> <ins> context IDs are server-allocated.  The context ID namespace is tied to a given HTTP request: it is possible for a context ID with the same numeric value to be simultaneously assigned different semantics in distinct requests, potentially with different semantics.  Context IDs must not be re-allocated within a given HTTP namespace but MAY be allocated in any order.  Once allocated, any context ID can be used by both client and server - only allocation carries separate namespaces to avoid requiring synchronization. </ins> Registration is the action by which an endpoint informs its peer of the semantics and format of a given context ID.  This document does
Change:
the target has to indicate its willingness to accept TCP connections by responding with a TCP SYN-ACK before the proxy can send it application data. UDP doesn't have this property, so a UDP proxy could send more data to an unwilling target than a CONNECT proxy. However, in practice denial of service attacks target open TCP ports so the TCP SYN-ACK does not offer much protection in real scenarios. Proxies MUST NOT introspect the contents of UDP payloads as that would lead to ossification of UDP-based protocols by proxies. This seems like an RFC 6919 "MUST (but we know you won't)"
Agreed. Are you proposing a change to the draft?
Yes. I would remove the last sentence. OTOH, given that the status of proxies is still under discussion maybe we just wait on this one.

Discussion:
could send more data to an unwilling target than a CONNECT proxy. However, in practice denial of service attacks target open TCP ports so the TCP SYN-ACK does not offer much protection in real scenarios. <del> Proxies MUST NOT introspect the contents of UDP payloads as that would lead to ossification of UDP-based protocols by proxies. </del> 8.
Change:
The doc has a development versioning header but it omits the ABNF. The format is described as a list of values on request headers and a single item on response headers. I'm going to assume this is an sf-list, can we state that to avoid uncertainty?

Discussion:
version: 0, 2").  When sent by the proxy, it contains a single draft number selected by the proxy from the list provided by the client (e.g., "connect-udp-version: 2").  Sending this header is RECOMMENDED <del> but not required. </del> <ins> but not required.  Its ABNF is: </ins> 4.
Change:
For some kinds of implementations, the action of closing a QUIC stream is not immediate. Do we really want to make this ordering so strong? There's not really any way to enforce it.
That makes sense. I'd like to keep the "MUST close the request stream" but we can remove the ordering requirement or make it a SHOULD.
Either of those options works for me. I can make a PR tomorrow.

Discussion:
proxy is notified by its operating system that its socket is no longer usable, it MUST close the request stream.  Proxies MAY choose to close sockets due to a period of inactivity, but they MUST close <del> the request stream before closing the socket.  Proxies that close </del> <ins> the request stream when closing the socket.  Proxies that close </ins> sockets after a period of inactivity SHOULD NOT use a period lower than two minutes, see Section 4.3 of BEHAVE.
Change:
When the client proxy hop is HTTP/3, and HTTP/3 datagrams are in use, the practical limit of datagrams is the maximum size of a QUIC packet minus header overheads. When DATAGRAM capsules are used, the logical limit is increased to that of an entire data stream. For the UDP proxying use case, a proxy that converts capsules into UDP datagrams will have a practical limit to the size of UDP datagrams that it can send. And it most likely wants to avoid fragmentation. When fragmentation is to be avoided, I would expect many proxy implementations to have a practical limit of less than 2000 for the size they would be willing to send. Such proxies can drop the contents of too-large datagrams but they would be required to drain them completely in order to continue reading the data stream. This seems like a possible avenue for DoS, because a client could send a verylarge datagram in theory, it would need to buffer the entirety of the datagram before sending it. We might be tempted to try to create some way for endpoints to communicate the practical limit of datagram capsules. But that could be hard due to the end-to-end version-indendent design. Instead we might just provide some guidance that $very_large capsules might cause problems for implementations, and that receivers might have local (or implementation-specific) limits that they want to enforce, which they could do by closing the stream or closing the connection.
According to RFC 768, the maximum length of a UDP payload is 65527. I would add some text to draft-ietf-masque-connect-udp along the lines of: Additionally, I think we could add some guidance text to draft-ietf-masque-h3-datagram along the lines of: I would leave the communication of actual limits to an extension.
Yeah we don't need to be 100% prescriptive, just spelling out foothold WFM

Discussion:
request with a failure, or if the datagrams are received by the proxy before the request. <ins> Endpoints MUST NOT send HTTP Datagrams with payloads longer than 65527 using Context ID zero.  An endpoint that receives a DATAGRAM capsule using Context ID zero whose payload is longer than 65527 MUST abort the stream.  If a proxy knows it can only send out UDP packets of a certain length due to its underlying link MTU, it SHOULD discard incoming DATAGRAM capsules using Context ID zero whose payload is longer than that limit without buffering the capsule contents. </ins> 6. Proxies SHOULD strive to avoid increasing burstiness of UDP traffic:
Change:
An application that tunnels UDP may rely on certain properties or features of the socket that the proxy creates. The draft covers some of these but doesn't seem to mention the UDP fragmentation. TURN has a whole section on this URL QUIC, for example, requires that and recommends the Don't Fragment (DF) bit MUST be set if possible. Since a proxy is agnostic to the application protocol in use (I'm assuming that because we don't mention the anywhere) perhaps CONNECT-UDP would benefit from a signal the client can send to the proxy to state it's DF preferences.
This sounds like a worthwhile extension draft? I don't think it's required to have a functional CONNECT-UDP protocol
One argument for doing it here is that one of the common uses of CONNECT-UDP will be to tunnel QUIC, and this is an obvious footgun in consideration of RFC 9000 requirements. The opposite way to solve the problem could be to add MUST/SHOULD language about proxies setting DF by default. And then require an extension to signal to disable it. But this is solutionizing a bit. Really, I want to be able to write a client that can have consistent expectations about the way datagram payload gets sent on UDP. Otherwise when things go wrong I'm left guessing and I might not have the information that the proxy did. I could even live with text in this document that raises this as a consideration but punts on the problem.
Note that this isn't just about setting in IPv4. It's also about whether to apply sender fragmentation, in IPv6. I would be OK with declaring that all fragmentation is off by default, and leave it to extensions to turn it on.
Good point Ben!
I'd be OK with saying proxies MUST NOT explicitly add fragmentation and SHOULD set the DF bit. We can't say MUST set DF because not all operating systems allow setting the DF bit on UDP sockets.
RFC 9000 says , not a fan?
"MUST ... if possible" is the same as "SHOULD" for me, I don't much care between them.

Discussion:
indicates that the request has failed, and the client MUST therefore abort the request. <ins> Proxies MUST NOT introduce fragmentation at the IP layer when forwarding HTTP Datagrams onto a UDP socket.  In IPv4, the Don't Fragment (DF) bit MUST be set if possible, to prevent fragmentation on the path.  Future extensions MAY remove these requirements. </ins> 3.2. When using HTTP/1.1, a UDP proxying request will meet the following
Change:
With the CONNECT UDP, a proxy will send and receive UDP datagrams on behalf of a client. However, in addition to these UDP datagrams, it could also receive ICMP messages. The current draft does not discuss how these ICMP messages should be handled by a proxy and how they would need to be conveyed to the client. It probably makes sense to at least discuss how ICMP destination/network/port unreachable should be handled by the proxy (ignore, terminate the HTTP connection, ...)
I agree. I'm not yet sure what the best solution is (closing the stream on port unreachable would improve reliability but does introduce a way for an attacker to deny service) but we should figure that out and provide guidance in the doc.
FWIW, the way TURN handles this is by having a way for the server to forward ICMP indications. URL Obviously, in order to have this in MASQUE we would need to have some sort of type indicator in the datagram.
I do want the relevant information in the ICMP to make it to the client. However, ICMP falls into the asynchronous information that is not directly associated with a forwarded packet. It can clearly be a forwarded packet per EKR's suggestion. We have other cases where we have information that is related to the associated packet, for example ECN. So I think this there is an important high level design choice here that we need to sorted out. I think for the general extensibility lets consider a content identifier so that just UDP payloads can be separated from additional types with additional fields.

Discussion:
The lifetime of the socket is tied to the request stream.  The proxy MUST keep the socket open while the request stream is open.  If a proxy is notified by its operating system that its socket is no <del> longer usable, it MUST close the request stream.  Proxies MAY choose to close sockets due to a period of inactivity, but they MUST close the request stream when closing the socket.  Proxies that close sockets after a period of inactivity SHOULD NOT use a period lower than two minutes, see BEHAVE. </del> <ins> longer usable (for example, this can happen when an ICMP "Destination Unreachable" message is received, see ICMP6), it MUST close the request stream.  Proxies MAY choose to close sockets due to a period of inactivity, but they MUST close the request stream when closing the socket.  Proxies that close sockets after a period of inactivity SHOULD NOT use a period lower than two minutes, see BEHAVE. </ins> A successful response (as defined in resp1 and resp23) indicates that the proxy has opened a socket to the requested target and is willing

defeats the end-to-end unreliability characteristic that methods such as Datagram Packetization Layer Path MTU Discovery (DPLPMTUD) depend on DPLPMTUD.  In this scenario, the proxy SHOULD drop the UDP payload <del> and send an ICMP "Packet Too Big" message to the target ICMP6. </del> <ins> and send an ICMP "Packet Too Big" message to the target, see ICMP6. </ins> 6.2.
Change:
. That template contains the and variables which convey the target host/port in the pseudo-header. This has the following benefits: allows custom schemes allows proxy to pick path they use However it has downsides: it requires parsing URI templates which is more of a pain than it seems it prevents reusing the same configuration between CONNECT-UDP and CONNECT-IP Alternatively, we could replace the configuration URI template with a configuration URL, and instead convey the target host/port in separate HTTP headers. This has the same benefits of the URI template without the downsides.
Discussed this issue at IETF 112, consensus in the room was to keep the URI template but to tighten the template restrictions.

Discussion:
2. Clients are configured to use UDP Proxying over HTTP via an URI <del> Template TEMPLATE.  The URI template MUST contain exactly two variables: "target_host" and "target_port".  Examples are shown below: </del> <ins> Template TEMPLATE with the variables "target_host" and "target_port". Examples are shown below: The URI template MUST be a level 3 template or lower.  The URI template MUST be in absolute form, and MUST include non-empty scheme, authority and path components.  The path component of the URI template MUST start with a slash "/".  All template variables MUST be within the path component of the URI.  The URI template MUST contain the two variables "target_host" and "target_port" and MAY contain other variables.  The URI template MUST NOT contain any non-ASCII unicode characters and MUST only contain ASCII characters in the range 0x21-0x7E inclusive (note that percent-encoding is allowed). The URI template MUST NOT use Reserved Expansion ("+" operator), Fragment Expansion ("#" operator), Label Expansion with Dot-Prefix, Path Segment Expansion with Slash-Prefix, nor Path-Style Parameter Expansion with Semicolon-Prefix.  If any of the requirements above are not met by a URI template, the client MUST reject its configuration and fail the request without sending it to the proxy. </ins> Since the original HTTP CONNECT method allowed conveying the target host and port but not the scheme, proxy authority, path, nor query,
Change:
For HTTP/1.1, should the method be "GET" or "CONNECT"? WebSockets uses GET -- are there any uses of "Extended CONNECT" that use CONNECT rather than GET? (issue based on by NAME
In my experience, H1.1 CONNECT for anything but it's intended purpose of proxying will see some deployment problems. The last HTTP spec admits some origins might respect it, but I suspect many HTTP components won't like it. I think sticking with GET plus Upgrade header field is a good choice
At IETF 113, after lengthy discussion the consensus is the room appeared to be to switch to GET so I'm merging so we have a version of the draft ready for WGLC

Discussion:
When using HTTP/1.1, a UDP proxying request will meet the following requirements: <del> the method SHALL be "CONNECT". </del> <ins> the method SHALL be "GET". </ins> the request-target SHALL use absolute-form (see H1).
Change:
Most likely just need a sentence saying that the data stream is treated the same regardless if capsules are used or not.
Adding that sentence sounds fine by me.

Discussion:
6. <ins> Data streams (see capsule-protocol) can be prioritized using any means suited to stream or request prioritization.  For example, Section 11 of PRIORITY. </ins> Prioritization of HTTP/3 datagrams is not defined in this document. Future extensions MAY define how to prioritize datagrams, and MAY define signaling to allow endpoints to communicate their