Draft: draft-ietf-masque-connect-udp

Commentary: As discussed on the list , there appears to be agreement to replace a custom method with extended CONNECT . 
 Some potential bikesheds / comments from ( which generally looks good ): 1 ) For  , should the method be " GET " or " CONNECT " ? WebSockets uses GET -- are there any uses of " Extended CONNECT " that use CONNECT rather than GET ? 2 ) Should the default URI template have a /.well - known prefix ? For example , " /.well - known / masque / udp/{targethost}/{targetport}/ " ? 3 ) Should the upgrade token be " connect - udp " or " masque - udp " ? 
 Great questions , but let 's keep one issue per topic , I 've opened , , and to track these individual points . 
 With the switch to use Extended CONNECT in for UDP , it seems logical to shift TCP to also use the same model . Two approaches would either be for a new draft ( draft - ietf - masque - connect - tcp ? ) , or to generalize the connect - udp draft since there is lots in - common given how things are now factored . 
 I was thinking about that when I wrote the PR and I agree 
 I 'd worry accommodating TCP is scope creep for this draft . H2 and H3 CONNECT already support TCP . Extended CONNECT might be nicer but then we 'd probably want text to explain why endpoints might choose one or another . That seems better suited to some other document to me right now . edit : I also think the HTTP WG could probably own that work 
 I 'm realizing my " I agree " was n't very specific , I meant : I agree that we should do the same for TCP . I did n't have a strong opinion for this draft vs a new draft , but based on I think a separate draft might be best 
 Yeah , this should probably be a separate draft , but defining connect - tcp would be nice to make things more parallel . 
 Closing this issue since we 'll want to do this in a separate draft 
 draft 03 states indicates that the proxy has opened a socket to the request - target and is willing to proxy UDP payloads . Any response other than a successful response indicates that the tunnel has not yet been formed . the use of " not yet " seems a little hand waving . What 's the intent of the statement , I think it would help to be more specific . We could presume that a non - final 1xx response could indicate that the tunnel is possibly yet to be created . Whereas a 4xx could mean that the client erred and that no tunnel is ever going to be created . 
 This text was lifted from the but I 'm sure we can be even more clear . Can you propose some text ? 
 touché Semantics still says it , so it must mean something But both the H2 and H3 definitions do n't really do any handwaving and just say [ RFC0793 ] to the server identified in the " : authority " pseudo- header field . Once this connection is successfully established , the proxy sends a HEADERS frame containing a 2xx series status code to the client , as defined in Section 15.3 of [ SEMANTICS ] . Since CONNECT - UDP is trying to cover all 3 known major versions , it has to be careful . If I had to write a PR , I might try to combine the most up to date  text with H2 / H3 , and in the process drop this " not yet been fully formed " clause . However , maybe I 'm missing something that HTTP WG aficionados will tell be is really important . 
 So I think it 's pretty clear that 2xx means " yes send me your UDP " and 4xx/5xx means " nope do n't send your UDP " . I think the points that might need clarification are : 1xx responses allowed ? 1xx is allowed , how does the client react ? 3xx allowed ? 3xx is allowed , how does the client react ? 
 This was fixed by , closing . 
 So the URI scheme registration rules ( ) have a number of things to consider . Thus , at a minimal the definition needs its own section where that is properly covered . My experience is that the template and definition needs its own sections to make it easy to define clearly and know where things reside . I would also note that issue depending on the semantics is for masque scheme and how it relates to the proxied protocol it might make sense to split this scheme out into its own document even if it will be a short one . 
 Or , better yet , we do n't define any scheme , and just use https for the CONNECT - UDP requests ! 
 requires that CONNECT requests omit the pseudo - header : Why does this draft need to define a URI scheme and then include that in ? There are already two different definitions for URI scheme . Both seem - at least on face value - fairly sensible , but they both come with considerable baggage . The question I 'd like to ask is whether this protocol even needs a URI scheme at all . My first inclination is very much that it does not . 
 I the scheme because I thought it was required ( and ) , but maybe it is n't . Unfortunately , CONNECT - UDP is distinct from CONNECT , so it can not benefit from the exception that CONNECT has . This is pretty explicit in : This means that , unlike CONNECT , CONNECT - UDP needs a URI reference . However , according to : So , if we go the route of I think we can legally say that CONNECT - UDP request targets are of the form and require the and pseudo - headers to not be sent . This would allow us to use URIs without schemes for CONNECT - UDP . Can someone who 's more of an HTTP guru comment on this please ? 
 It 's an intriguing approach , but I 'm not sure it works . SEMANTICS 4.1 says : I do n't see anywhere in SEMANTICS it specifies that a method 's target URI ca n't be relative . However , for HTTP/1.1 at least : does not permit the use of relative URIs . Since support for this method is negotiated in SETTINGS for HTTP/2 and HTTP/3 , it 's possible for it to depart from the general requirements for which pseudo - headers to send and specify something that looks more like CONNECT ( omit and , for example ) . However , I 'm not convinced that can be generalized . and thoughts ? 
 support for CONNECT - UDP is not gated by a SETTINGS parameter . Only the datagram mode in h3 has a setting . 
 Ah , then it would need to include and pseudo - headers ; I 'm not sure off - hand if it 's valid for those to be empty . 
 I think that I would prefer a setting . It 's probably true that this does n't require special handling , but there are intermediaries that do crazy things like buffer request bodies . A setting would avoid any potential for misunderstanding . It makes this unusable in HTTP/1.1 , but I might see that as more of a feature than a bug . 
 I would strongly prefer to avoid a setting , as it breaks the use - case . 
 I tend to think that defining a URI scheme ( perhaps not ) is the path of least resistance here , and I do n't see any immediate harm in doing so . As a thought experiment , consider how the Web would work if CONNECT had a URI scheme ; that would give a distinct way to convey proxy configuration , for example . Based on the above I also think we need to clarify in Semantics that a target - uri is always absolute , even if it is transmitted as a relative uri . 
 For your obfuscation goals , the client needs to initiate any feature detection and do so after or in parallel with authentication . So you 're right , probably that precludes a setting unless you 're using client certs to authenticate ( which would itself be visible on a probe , though not clear evidence of Masque ) . Then I agree with that your path of least resistance is to mint a scheme for a UDP connection . The fact that has been used to describe other services available over UDP is regrettable , since those services actually intended to convey certain protocol endpoints . In this instance , you are literally describing a UDP connection with no protocol - specific properties ; I 'd consider asking if he 'd be willing to have the provisional registration ( which ) replaced by a permanent one that simply designates as describing a UDP endpoint without conveying application - layer protocol expectations . 
 Thinking about this some more , could we use the " https " scheme ? I really like to use a URI for proxy configuration , as that could allow future extensibility . and the " https " scheme there already maps TCP to the CONNECT method . I think it would make sense to have that also map UDP to CONNECT - UDP . And with that mindset , having the scheme sent over the wire as "  " seems natural , and bypasses the need to define a new URI scheme . Thoughts ? 
 Can you explain a bit more please  ? I 'm vaguely familiar with  's URI format of proxy configuration . I note that the link you provide also defines THR " quic " scheme . And I presume that it would be nice to ditch that some something more consistent . IIRC it is possible for a proxy identified by " http " or "  " schemes to offer H3 as an Alt - Svc . And then it 's upon the client to decide how to tunnel requests through such a proxy that might be capable of talking CONNECT and CONNECT - UDP . If this is too far off tangent ( because of discovery ) , we do n't need to explore it here . 
 I totally agree with you ,  's " quic " scheme is historical and I think it should now be deprecated in favor of "  " ( and rely on    to use h3 ) . But yes this is somewhat of a tangent that we may want to discuss offline . I was simply trying to make the case that there was some sort of precedent to consider proxying using CONNECT as "  " . Back to the scheme discussion , since the scheme carries no useful information on CONNECT - UDP requests , I 'm proposing to simply use "  " . 
 That all works for me . It does n't adhere to any sort of architectural purity , but CONNECT has no hope of achieving that ; hoping to include some notion of purity along other design constraints would only make things worse . I like the idea that you can just use "  " and work out the rest using the protocol negotiation tools we have (    , HTTPS , settings ) . 
 I think some discussion in this thread , but likely not fully what the intended semantics of the URI scheme should be . I think there are two basic ones that I can think of and the first one is : A ) Use a MASQUE proxy to send packets to " target address " However , I would think that outside of the MASQUE protocol a more useful URI semantics would be : B ) Use this MASQUE proxy to send traffic to this target address . I also think we have to take a step back and ask ourselves if MASQUE URI scheme implies UDP or it it should use parameters to encode which protocol that should be proxied over the MASQUE proxy ? The other aspect in this country I think the A ) semantics in the -03 connect - udp draft is that is it does n't discuss the identity of the proxy . For the security aspect the MASQUE client need to know the identity of the proxy so that it can verify the initial H/3 connection to the MASQUE proxy . 
 Can we simply recommend using as the scheme , but allow clients to specify a different scheme if appropriate ? 
 After discussion at the meeting , my understanding is that the target resource CONNECT - UDP might be an origin that speaks CONNECT - UDP , or it might be a ' raw ' UDP endpoint . In the former case , a HTTPS schemed target URI makes sense ; in the latter , something new is necessary ( e.g. , , if we can make that interoperable ) . 
 given that the authority component of an URI would not need to be aware of CONNECT - UDP , I am not sure that this reasoning for works for me . IOW , it implies that a new scheme is good . I think that is doubly burned already , unfortunately . 
 if we required a new scheme for every new method introduced , we 'd have some problems . Why is that necessary ? 
 I was n't arguing for anything in particular , just looking for you ( or someone ) to address the problem somehow . 
 Given that we do n't care about the scheme for now , and want to make sure people ignore it on receipt , how about we do https:// by default , but say that clients SHOULD grease the scheme ? 
 FWIW , I tend to think that we should omit scheme , path , and use SETTINGS for HTTP/2 and HTTP/3 . As points out , we have to make sure that servers unaware of CONNECT - UDP do not mishandle CONNECT - UDP requests . For HTTP/2 and /3 , we can go with either using sending SETTINGS or send set to something else than or as well as sending a fake . But in HTTP/1 , there 's no way of sending a scheme , therefore , we 'd have to use a connect - style request line ( i.e. ` CONNECT - UDP host : port HTTP/1.1 ) . Otherwise , servers unaware of the method would handle it as an ordinary request . The latter point means that there 's practical advantage in following the style of CONNECT method . Then , why not use a SETTINGS on H2 and H3 to minimize the difference between H1 and H2 / H3 ? 
 It 's actually legal to send a fully - qualified URI in HTTP/1.1 ; that 's just not the common case when you 're talking to an origin server . I do n't think it 's a problem to be considering a full URI for CONNECT - UDP in HTTP/1.1 . Of course , if we know there 's a lack of support for that form , that 's a different issue . 
 That 's a good point . Regarding the concern that you point out , I 'm not sure if that would actually be an issue because a request in absolute - URI form will be considered malformed and rejected by a server that only supports HTTP/1.0 - style requests . However , there 's the other failure mode , and that is servers ignoring the scheme . IIUC , most origin servers do not have the incentive to consult and reject requests based on the scheme . When I send to some host , I do see 200 responses , from servers hosted by large IaaS operators / multiple CDNs < supnote 1</sup . When sending to those servers , I do see 4xx errors . Therefore , if we are to care about how existing HTTP/1.1 servers would respond to masque , I think that using the form of is going to provide us better results . note 1 : I 'd take part of the blame , because h2o simply drops the scheme when receiving an HTTP/1.1 request . I 'm glad that we are not alone ! 
 The more I 'm thinking about this , the more I 'm leaning towards the simplest solution : no SETTING , and simply use a scheme of . That works perfectly for everything we need , and carries the least complexity . 
 I 'm not sure if we 'd be fine with the failure mode associated to that approach ? HTTP servers ( or applications ) often buffer the entire request , before they start processing it . Even the method is being checked after all the request body is being received . When a client connects to such a server , sending a CONNECT - UDP request with an   , the server will hang forever , as the client never closes the request stream . Eventually , a timeout would kick in , but I do not think it 's preferable to keep the client waiting until a timeout ? Am I missing something , or is it the case that you are fine with relying on a timeout ? 
 thanks for clarifying - that 's a good argument for a SETTING ( at least in the server - to - client direction ) . However , I really dislike the idea that every new HTTP method needs its own SETTING ... But apart from switching to extended CONNECT I 'm not seeing a lot of alternate solutions . 
 None of this makes any sense . If you ca n't send a valid request , then this protocol does not belong anywhere near an HTTP stream . Figure out how to send a valid request or build your own protocol . 
 how do you define a valid request ? The issue here is that a CONNECT ( or CONNECT - UDP ) request is valid as far as our understanding of the HTTP specs , but that does n't mean that servers handle them correctly - the important difference is that these requests are not followed by a FIN on the stream , and some servers do n't handle that well , even if it 's valid . 
 I have never met a server that did n't handle an HTTP request " well " , for its own definition of well . A server that does n't know the method will use the standard parsing algorithm and respond at the end of the header section with a 405 or 501 , depending on taste . If you want that to be faster , send fewer header fields . This is not a concern in practice . There is no option to send host : port with CONNECT - UDP . That is not HTTP . Stop bringing it up . Obviously , sending a GET request to a server is not the same as sending CONNECT - UDP to a server . The two have entirely different backwards - compatibility algorithms . Likewise , sending an absolute URI within a CONNECT - UDP request works just fine for every server chain that might be expected to support such a request , and the response is going to be 501 , 405 , or 400 for those that do n't . If you find a deployed server that evidences any other form of behavior , send the developers a bug report . The IETF is not the place to work around every possible fool 's implementation of bad parsing . By the time you finish writing the spec , there will be at least three more ways to fail to implement that spec correctly . Focus instead on making it work for servers that implement HTTP correctly . 
 No HTTP requests are followed by a FIN on the stream . FIN is part of TCP . Clients do not half - close their sockets in HTTP/1.1 -- the end of a request is indicated by either the end of the header section or by the end of the request Content - Length 's amount of data , and the server does n't read past that until it looks for the next request ( on a persistent connection ) . A server sends FIN after closing their end of the TCP connection . For HTTP/2 and HTTP/3 , both requests and response occur within protocol frames . A FIN only occurs when the underlying connection breaks . 
 my comment about the FIN was specific to HTTP/2 + . With those versions , the client sends a FIN on the request stream when it is done sending the body ( or the headers when there is no body ) for non - CONNECT requests . Some servers have unfortunately come to expect that of all request types , leading to timeouts for CONNECT . 
 I get your argument that sending CONNECT - style host : port is an act of breaking HTTP . Though , I would argue that if we are to stay within HTTP , we have to use a hop - by - hop opt - in mechanism for CONNECT - UDP , because it breaks existing assumption within HTTP that servers can wait for a complete request before processing it . To that end , I tend to believe that we have to do the following : For HTTP/2 and /3 , use SETTINGS , like we did in RFC 8441 . If we need support for HTTP/1.1 , use upgrade , like we did in RFC 6455 , RFC 7540 . We do not have to add a new SETTING parameter for every new type of tunnel . Assuming that we are fine with using SETTINGS , I tend to wonder if we could reuse RFC 8441 . With that opt - in UDP tunnels can be created by using a CONNECT request ( rather than a new method ) , with a scheme used for identifying that the payload is UDP datagrams ? 
 There is no such assumption in HTTP . The request is complete when the header section is complete . 
 IOW , if a server does n't start processing a request message as soon as the header section is complete , it can not correctly implement Expect and it probably does n't support request content delimited by Transfer - Encoding or Content - Length . HTTP is designed for infinite length content streams , so there are no cases where we assume a recipient will wait until the end of the message body before starting to process the request . There would be no distinction between that and a denial - of - service vulnerability . 
 Sorry my phrasing was incorrect . What I meant to say was that HTTP does not assume servers to start sending a final response before receiving end of the stream . EDIT . After initially posting this comment , I realized that for HTTP/1.1 , lack of CL or TE indicates that the end of request headers is the end of the request . But for HTTP/2 and HTTP/3 , the method being CONNECT is the only indicator that changes where the request ends , is n't it ? 
 FWIW , if all you need is something that is a valid URI ( and the content does not matter ) , a URN might work perfectly well : urn : ietf : rfc : xxxx ( see ) . ( I think   mentioned this in the IETF meeting chat ) 
 mentioned elsewhere that a locator that identifies the server providing the connect tunnel would be much better than the current design , which effectively puts the target host as an authority . I 'm not yet sure what I think of that , but it 's an interesting thought worth considering . 
 Here is the example from : 
 That specific example makes my RFC 8820 sense itch , but it 's an OK illustration of the idea . 
 do you have an alternate encoding that would appease your itch ? 
 With the  scheme , we might be able to use a URI template ( which might lead to that exact example if people so chose ) . Or we could define a new scheme ... 
 pointed out that draft - pauly - dprive - oblivious - doh does something similar . It may make sense to have some consistency . Maybe : ( perhaps adjusting the path somehow , or using a URI template ? ) 
 I like the idea of keeping the https scheme and using the path to convey the target 
 No need to abuse .well - known when we can use a URI template . 
 in something using curly brackets ... ? 
 So something like ? 
 That would be an easy way of doing it . Or . 
 But that would be an invalid path . 
 Would it be invalid after RFC 6570 substitution ? 
 After substitution is of course ok . So where do you want to put the template ? 
 The template goes the same place you might put a URL . Right now , that is configuration . 
 Ah , I thought you wanted to put it into the " : path " pseudo header . 
 Closely related to this is whether : 1 ) Use a method per protocol ( CONNECT - UDP , CONNECT - IP , etc ) 2 ) Use a new common method ( eg ,  ) with protocol in either a pseudoheader or path component 3 ) Use Extended CONNECT with a " : protocol " psuedoheader Given all of the baggage with CONNECT , I 'd lean towards ( 2 ) 
 ( This issue probably wants a more general name covering the set of interrelated topics here . ) 
 As said at the meeting , to avoid intermediaries unaware of masque waiting for FIN before doing anything , I think it would be a good idea to make this an opt - in . For that , we need to use an ALPN , SETTING , or something that it being exchanged prior to the HTTP requests . The problem with option 1 is that we 'd need to introduce a new negotiation scheme for every protocol . Option 2 is better in that respect because we need to introduce one negotiation scheme , and reuse it for different protocols . But I 'm not sure if hawing a new negotiation scheme is necessary , when option ( 3 ) , i.e. , the Extended CONNECT method , already provides us the necessary negotiation scheme with the " : protocol " psuedo header acting as a way of specifying the protocol . 
 Extended CONNECT does have the advantage of targeting a resource . The challenge then is in how the target ( for UDP , that would be a hostname or IP plus a port ) is encoded into that target URI . We have URI templates that have been successfully used elsewhere , so that might work . Webtransport can just use an arbitrary target URI . The main complaint I have is that : protocol is terrible . HTTP Upgrade Tokens are n't ALPN , but that 's almost what we want here : a unified protocol identification system . Of course , as a tunneled protocol , ALPN is n't right either , so maybe we can just reclaim upgrade tokens for this tunneling stuff . 
 Yeah , I share the temptation to use ALPN . Though , talking specifically about masque , I 'm not sure if it 's an application protocol . Rather , it is a combination of an encapsulated datagram protocol and a way of specifying the remote address . Let 's say we want to use SRTP on top of a HTTP tunnel with support for datagrams . In such case ,  would be the ALPN , and we 'd need another identifier for specifying that the transport carries datagrams , rather than a bidirectional stream . Based on that , I am inclined to say that " : protocol " might be a better fit for masque , and separately , we could discuss adding a non - pseudo header field for specifying ALPN . PS . And the other benefit of using Upgrade Tokens is that we can support HTTP/1.1 as well ( though I 'm not entirely sure if we want to officially support HTTP/1.1 ) . 
 I keep forgetting that I wrote RFC 7639 . Still , I agree on all counts . ALPN has a purpose , but it is n't quite right here . Update tokens are a little weird , but I think that they are actually perfect . We just need to reclaim them for use . 
 One thing I do find appealing about using   is that it means that HTTP/1.1 support becomes easy : we just use Upgrade and keep the target in the path like in h2 and h3 . And conceptually an upgrade is what we 're doing : we 're replacing the DATA stream with a new protocol that uses capsules / stream chunks . That 's not too dissimilar to WebSocket .
This document describes the CONNECT-UDP HTTP method.  CONNECT-UDP is
similar to the HTTP CONNECT method, but it uses UDP instead of TCP.
This document describes the CONNECT-UDP HTTP method.  CONNECT-UDP is
similar to the HTTP CONNECT method (see section 4.3.6 of RFC7231),
but it uses UDP UDP instead of TCP TCP.
This document describes how to proxy UDP over HTTP.  Similar to how
the CONNECT method allows proxying TCP over HTTP, this document
defines a new mechanism to proxy UDP.  It is built using HTTP
Extended CONNECT.
This document describes how to proxy UDP over HTTP.  Similar to how
the CONNECT method (see Section 9.3.6 of SEMANTICS) allows proxying
TCP TCP over HTTP, this document defines a new mechanism to proxy UDP
UDP.
UDP Proxying supports all versions of HTTP and uses HTTP Datagrams
HTTP-DGRAM.  When using HTTP/2 or HTTP/3, UDP proxying uses HTTP
Extended CONNECT as described in EXT-CONNECT2 and EXT-CONNECT3.  When
using HTTP/1.x, UDP proxying uses HTTP Upgrade as defined in
Section 7.8 of SEMANTICS.
In this document, we use the term "proxy" to refer to the HTTP server
that opens the UDP socket and responds to the CONNECT-UDP request.
If there are HTTP intermediaries (as defined in Section 2.3 of
RFC7230) between the client and the proxy, those are referred to as
"intermediaries" in this document.
The CONNECT-UDP method is defined for all versions of HTTP.  UDP
payloads are sent using HTTP Datagrams HTTP-DGRAM.  Note that, when
the HTTP version in use does not support multiplexing streams (such
as HTTP/1.1), then any reference to "stream" in this document is
meant to represent the entire connection.
The CONNECT-UDP method requests that the recipient establish a tunnel
over a single HTTP stream to the destination origin server identified
by the request-target and, if successful, thereafter restrict its
behavior to blind forwarding of packets, in both directions, until
the tunnel is closed.  Tunnels are commonly used to create an end-to-
end virtual connection, which can then be secured using QUIC QUIC or
another protocol running over UDP.
The ":method" pseudo-header field is set to "CONNECT-UDP".
The ":scheme" pseudo-header field is set to "masque".
The ":path" pseudo-header field is set to "/".
The ":authority" pseudo-header field contains the host and port to
connect to (similar to the authority-form of the request-target of
CONNECT requests; see RFC7230, Section 5.3).
A CONNECT-UDP request that does not conform to these restrictions is
malformed (see H2, Section 8.1.2.6).
The recipient proxy establishes a tunnel by directly opening a UDP
socket to the request-target.  Any 2xx (Successful) response
indicates that the proxy has opened a socket to the request-target
and is willing to proxy UDP payloads.  Any response other than a
successful response indicates that the tunnel has not yet been
formed.
A proxy MUST NOT send any Transfer-Encoding or Content-Length header
fields in a 2xx (Successful) response to CONNECT-UDP.  A client MUST
treat a response to CONNECT-UDP containing any Content-Length or
Transfer-Encoding header fields as malformed.
A payload within a CONNECT-UDP request message has no defined
semantics; a CONNECT-UDP request with a non-empty payload is
malformed.
Responses to the CONNECT-UDP method are not cacheable.
UDP packets are encoded using HTTP Datagrams HTTP-DGRAM.  The payload
of a UDP packet (referred to as "data octets" in UDP) is sent
unmodified in the "HTTP Datagram Payload" field of an HTTP Datagram.
In order to use HTTP Datagrams, the CONNECT-UDP client will first
decide whether or not to use HTTP Datagram Contexts and then register
its context ID (or lack thereof) using the corresponding registration
capsule, see HTTP-DGRAM.
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
they have established support on a given connection.
The proxy that is creating the UDP socket to the destination responds
to the CONNECT-UDP request with a 2xx (Successful) response.
Clients MAY optimistically start sending proxied UDP packets before
receiving the response to its CONNECT-UDP request, noting however
that those may not be processed by the proxy if it responds to the
CONNECT-UDP request with a failure, or if the datagrams arrive before
the CONNECT-UDP request.
Extensions to CONNECT-UDP MAY leverage the "Context Extensions" field
of registration capsules in order to negotiate different semantics or
encoding for UDP payloads.
Unlike TCP, UDP is connection-less.  The proxy that opens the UDP
socket has no way of knowing whether the destination is reachable.
Therefore it needs to respond to the CONNECT-UDP request without
waiting for a TCP SYN-ACK.
Proxies can use connected UDP sockets if their operating system
supports them, as that allows the proxy to rely on the kernel to only
send it UDP packets that match the correct 5-tuple.  If the proxy
uses a non-connected socket, it MUST validate the IP source address
and UDP source port on received packets to ensure they match the
client's CONNECT-UDP request.  Packets that do not match MUST be
discarded by the proxy.
The lifetime of the socket is tied to the CONNECT-UDP stream.  The
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.
If a proxy is notified by its operating system that its socket is no
longer usable, it MUST close the CONNECT-UDP stream.
In this document, we use the term "proxy" to refer to the HTTP server
that opens the UDP socket and responds to the UDP proxying request.
If there are HTTP intermediaries (as defined in Section 3.7 of
SEMANTICS) between the client and the proxy, those are referred to as
"intermediaries" in this document.
Note that, when the HTTP version in use does not support multiplexing
streams (such as HTTP/1.1), any reference to "stream" in this
document represents the entire connection.
Since the original HTTP CONNECT method allowed conveying the target
host and port but not the scheme, proxy authority, path, nor query,
there exist proxy configuration interfaces that only allow the user
to configure the proxy host and the proxy port.  Client
implementations of this specification that are constrained by such
limitations MUST use the default template which is defined as:
"https://{proxy_host}:{proxy_port}/{target_host}/{target_port}/"
where "proxy_host" and "proxy_port" are the configured host and port
of the proxy respectively.  Proxy deployments SHOULD use the default
template to facilitate interoperability with such clients.
This document defines the "masque-udp" HTTP Upgrade Token. "masque-
udp" uses the Capsule Protocol as defined in HTTP-DGRAM.
A "masque-udp" request requests that the recipient establish a tunnel
over a single HTTP stream to the destination target server identified
by the "target_host" and "target_port" variables of the URI template
(see client-config).  If the request is successful, the proxy commits
to converting received HTTP Datagrams into UDP packets and vice versa
until the tunnel is closed.  Tunnels are commonly used to create an
end-to-end virtual connection, which can then be secured using QUIC
QUIC or another protocol running over UDP.
When sending its UDP proxying request, the client SHALL perform URI
template expansion to determine the path and query of its request.
target_host supports using DNS names, IPv6 literals and IPv4
literals.  Note that this URI template expansion requires using pct-
encoding, so for example if the target_host is "2001:db8::42", it
will be encoded in the URI as "2001%3Adb8%3A%3A42".
A payload within a UDP proxying request message has no defined
semantics; a UDP proxying request with a non-empty payload is
malformed.
Responses to UDP proxying requests are not cacheable.
Upon receiving a UDP proxying request, the recipient proxy extracts
the "target_host" and "target_port" variables from the URI it has
reconstructed from the request headers, and establishes a tunnel by
directly opening a UDP socket to the requested target.
Unlike TCP, UDP is connection-less.  The proxy that opens the UDP
socket has no way of knowing whether the destination is reachable.
Therefore it needs to respond to the request without waiting for a
packet from the target.  However, if the target_host is a DNS name,
the proxy MUST perform DNS resolution before replying to the HTTP
request.  If DNS resolution fails, the proxy MUST fail the request
and SHOULD send details using the Proxy-Status header PROXY-STATUS.
Proxies can use connected UDP sockets if their operating system
supports them, as that allows the proxy to rely on the kernel to only
send it UDP packets that match the correct 5-tuple.  If the proxy
uses a non-connected socket, it MUST validate the IP source address
and UDP source port on received packets to ensure they match the
client's request.  Packets that do not match MUST be discarded by the
proxy.
The lifetime of the socket is tied to the request stream.  The proxy
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.
A successful response (as defined in resp1 and resp23) indicates that
the proxy has opened a socket to the requested target and is willing
to proxy UDP payloads.  Any response other than a successful response
indicates that the request has failed, and the client MUST therefore
abort the request.
the method SHALL be "CONNECT".
the request-target SHALL use absolute-form (see Section 3.2.2 of
MESSAGING).
the request SHALL include a single Host header containing the
origin of the proxy.
the request SHALL include a single "Connection" header with value
"Upgrade".
the request SHALL include a single "Upgrade" header with value
"masque-udp".
the HTTP status code on the response SHALL be 101 (Switching
Protocols).
the reponse SHALL include a single "Connection" header with value
"Upgrade".
the response SHALL include a single "Upgrade" header with value
"masque-udp".
the response SHALL NOT include any Transfer-Encoding or Content-
Length header fields.
The ":method" pseudo-header field SHALL be "CONNECT".
The ":protocol" pseudo-header field SHALL be "masque-udp".
The ":authority" pseudo-header field SHALL contain the authority
of the proxy.
The ":path" and ":scheme" pseudo-header fields SHALL NOT be empty.
Their values SHALL contain the scheme and path from the URI
template after the URI template expansion process has been
completed.
A UDP proxying request that does not conform to these restrictions is
malformed (see Section 8.1.2.6 of H2).
The proxy SHALL indicate a successful response by replying with any
2xx (Successful) HTTP status code, without any Transfer-Encoding or
Content-Length header fields.
UDP packets are encoded using HTTP Datagrams HTTP-DGRAM.  The payload
of a UDP packet (referred to as "data octets" in UDP) is sent
unmodified in the "HTTP Datagram Payload" field of an HTTP Datagram.
In order to use HTTP Datagrams, the client will first decide whether
or not to use HTTP Datagram Contexts and then register its context ID
(or lack thereof) using the corresponding registration capsule, see
HTTP-DGRAM.
Clients MAY optimistically start sending proxied UDP packets before
receiving the response to its UDP proxying request, noting however
that those may not be processed by the proxy if it responds to the
request with a failure, or if the datagrams are received by the proxy
before the request.
Extensions to this mechanism MAY leverage the "Context Extensions"
field of registration capsules in order to negotiate different
semantics or encoding for UDP payloads.
If a client or proxy with a connection containing a CONNECT-UDP
stream disables congestion control, it MUST NOT signal ECN support on
that connection.  That is, it MUST mark all IP headers with the Not-
ECT codepoint.  It MAY continue to report ECN feedback via ACK_ECN
frames, as the peer may not have disabled congestion control.
If a client or proxy with a connection containing a UDP proxying
request stream disables congestion control, it MUST NOT signal ECN
support on that connection.  That is, it MUST mark all IP headers
with the Not-ECT codepoint.  It MAY continue to report ECN feedback
via ACK_ECN frames, as the peer may not have disabled congestion
control.
CONNECT-UDP does not create an IP-in-IP tunnel, so the guidance in
RFC6040 about transferring ECN marks between inner and outer IP
headers does not apply.  There is no inner IP header in CONNECT-UDP
tunnels.
Note that CONNECT-UDP clients do not have the ability in this
specification to control the ECN codepoints on UDP packets the proxy
sends to the server, nor can proxies communicate the markings of each
UDP packet from server to proxy.
A CONNECT-UDP proxy MUST ignore ECN bits in the IP header of UDP
packets received from the server, and MUST set the ECN bits to Not-
ECT on UDP packets it sends to the server.  These do not relate to
the ECN markings of packets sent between client and proxy in any way.
There are significant risks in allowing arbitrary clients to
establish a tunnel to arbitrary servers, as that could allow bad
actors to send traffic and have it attributed to the proxy.  Proxies
that support CONNECT-UDP SHOULD restrict its use to authenticated
users.
Because the CONNECT method creates a TCP connection to the target,
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 CONNECT-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 document will request IANA to register "CONNECT-UDP" in the HTTP
Method Registry (IETF review) maintained at
<<https://www.iana.org/assignments/http-methods>>.
This document will request IANA to register the URI scheme "masque".
UDP proxying does not create an IP-in-IP tunnel, so the guidance in
RFC6040 about transferring ECN marks between inner and outer IP
headers does not apply.  There is no inner IP header in UDP proxying
tunnels.
Note that UDP proxying clients do not have the ability in this
specification to control the ECN codepoints on UDP packets the proxy
sends to the server, nor can proxies communicate the markings of each
UDP packet from server to proxy.
A UDP proxy MUST ignore ECN bits in the IP header of UDP packets
received from the server, and MUST set the ECN bits to Not-ECT on UDP
packets it sends to the server.  These do not relate to the ECN
markings of packets sent between client and proxy in any way.
There are significant risks in allowing arbitrary clients to
establish a tunnel to arbitrary servers, as that could allow bad
actors to send traffic and have it attributed to the proxy.  Proxies
that support UDP proxying SHOULD restrict its use to authenticated
users.
Because the CONNECT method creates a TCP connection to the target,
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 document will request IANA to register "masque-udp" in the HTTP
Upgrade Token Registry maintained at
<<https://www.iana.org/assignments/http-upgrade-tokens>>.
Proxying of UDP Payloads.
None.