its Argument.  The node referring to the entirety of this JSON value is also referred to as its root node. <del> A structure complying to the generic data model of JSON, i.e., composed of containers, namely JSON objects and arrays, and of atomic data, namely null, true, false, numbers, and text strings. Also called a JSON value.  In this document, often abbreviated to _item_. A Data Item, with an emphasis on the location of the item within the Argument.  I.e., an item identical to or contained within the JSON data item to which the query is applied.  A node can be viewed as a combination of a (1) JSON value and (2) its location in the argument; the latter can, if desired, be represented as an Output Path. </del>  A JSON object as defined in RFC8259.  Never used in its generic sense, e.g., for programming language objects. A JSON array as defined in RFC8259.  Never used in its generic sense, e.g., for programming language objects. <del> An item in an array.  (Also used with a distinct meaning in XML context for XML elements.) </del>  A non-negative integer that identifies a specific element in an array.  The term, in particular in the form indexing, is also Short name for JSONPath expression. <del> Short name for the JSON data item a JSONPath expression is applied to. </del>  Output of applying a query to an argument: a list of nodes within that argument.  While this list can be represented in JSON, e.g. as an array, the nodelist is an abstract concept unrelated to JSON <del> data items. </del>  A simple form of JSONPath expression that identifies a node by providing a query that results in exactly that node.  Similar to, In 2007, the need for something solving the same class of problems for the emerging JSON community became apparent, specifically for: <del> Finding data interactively and extracting them out of RFC8259 data items without special scripting. </del>  Specifying the relevant parts of the JSON data in a request by a client, so the server can reduce the amount of data in its or in popular programming languages such as JavaScript, Python and PHP, <del> with a variable x holding the JSON data item.  Here we observe that such languages already have a fundamentally XPath-like feature built in. </del>  The JSONPath tool in question should: 1.3. <del> JSONPath expressions always apply to a JSON data item in the same way as XPath expressions are used in combination with an XML document. Since a JSON data item is anonymous, JSONPath uses the abstract name "$" to refer to the top level data item of the argument. </del>  JSONPath expressions can use the _dot-notation_ JSONPath can use expressions, written in parentheses: "(<expr>)", as an alternative to explicit names or indices as in: <del> The symbol "@" is used for the current item.  Filter expressions are </del>  supported via the syntax "?(<boolean expr>)" as in Here is a complete overview and a side by side comparison of the 2. This section provides some more examples for JSONPath expressions. <del> The examples are based on a simple JSON data item patterned after a typical XML example representing a bookstore (that also has bicycles): </del>  The examples in tbl-example use the expression mechanism to obtain <del> the number of items in an array, to test for the presence of a member in a object, and to perform numeric comparisons of member values with a constant. </del>  3.

See discussion in . To do: What exactly doesn't $..* stand for -- the table currently says "member values" (i.e., no array elements). Is that true?
Clusters of terms: Cluster 1 JSON value (data) item node location These are related, but different. We probably do not need all four. (Of course, JSON value is a 8259 term, so it does not go away.) We should decide which of these terms we want to use, and what they exactly mean. A node seems to be a combination of a discrete JSON value and its location. JSON value seems to imply equivalence by value (even though equivalence is undefined in RFC 8259), while node is based on equivalence by identity. Location seems to imply that you can get to the node (and thus the value) from it. Cluster 2 Argument: input to executing JSON query root value, root node (used as Argument, may be used in nested queries) current node (current item): input to selector function invocation, maybe used inside filtering/indexing selectors Cluster 3 selector (part of the selector chain that makes up a JSONPath query) (we probably need a word for) selector function [invocation] This is needed if we stick to the model that each node in the input node list is treated separately and the results are then combined using (TBD) combine1. combine1 (placeholder for what combines the outputs of the selector function invocations) This becomes important when we either resolve there is only one combine1 function or we resolve that combine1 functions are (within limits) implemenation specific (i.e., we give up) or that different selectors have different combine1 functions. All these can only be meaningfully decided once we have agreement on a processing model.
... (we probably need a word for) selector function [invocation] ... perhaps ... selection selection process selection step (atomic)
We are using way more generic terms: value, object etc. (I’d rather get rid of those first.) The Argument is the JSON value that goes into the evaluation of the query. The Argument is then viewed as a tree and has a root node. Grüße, Carsten
... using some examples ... ... is the name of a member value of object . ... is the index of an entry value of array . location is a general/abstract term for name and index. So and are both locations. is name and location of the root value. A (normalized) path is a sequence of locations enclosed in brackets. A is a pair. A in its simpliest case is a location. Special selectors are . I think with this we have a minimalistic and complete term set.
Unless I've missed a strict definition in our discussions, there can be more than one normalised path for a given location. For instance, to identify the child node of the root node with name , and assuming we are using the more general "bracket" form of child name (the production in the current grammar), we could use an array consisting of any one of the following name components: "a" 'a' "u0061" 'u0061' To accommodate this, we could associate a location with an of normalised paths. Alternatively, we could define a unique normalised path for each location (e.g. for names by stipulating double quotes and unicode escapes for every character, even if that would be unfriendly to end users and, for indices, by stipulating non-negative indices). I guess we could even standardise on basic Latin unicode characters and use unicode escapes for everything else, but that seems a little biased.
That is not exactly a terminology issue. If we want the output paths to be normalized, we would need to define that normalization. If we just want them to be stylized (e.g., bracket notation only, unsigned integer indexing or quoted name indexing) and leave representation details to the implementations, we could do that, too. (My personal view is that they should be normalized. Single quotes are very un-JSON, and escaping non-control characters is un-2000s, so it is pretty clear that "a" would be the normalized form.)
I think that works best the other way around: a location is an abstraction that can be represented by a path (full path, path from the root, ...). We don't really need locations for member names, so I would limit this to nodes. If we have normalization of paths, a normalized path can indeed be derived from the path (from the root) of the location. (But I don't know yet whether we opt for normalization of output paths.)
charming aspect of single quotes in normalized pathes would be to use them as JSON values itself without escaping ... We should care for: There can be only one normalized path per JSON value ! If is defined as the complete path, we need another universal term for . hmm ... why not simply use instead of from root to value and redefine as local location relative to parent value ... ?
I really, really like Stefan's approach here. I it is precise and easy to understand and does the minimum amount of invention required.
a "canonical form" of anything, I think we could get away with it here. Any JSON string can be represented as a sequence of Unicode codepoints - granted, some of them might not be valid codepoints - and for the purpose of a normalized path, we could either (a) specify UTF-8 or (b) say that the codepoints are all that matters, the syntactic expression is not significant. Or am I missing something?
I don't feel strongly. I think we could define an abstract "path" term, but I wonder if it might sound a bit odd in places in context of JSONpath? I'm not sure we need a term for that. We already have names in objects and indices in arrays.
It would help the concision to have a single common term for indexing by name and indexing by index. I don't have a proposal, though... ("location" probably is not it, that term is better used the way it is now. A location in that sense can be expressed by an output path, but it "is" not an output path.)
This has been brought up before. To me, is the only sensible term that covers both objects and arrays. I know there's other discussion regarding this term, but I'm on mobile and can't find it right now.
"child" gives me the XPath heebie-jeebies... But that is a reasonable working term for array element or member value (i.e., data items that result from indexing a container). What's missing is a term for the parameter that goes into the indexing (array index or member name). Maybe we need to rename array index so we can use index for the combined term (which also would solve the fact that indexing otherwise isn't always related to indexes).
This works for me. I tend to think of a thing inside as an index, whether it's a number or a string (because the in .Net is called the "index" operator). It also helps define a union as "a set of indices" where a single "index" could be a number, a string, a slice, etc. Unions can then be any combination of these things. (We should also decide on "indices" vs "indexes". I'm not sure which is more correct. seems to indicate there's not a "correct," but we should decide on one or the other.)
Search engine of my choice offers "tag, label, mark" as kind of synonyms for "name / index". So how do we like to talk about (including Carsten's proposal): tag/value pair label/value pair mark/value pair index/value pair "tag" may be too HTML'ish ... ?
Given those options, I think I'll stick with my vote for "index".
Don't forget "key" ... key/value pair
I think we can stick with 8259 for member name. Key is maybe indeed a candidate for "member name or array index". I'll propose a PR as soon as is through (too many conflicts otherwise).
Following on from the previous comments, I propose to add two additional terms to the terminology list: Key: Synonym for array index or object member name. Selector: An atomic component of a query expression. Different selector types are ... Root selector Current item selector Nested descendants selector . Dot selector , used with object member names exclusively. Dot wild card selector . Key selector , where is either an (possibly negative) array index or an object member name. Key wild card selector . Array slice selector , where , , are integer literals. Union selector , holding a comma delimited list of keys. Filter selector I hope I did not miss a selector type. Also, I dislike the current fact, that union selectors are first class citizens in the spec. They should be equal among equal. Let's discuss ...
How about maybe index/key? index key? indexing key? Grüße, Carsten
We will use that mostly in the form "key/value pair", where "index/key/value pair" is confusing. "index/value pair" would be better then, but "index" alone is often mentally completed to "array index".
... if agreement goes to "index/value pair", I can live with it ...
~I still think "index" denotes an array specifically.~ Thinking over this again, yeah, index/value. For reasons I've mention above. (Sorry, typing without thinking)
ok ... then ... Index: Synonym for array index or object member name. Selector: An atomic component of a query expression. Different selector types are ... Root selector Current item selector Nested descendants selector . Dot selector , used with object member names exclusively. Dot wild card selector . Index selector , where is either an (possibly negative) array index or an object member name. Index wild card selector . Array slice selector , where , , are integer literals. Union selector , holding a comma delimited list of indices (indexes ?). Filter selector
"Indices" is more correct, but "indexes" has become more common recently. Also, I still think we should include the selector. I've already explained its uses in other issues, but we should keep it for no other reason than people will complain if it's not supported.
Well ... I would like to get filter selector syntax straight first. Then discuss, if and what subset of it we want to support with index selectors.
I would expect that the expression syntax would be the same. The resulting value would need to, instead of being truthy, be able to evaluate to a well-defined index, e.g. a number or string.
I think we should summarize all the above kinds of selector into "indexing selectors". (Note that the wild card selector is not there, as there is no indexing key.)
The current draft says: Thus a an indexing expression can include multiple slice expressions:
We may want to adjust that after agreeing on a term
(but "resolves" doesn't trigger closing the issue, so I'm doing this by hand here).
LGTM, thanks.

its Argument.  The node referring to the entirety of this JSON value is also referred to as its root node.  <ins> As per RFC8259, a structure complying to the generic data model of JSON, i.e., composed of components such as containers, namely JSON objects and arrays, and atomic data, namely null, true, false, numbers, and text strings. A JSON value, with an emphasis on its location within the Argument.  I.e., a JSON value that is identical to or contained within the JSON value to which the query is applied.  A node can be viewed as a combination of a (1) JSON value and (2) its location in the Argument; the latter can, if desired, be represented as an Output Path. </ins> A JSON object as defined in RFC8259.  Never used in its generic sense, e.g., for programming language objects. A JSON array as defined in RFC8259.  Never used in its generic sense, e.g., for programming language objects.  <ins> A JSON value in an array.  (Also used with a distinct meaning in XML context for XML elements.) </ins> A non-negative integer that identifies a specific element in an array.  The term, in particular in the form indexing, is also Short name for JSONPath expression.  <ins> Short name for the JSON value a JSONPath expression is applied to. </ins> Output of applying a query to an argument: a list of nodes within that argument.  While this list can be represented in JSON, e.g. as an array, the nodelist is an abstract concept unrelated to JSON  <ins> values. </ins> A simple form of JSONPath expression that identifies a node by providing a query that results in exactly that node.  Similar to, In 2007, the need for something solving the same class of problems for the emerging JSON community became apparent, specifically for:  <ins> Finding data interactively and extracting them out of RFC8259 JSON values without special scripting. </ins> Specifying the relevant parts of the JSON data in a request by a client, so the server can reduce the amount of data in its or in popular programming languages such as JavaScript, Python and PHP,  <ins> with a variable x holding the JSON value.  Here we observe that such languages already have a fundamentally XPath-like feature built in. </ins> The JSONPath tool in question should: 1.3.  <ins> JSONPath expressions always apply to a JSON value in the same way as XPath expressions are used in combination with an XML document. Since a JSON value is anonymous, JSONPath uses the abstract name "$" to refer to the entire JSON value ("root node") of the argument. </ins> JSONPath expressions can use the _dot-notation_ JSONPath can use expressions, written in parentheses: "(<expr>)", as an alternative to explicit names or indices as in:  <ins> The symbol "@" is used for the current node.  Filter expressions are </ins> supported via the syntax "?(<boolean expr>)" as in Here is a complete overview and a side by side comparison of the 2. This section provides some more examples for JSONPath expressions.  <ins> The examples are based on the simple JSON value shown in fig-example- value, which was patterned after a typical XML example representing a bookstore (that also has bicycles). </ins> The examples in tbl-example use the expression mechanism to obtain  <ins> the number of elements in an array, to test for the presence of a member in a object, and to perform numeric comparisons of member values with a constant. </ins> 3.


The Extended CONNECT protocol defined for this mechanism is "connect- ip", which is also referred to as CONNECT-IP in this document. <del> The CONNECT-IP protocol allows endpoints to set up a path for </del>  proxying IP packets using an HTTP proxy.  This can be used for various solutions that include general-purpose packet tunnelling, such as for a point-to-point or point-to-network VPN, or for limited IP packets in HTTP Datagrams (packet-handling). Any 2xx (Successful) response indicates that the proxy is willing to <del> open an IP forwarding path between it and the client.  Any response </del>  other than a successful response indicates that the tunnel has not been formed. request.  A client MUST treat a successful response containing any Content-Length or Transfer-Encoding header fields as malformed. <del> The lifetime of the forwarding path is tied to the CONNECT stream. </del>  Closing the stream (in HTTP/3 via the FIN bit on a QUIC STREAM frame, <del> or a QUIC RESET_STREAM frame) closes the associated forwarding path. </del>  Along with a successful response, the proxy can send capsules to assign addresses and routes to the client (capsules).  The client can In the other direction, when a CONNECT-IP endpoint receives an IP packet, it checks to see if the packet matches the routes mapped for <del> a CONNECT-IP forwarding path, and performs the same forwarding checks as above before transmitting the packet over HTTP Datagrams. </del>  Note that CONNECT-IP endpoints will decrement the IP Hop Count (or TTL) upon encapsulation but not decapsulation.  In other words, the server through the proxy. The following example shows an IP flow forwarding setup, where a <del> client requests to establish a forwarding path to target.example.com using ICMP (IP protocol 1), and receives a single local address and remote address it can use for transmitting packets. </del>  The following example shows a proxied UDP listen flow, where a client receives can receive UDP packets via the proxy, and can send to any

The draft currently mentions an "IP forwarding path" (or elsewhere a "path for proxying IP packets") without defining what that term means. It's ambiguous because "path" is a . I'd propose we replace this use of the word "path" with the word "tunnel" which is .
Yes, "IP forwarding tunnel" sounds fine to me.
Yes tunnel is good. Or maybe association in the context of handling state st the proxy.

The Extended CONNECT protocol defined for this mechanism is "connect- ip", which is also referred to as CONNECT-IP in this document.  <ins> The CONNECT-IP protocol allows endpoints to set up a tunnel for </ins> proxying IP packets using an HTTP proxy.  This can be used for various solutions that include general-purpose packet tunnelling, such as for a point-to-point or point-to-network VPN, or for limited IP packets in HTTP Datagrams (packet-handling). Any 2xx (Successful) response indicates that the proxy is willing to  <ins> open an IP forwarding tunnel between it and the client.  Any response </ins> other than a successful response indicates that the tunnel has not been formed. request.  A client MUST treat a successful response containing any Content-Length or Transfer-Encoding header fields as malformed.  <ins> The lifetime of the forwarding tunnel is tied to the CONNECT stream. </ins> Closing the stream (in HTTP/3 via the FIN bit on a QUIC STREAM frame,  <ins> or a QUIC RESET_STREAM frame) closes the associated forwarding tunnel. </ins> Along with a successful response, the proxy can send capsules to assign addresses and routes to the client (capsules).  The client can In the other direction, when a CONNECT-IP endpoint receives an IP packet, it checks to see if the packet matches the routes mapped for  <ins> a CONNECT-IP forwarding tunnel, and performs the same forwarding checks as above before transmitting the packet over HTTP Datagrams. </ins> Note that CONNECT-IP endpoints will decrement the IP Hop Count (or TTL) upon encapsulation but not decapsulation.  In other words, the server through the proxy. The following example shows an IP flow forwarding setup, where a  <ins> client requests to establish a forwarding tunnel to target.example.com using ICMP (IP protocol 1), and receives a single local address and remote address it can use for transmitting packets. </ins> The following example shows a proxied UDP listen flow, where a client receives can receive UDP packets via the proxy, and can send to any


Range A precedes an IP address range B in the same ROUTE_ADVERTISEMENT capsule, they MUST follow these requirements: <del> IP Version of A MUST be lesser or equal than IP Version of B </del>  If the IP Version of A and B are equal, the IP Protocol of A MUST <del> be lesser or equal than IP Protocol of B. </del>  If the IP Version and IP Protocol of A and B are both equal, the End IP Address of A MUST be strictly less than the Start IP

Where the word "lesser" is used, I think "less than" would read better. Especially in the construct "lesser or equal than"
SGTM

Range A precedes an IP address range B in the same ROUTE_ADVERTISEMENT capsule, they MUST follow these requirements:  <ins> IP Version of A MUST be less than or equal than IP Version of B </ins> If the IP Version of A and B are equal, the IP Protocol of A MUST  <ins> be less than or equal than IP Protocol of B. </ins> If the IP Version and IP Protocol of A and B are both equal, the End IP Address of A MUST be strictly less than the Start IP


one or more IP addresses to its peer, and then respond with an ADDRESS_ASSIGN capsule to inform the peer of the assignment.  For each Requested Address, the receiver of the ADDRESS_REQUEST capsule <del> SHOULD respond with a Assigned Address with a matching Request ID. If the requested address was assigned, the IP Address and IP Prefix </del>  Length fields in the Assigned Address response SHALL be set to the assigned values.  If the requested address was not assigned, the IP Address SHALL be all-zero and the IP Prefix Length SHALL be the maximum length (0.0.0.0/32 or ::/128) to indicate that no address was <del> assigned.  Note that other Assigned Address entries that do not correspond to any Request ID can also be contained in the same ADDRESS_ASSIGN response. </del>  If an endpoint receives an ADDRESS_REQUEST capsule that contains zero Requested Addresses, it MUST abort the IP proxying request stream.

s/SHOULD/MUST/ regarding replying to add requests. Indicate that endpoints responding to ADDRESSREQUEST capsules SHOULD NOT send repeat non-assignments in future ADDRESSASSIGN capsules. Please wordsmith away.
IIUC the recipient of an ADDRESSREQUEST has to respond one way or another, using ADDRESSASSIGN. Via , it is possible to reject a request and send a "null response" back. Per ADDRESSASSIGN Technically, the address was never given, so sending a "null address" just once and then never sending it again is probably a good move - it limits the commitment to remember full details and reduces capsule transfer size. Endpoints that try to send a complete list of addresses in every ADDRESSASSIGN, including the null ones, might find they could get aboused, because its a lot simpler to send a short request with a unique request ID, than to respond to it. Probably nothing needs to change in the protocol but adding some considerations for implementers might be nice.
That's fair, we should say that the all-zero addresses don't need to be repeated in future capsules
Preferences for SHOULD NOT be repeated vs MUST NOT be repeated?
If an endpoint sends a polite ADDRESS_REQUEST that is well formed but the receiver can't or won't action it, there's no feedback. Since capsules are sent reliably, we can depend on them making it to the peer, but not necessarily being procesed. If the request is blackholed, should it, for example, ever be retried? There's a difference between a proxy refusing to do something and it temporarily being unable to do it (possibly due to resource constraints or rate limiting).
I don't think we currently have support for an ADDRESS_REQUEST capsule not being replied-to. The current language is written with the expectation that every REQUEST gets a RESPONSE. SO I would expect that if the request cannot be satisfied (i.e., is rejected) you get the rejection response that NAME just committed. So I would expect a proxy that is being rate-limited to respond, just slowly.
NAME please see URL
Thanks! makes it clearer how to assertively respond, which is good. However, the text IP addresses to its peer, and then respond with an ADDRESSASSIGN capsule to inform the peer of the assignment. This SHOULD is a bit hairy. Maybe it would be clear to split these out and state that a receiver of an ADDRESSREQUEST MUST reply.
I agree, I think that this should be upgraded to MUST that was missed after request/response IDs were added.
Agreed. I'd be supportive of a MUST along the lines of: Though we need to wordsmith it better
Not sure if a MUST really helps here. I guess there is no way to force an endpoint to reply and we also can't specify until when the reply needs to come, so you always need to implement a logic to detect that you didn't get reply. To be honest that also a point where I'm not fully happy with . So far my assumption was rather that you can of course nicely ask for an address. But as soon as you get an address_assign you should assume that the list is complete and work with rather that than speculatively waiting for a potentially update that may or may not come. Sending a reject as specified in makes the situation less ambiguous but in the end it shouldn't really change much because it always better to start sending quickly with an address that you got assigned than to wait and hope for another address.
Why not? Peer could reset the stream, or time out the entire connection. That is what the point of a MUST is.
If you get a bunch of addresses assigned that you don't want to use and they're decide to not use the connect, I guess you should close it. however, if you use it, there is no point in closing it just because you didn't get a reply to your request. And again we don't send when a reply should or must be send. So there is no final deadline when you could close a stream.
The whole reason we added request IDs was to remove the requirement to timeout. This does not work if we allow the peers to simply not respond. The contract here needs to be that reach request gets a response, like HTTP. If a peer breaks that, you close the stream -- like HTTP.
I don't think it's the same. If you send two requests which each one IP address and you only get one reply, you can use the IP you got and everything is fine. In http if you don't get a reply, you connection simply broken. Yes, it would make things easier if you can guarantee that you always get a reply but I don't think there is a good way to enforce that; or even trying to enforce it, creates more limitation than it might help.
I think its easier to built a client if it knows whether to expect responses in the protocol or not. This will govern how it approaches cases where it does or does not get a timely response, for some measure of timely. These might be (and probably are) implementations choices that should be pointed out. There's lots of reasons a client might detect something was slow, when in fact it was serviced as fast as possible. Imagine I run a proxy that might, for reasons that are outside of its control, have delays servicing one address request out of a few. If clients are going to be "smart" and make opaque decisions, then it could adversely affect my operations.

one or more IP addresses to its peer, and then respond with an ADDRESS_ASSIGN capsule to inform the peer of the assignment.  For each Requested Address, the receiver of the ADDRESS_REQUEST capsule  <ins> SHALL respond with a Assigned Address with a matching Request ID.  If the requested address was assigned, the IP Address and IP Prefix </ins> Length fields in the Assigned Address response SHALL be set to the assigned values.  If the requested address was not assigned, the IP Address SHALL be all-zero and the IP Prefix Length SHALL be the maximum length (0.0.0.0/32 or ::/128) to indicate that no address was  <ins> assigned.  These address rejections SHOULD NOT be included in subsequent ADDRESS_ASSIGN capsules.  Note that other Assigned Address entries that do not correspond to any Request ID can also be contained in the same ADDRESS_ASSIGN response. </ins> If an endpoint receives an ADDRESS_REQUEST capsule that contains zero Requested Addresses, it MUST abort the IP proxying request stream.


been formed. The lifetime of the IP forwarding tunnel is tied to the IP proxying <del> request stream.  Closing that stream (in HTTP/3 via the FIN bit on a QUIC STREAM frame, or a QUIC RESET_STREAM frame) closes the associated IP tunnel. </del>  Along with a successful response, the IP proxy can send capsules to assign addresses and advertise routes to the client (capsules).  The

I think it would be helpful to review the lifetime text in URL more closely align with it where it makes sense. What stuck out to me first was speaking about HTTP/3 specifically sticks out because all versions are supported. Second, there's no text about if a proxy can timeout itself and close the stream.
This makes sense, we can be a bit more specific with this guidance

been formed. The lifetime of the IP forwarding tunnel is tied to the IP proxying  <ins> request stream.  The IP proxy MUST maintain all IP address and route assignments associated with the IP forwarding tunnel while the request stream is open.  IP proxies MAY choose to tear down the tunnel due to a period of inactivity, but they MUST close the request stream when doing so. </ins> Along with a successful response, the IP proxy can send capsules to assign addresses and advertise routes to the client (capsules).  The


malformed.  The recipient of such a malformed request MUST respond with an error and SHOULD use the 400 (Bad Request) status code.  4.2. The IP proxy SHALL indicate a successful response by replying with If any of these requirements are not met, the client MUST treat this proxying attempt as failed and abort the connection.  4.3. When using HTTP/2 H2 or HTTP/3 H3, IP proxying requests use HTTP An IP proxying request that does not conform to these restrictions is malformed (see H2 and H3).  4.4. The IP proxy SHALL indicate a successful response by replying with If any of these requirements are not met, the client MUST treat this proxying attempt as failed and abort the request.  4.5. Unlike UDP proxying requests, which require specifying a target host,

Our cousin, CONNECT-UDP, has simple examples about how the requests and responses look in HTTP/1.1, 2 and 3. I appreciate the appendix has complicated examples. Would it be worth providing simple examples in Section 4, or at least forward referencing to them so people can get a feel?
That would be nice, if someone's willing to volunteer to do the editorial work of writing that PR. In other words, I'll happily review and merge it, but I don't have time to write it personally.
there's 5 authors on the draft, maybe one of the other 4 can spare the 10 minutes it would take?
Simple enough to add =)
Thanks for writing this!

malformed.  The recipient of such a malformed request MUST respond with an error and SHOULD use the 400 (Bad Request) status code. <ins> For example, if the client is configured with URI Template "https://example.org/.well-known/masque/ip/{target}/{ipproto}/" and wishes to open an IP forwarding tunnel with no target or protocol limitations, it could send the following request: </ins> 4.2. The IP proxy SHALL indicate a successful response by replying with If any of these requirements are not met, the client MUST treat this proxying attempt as failed and abort the connection. <ins> For example, the IP proxy could respond with: </ins> 4.3. When using HTTP/2 H2 or HTTP/3 H3, IP proxying requests use HTTP An IP proxying request that does not conform to these restrictions is malformed (see H2 and H3). <ins> For example, if the client is configured with URI Template "https://example.org/.well-known/masque/ip/{target}/{ipproto}/" and wishes to open an IP forwarding tunnel with no target or protocol limitations, it could send the following request: </ins> 4.4. The IP proxy SHALL indicate a successful response by replying with If any of these requirements are not met, the client MUST treat this proxying attempt as failed and abort the request. <ins> For example, the IP proxy could respond with: </ins> 4.5. Unlike UDP proxying requests, which require specifying a target host,


scenarios, endpoints MUST follow the recommendations from BCP38 to prevent source address spoofing.  11. 11.1.

Addressing the monitoring possibilities that connect request with ICMP scope has if sharing IP address as discussed in .
Over email, Mike Bishop mentioned: When looking into this I noticed that the section states the following about the IP Protocol field: But the section states: This is contradictory. I would recommend removing the recommendation in Error Signalling.
I don't think this is contradictory. The former text says "we will send you traffic whether you like it or not". The latter says "you should do something useful with it". Certainly it could be wordsmithed a bit, but I don't think an outright removal is a good idea as we should still give guidance to users that they are expected to do something if they're doing ipproto-based routing.
That doesn't match my understanding. To me, the former says "you don't need to send a route with ipproto=ICMP because it's always allowed" but the latter says "you SHOULD send a route with ipproto=ICMP"
I think those are compatible? The former is saying you don't have to, the latter is signaling you've acknowledged and will do something useful with it.
Isn't that just wasted bytes?
I could imagine a server doing something useful with this information. Maybe having different ratelimits for ICMP traffic for a well-behaved client that will process the messages. But this only applies in the cases where you're using ipproto scoping, so I am not too worried about the bytes-wasted
If we intend to have recipients act on this information, we should clearly define what it's meant to convey, otherwise we'll create interoperability issues.
That's fair. To be clear, I do not object to removing the text as you originally suggested. I just wanted to clarify that I didn't consider the current situation a contradiction.
I think we need to clarify this a bit as it actually exist three different interpretation depending on what was requested. So if the requester do a Connect request with ipproto=1 scope: I will get all ICMP message for this IP address would be my interpretation. This is fine to ask for, but I think we need a security consideration note on this. This should only be allowed if this external IP address that is assigned is only used by this requesting endpoint. Otherwise it will allow some possibility to overhead what the other endpoint attempt to do when ICMP messages are generated back towards this IP address. So if the connect request is for ipproto=6 (TCP): In this case we have two interpretations of what has been written. A) The IP proxy will send ICMP messages to the requesting endpoint to indicate issues. B) The IP proxy will match any incoming ICMP messages on the external IP address assgined and forward them to the requestor. So what I expect to happen is that A) will always happen, but it is unclear if B) will happen. I think we want to make clear that B) MAY/SHOULD/MUST be done. I will write a PR for the security consideration for requesting ICMP traffic for an assigned address.
Overall I totally agree with this change, but I think the wording needs some work. I've included a proposal.

scenarios, endpoints MUST follow the recommendations from BCP38 to prevent source address spoofing. <ins> Limiting request scope (see scope) allows two clients to share one of the proxy's external IP addresses if their requests are scoped to different IP protocol numbers.  If the proxy receives an ICMP packet destined for that external IP address, it has the option to forward it back to the clients.  However, some of these ICMP packets carry part of the original IP packet that triggered the ICMP response. Forwarding such packets can accidentally divulge information about one client's traffic to another client.  To avoid this, proxies that forward ICMP on shared external IP addresses MUST inspect the invoking packet included in the ICMP packet and only forward the ICMP packet to the client whose scoping matches the invoking packet. </ins> 11. 11.1.


send Packet Too Big ICMPv6. In order to receive these errors, endpoints need to be prepared to <del> receive ICMP packets.  If an endpoint sends ROUTE_ADVERTISEMENT capsules, its routes SHOULD include an allowance for receiving ICMP messages.  If an endpoint does not send ROUTE_ADVERTISEMENT capsules, such as a client opening an IP flow through an IP proxy, it SHOULD process proxied ICMP packets from its peer in order to receive these errors.  Note that ICMP messages can originate from a source address different from that of the IP proxying peer. </del>  8.

Over email, Mike Bishop mentioned: When looking into this I noticed that the section states the following about the IP Protocol field: But the section states: This is contradictory. I would recommend removing the recommendation in Error Signalling.
I don't think this is contradictory. The former text says "we will send you traffic whether you like it or not". The latter says "you should do something useful with it". Certainly it could be wordsmithed a bit, but I don't think an outright removal is a good idea as we should still give guidance to users that they are expected to do something if they're doing ipproto-based routing.
That doesn't match my understanding. To me, the former says "you don't need to send a route with ipproto=ICMP because it's always allowed" but the latter says "you SHOULD send a route with ipproto=ICMP"
I think those are compatible? The former is saying you don't have to, the latter is signaling you've acknowledged and will do something useful with it.
Isn't that just wasted bytes?
I could imagine a server doing something useful with this information. Maybe having different ratelimits for ICMP traffic for a well-behaved client that will process the messages. But this only applies in the cases where you're using ipproto scoping, so I am not too worried about the bytes-wasted
If we intend to have recipients act on this information, we should clearly define what it's meant to convey, otherwise we'll create interoperability issues.
That's fair. To be clear, I do not object to removing the text as you originally suggested. I just wanted to clarify that I didn't consider the current situation a contradiction.
I think we need to clarify this a bit as it actually exist three different interpretation depending on what was requested. So if the requester do a Connect request with ipproto=1 scope: I will get all ICMP message for this IP address would be my interpretation. This is fine to ask for, but I think we need a security consideration note on this. This should only be allowed if this external IP address that is assigned is only used by this requesting endpoint. Otherwise it will allow some possibility to overhead what the other endpoint attempt to do when ICMP messages are generated back towards this IP address. So if the connect request is for ipproto=6 (TCP): In this case we have two interpretations of what has been written. A) The IP proxy will send ICMP messages to the requesting endpoint to indicate issues. B) The IP proxy will match any incoming ICMP messages on the external IP address assgined and forward them to the requestor. So what I expect to happen is that A) will always happen, but it is unclear if B) will happen. I think we want to make clear that B) MAY/SHOULD/MUST be done. I will write a PR for the security consideration for requesting ICMP traffic for an assigned address.

send Packet Too Big ICMPv6. In order to receive these errors, endpoints need to be prepared to  <ins> receive ICMP packets.  If an endpoint does not send ROUTE_ADVERTISEMENT capsules, such as a client opening an IP flow through an IP proxy, it SHOULD process proxied ICMP packets from its peer in order to receive these errors.  Note that ICMP messages can originate from a source address different from that of the IP proxying peer. </ins> 8.


bytes of data to ascertain the link MTU and tear down the tunnel if they do not receive a response.  Unless endpoints have an out of band means of guaranteeing that the previous techniques is <del> sufficient, they MUST use this method. </del>  If an endpoint is using QUIC DATAGRAM frames to convey IPv6 packets, and it detects that the QUIC MTU is too low to allow sending 1280

Which IPv6 address is the Client pinging through the tunnel? The Client knows which source address(es) it can use (from the ADDRESSASSIGN(s) that it has received), but not necessarily a good destination address. When ROUTEADVERTISEMENT are networks, it is not clear which hosts if any on those networks are pingable. In the flow forwarding case, there is a clear target host, but do we want to require the target to respond to ICMPv6 echo request pings lest it be unreachable on any protocol over connect-ip? Perhaps the destination address for these pings should be a special address on which the IP Proxy itself is required to respond to ICMPv6 echo requests through the tunnel?
Good question! NAME thoughts?
This was intended to be the link-local address(es)
Good catch. I'll write a PR suggesting to use the link-local all-nodes multicast address if the peer's address is unknown

bytes of data to ascertain the link MTU and tear down the tunnel if they do not receive a response.  Unless endpoints have an out of band means of guaranteeing that the previous techniques is  <ins> sufficient, they MUST use this method.  If an endpoint does not know an IPv6 address of its peer, it can send the ICMPv6 echo request to the link local all nodes multicast address (ff02::1). </ins> If an endpoint is using QUIC DATAGRAM frames to convey IPv6 packets, and it detects that the QUIC MTU is too low to allow sending 1280


different from the one used to receive it, as the request encoding differs by version (see below). <del> otherwise, the recipient will act as an IP proxy.  It extracts the optional "target" and "ipproto" variables from the URI it has reconstructed from the request headers, decodes their percent- encoding, and establishes an IP tunnel. </del>  IP proxies MUST validate whether the decoded "target" and "ipproto" variables meet the requirements in scope.  If they do not, the IP proxy MUST treat the request as malformed; see H2 and H3.  If the "target" variable is a DNS name, the IP proxy MUST perform DNS <del> resolution before replying to the HTTP request.  If errors occur during this process, the IP proxy MUST reject the request and SHOULD send details using an appropriate Proxy-Status header field PROXY- STATUS.  For example, if DNS resolution returns an error, the proxy can use the "dns_error" Proxy Error Type from PROXY-STATUS. </del>  The lifetime of the IP forwarding tunnel is tied to the IP proxying request stream.  The IP proxy MUST maintain all IP address and route 8.2.  The following example shows an IP flow forwarding setup, where a client requests to establish a forwarding tunnel to target.example.com using SCTP (IP protocol 132), and receives a (2001:db8:3456::b), scoped to SCTP.  The client can send and receive SCTP IP packets to the remote host. <del> 8.3. </del>  The following example shows a setup where a client is proxying UDP packets through an IP proxy in order to control connection

This is an editorial PR based on comments made by Chris Wood during his shepherd review of the document.

different from the one used to receive it, as the request encoding differs by version (see below).  <ins> otherwise, the recipient will act as an IP proxy.  The IP proxy can choose to reject the IP proxying request.  Otherwise, it extracts the optional "target" and "ipproto" variables from the URI it has reconstructed from the request headers, decodes their percent-encoding, and establishes an IP tunnel. </ins> IP proxies MUST validate whether the decoded "target" and "ipproto" variables meet the requirements in scope.  If they do not, the IP proxy MUST treat the request as malformed; see H2 and H3.  If the "target" variable is a DNS name, the IP proxy MUST perform DNS  <ins> resolution (to query the corresponding IPv4 and/or IPv6 addresses via A and/or AAAA records) before replying to the HTTP request.  If errors occur during this process, the IP proxy MUST reject the request and SHOULD send details using an appropriate Proxy-Status header field PROXY-STATUS.  For example, if DNS resolution returns an error, the proxy can use the "dns_error" Proxy Error Type from PROXY- STATUS. </ins> The lifetime of the IP forwarding tunnel is tied to the IP proxying request stream.  The IP proxy MUST maintain all IP address and route 8.2. <ins> The following example shows how to connect a branch office network to a corporate network such that all machines on those networks can communicate.  In this example, the IP proxying client is attached to the branch office network 192.0.2.0/24, and the IP proxy is attached to the corporate network 203.0.113.0/24.  There are legacy clients on the branch office network that only allow maintenance request from machines on their subnet, so the IP Proxy is provisioned with an IP address from that subnet. In this case, the client does not specify any scope in its request. The IP proxy assigns the client an IPv4 address (203.0.113.100) and a split-tunnel route to the corporate network (203.0.113.0/24).  The client assigns the IP proxy an IPv4 address (192.0.2.200) and a split-tunnel route to the branch office network (192.0.2.0/24).  This allows hosts on both networks to communicate with each other, and allows the IP proxy to perform maintenance on legacy hosts in the branch office. 8.3. </ins> The following example shows an IP flow forwarding setup, where a client requests to establish a forwarding tunnel to target.example.com using SCTP (IP protocol 132), and receives a (2001:db8:3456::b), scoped to SCTP.  The client can send and receive SCTP IP packets to the remote host.  <ins> 8.4. </ins> The following example shows a setup where a client is proxying UDP packets through an IP proxy in order to control connection


However, these mechanisms cannot tunnel other IP protocols IANA-PN nor convey fields of the IP header. <del> This document describes a protocol for tunnelling IP to an HTTP </del>  server acting as an IP-specific proxy over HTTP.  This can be used for various use cases such as point-to-network VPN, secure point-to- point communication, or general-purpose packet tunnelling. defines protocol types, the definition format uses the notation from QUIC.  This specification uses the variable-length integer encoding from QUIC.  Variable-length integer values do not need to be encoded <del> on the minimum number of bytes necessary. </del>  Note that, when the HTTP version in use does not support multiplexing streams (such as HTTP/1.1), any reference to "stream" in this 10. There are significant risks in allowing arbitrary clients to <del> establish a tunnel that permits sending to arbitrary hosts, as that could allow bad actors to send traffic and have it attributed to the IP proxy.  IP proxies SHOULD restrict its use to authenticated users. The HTTP Authorization header HTTP MAY be used to authenticate clients.  More complex authentication schemes are out of scope for this document but can be implemented using extensions. </del>  Falsifying IP source addresses in sent traffic has been common for denial of service attacks.  Implementations of this mechanism need to

This adds some additional security considerations, touching on privacy considerations at the same time. Do we want to say anything about IP fragmentation, or at least point to some existing guidance around how to avoid sharp edges there? Please feel free to reframe or modify the text as you see fit!

However, these mechanisms cannot tunnel other IP protocols IANA-PN nor convey fields of the IP header.  <ins> This document describes a protocol for tunnelling IP through an HTTP </ins> server acting as an IP-specific proxy over HTTP.  This can be used for various use cases such as point-to-network VPN, secure point-to- point communication, or general-purpose packet tunnelling. defines protocol types, the definition format uses the notation from QUIC.  This specification uses the variable-length integer encoding from QUIC.  Variable-length integer values do not need to be encoded  <ins> in the minimum number of bytes necessary. </ins> Note that, when the HTTP version in use does not support multiplexing streams (such as HTTP/1.1), any reference to "stream" in this 10. There are significant risks in allowing arbitrary clients to  <ins> establish a tunnel that permits sending to arbitrary hosts, regardless of whether tunnels are scoped to specific hosts or not. Bad actors could abuse this capability to send traffic and have it attributed to the IP proxy.  IP proxies SHOULD restrict its use to authenticated users.  Depending on the deployment, possible authentication mechanisms include mutual TLS between clients and proxies, HTTP-based authentication via the HTTP Authorization header HTTP, or even bearer tokens.  Proxies can enforce policies for authenticated users to further constrain client behavior or deal with possible abuse.  For example, proxies can rate limit individual clients that send an excessively large amount of traffic through the proxy.  As another example, proxies can restrict address (prefix) assignment to clients based on certain client attributes such as geographic location. Address assignment can have privacy implications for endpoints.  For example, if a proxy partitions its address space by the number of authenticated clients and then assigns distinct address ranges to each client, target hosts could use this information to determine when IP packets correspond to the same client.  Avoiding such tracking vectors may be important for certain proxy deployments. Proxies SHOULD avoid persistent per-client address (prefix) assignment when possible. </ins> Falsifying IP source addresses in sent traffic has been common for denial of service attacks.  Implementations of this mechanism need to


11.4. <del> This document will request IANA to add the following values to the "HTTP Capsule Types" registry maintained at <<https://www.iana.org/assignments/http-capsule-protocol/http- capsule-protocol.xhtml>>. </del>

NAME as capsule type registry expert, are you OK with this text?
URL registers 3 capsules that use 0x1ECA6A00, 0x1ECA6A01, and 0x1ECA6A02. Its good practice to use the provisional registration space while developing a document, so you have my appreciation. But its not clear if you intend to change these into the permanent registration space prior to publication. CONNECT-UDP followed that approach and noted it with . Please clarify if you intend to change the values and, if so, when.
That's a good point, I was planning on changing them right after WGLC but I guess that's not written in the draft. Let's keep this issue open during the WGLC and close it once we move to the final values
Plan is to have: 0x01 for ADDRESSASSIGN 0x02 for ADDRESSREQUEST 0x03 for ROUTE_ADVERTISEMENT assuming NAME agrees since we're the two IANA experts on that registry
in principle that's fine by me. We should be wary of using them too early in case things have to change even after WGLC. So late binding once publication is impending is the least risky and works for me.
On one hand I agree with you that assigning them sooner avoids the risk of dealing with interop failures if IESG review leads to unavoidable wire-format changes. On the other, waiting until after IESG approval means that now we have interop issues between the folks that deployed before or after that - that's what we're seeing with QUIC version negotiation. So I would prefer to get provisional registrations for the low codepoints after WGLC personally
reasonable
LGTM. I was going to suggest ot would be nice to articulate the codepoint change in the changelog, but I guess you don't have one anyway...

11.4.  <ins> This document requests IANA to add the following values to the "HTTP Capsule Types" registry maintained at <<https://www.iana.org/assignments/http-capsule-protocol>>. All of these new entries use the following values for these fields: RFC Editor: please remove the rest of this subsection before publication. Since this document has not yet been published, it might still change before publication as RFC.  Any implementer that wishes to deploy IP proxying in production before publication MUST use the following temporary codepoints instead: 0x2575D601 for ADDRESS_ASSIGN, 0x2575D602 for ADDRESS_REQUEST, and 0x2575D603 for ROUTE_ADVERTISEMENT. </ins>


it will parse the packet's IP header, perform any local policy checks (e.g., source address validation), check their routing table to pick an outbound interface, and then send the IP packet on that interface <del> or pass it to a local application. </del>  In the other direction, when an endpoint receives an IP packet, it checks to see if the packet matches the routes mapped for an IP loops, and matches the choices in IPsec IPSEC. Implementers need to ensure that they do not forward any link-local <del> traffic onto a different interface than the one it was received on. IP proxies also need to properly reply to packets destined to link- local multicast addresses. </del>  IPv6 requires that every link have an MTU of at least 1280 bytes IPv6.  Since IP proxying in HTTP conveys IP packets in HTTP Datagrams

From NAME
This is IP networking, so there is no notion of "fear of being dropped". Any IP link or router can drop any packet any time for any reason. I wrote PR to clarify this.
I get that there are no guarantees in IP networking. The PR is fine, but I'm not afraid that someone thinks this protocol is providing delivery guarantees. But there is a clear divide between using an IP address speculatively and sending one that the peer has given an indication will succeed. It's the meaning of the phrase "due to an improper address" in the initial issue. This is the point of having ADDRESSASSIGN and ROUTEADVERTISEMENT. Put another way, what does an implementation do when it receives ROUTE_ADVERTISEMENT? Are there any other equivalent events that trigger the same behavior (e.g. A 200 on a CONNECT-IP request to a literal IP?)
No, that's not how IP networks work. Let's take the example of DHCP: a client attaches to a new network and asks for an address. The DHCP server assigns an IP to the client. The client often sends from that address, but that assignment does not represent any assurances with regards to delivery, it represents unicity. On my home network I have DHCP but also machines with static addresses - when I get address X via DHCP, I have absolutely no assurance that sending with that source address is more likely to succeed than with this static address. Whether packets gets through is a matter of either (a) policy or (b) addressing architecture - both of which were decided out of scope during the WG consensus process for draft-ietf-masque-ip-proxy-reqs, see . All this to say, I understand what you're asking for - but it's squarely out of scope
"I have absolutely no assurance that sending with that source address is more likely to succeed than with this static address." "assurance" and "more likely" are weird things to have in the same sentence -- anything dealing with likelihood is by definition not assured. Your flattening of the distinction between addresses the sender picks out of the air and those in ADDRESSASSIGNED and ROUTEADVERTISEMENT makes me wonder what the point of those capsules are. ADDRESSASSIGNED at least means "I will try to deliver packets to you if they have this destination IP", but what does ROUTEADVERTISEMENT mean if not "you have a somewhat better chance of delivering these than a randomly picked destination IP?" And whatever ROUTE_ADVERTISEMENT means, is a 200 on CONNECT to a literal IP equivalent, or do they carry different semantics?
These capsules exchange configuration data. The recipient is free to choose to apply said configuration, or ignore it. To answer your specific question: yes - if you are a split-tunnel VPN client, you'll install any routes from ROUTEADVERTISEMENT into your routing table. But in a separate scenario if you're just trying to get a point-to-point link, you're going to ignore a ROUTEADVERTISEMENT telling you the whole world is routable. Taking a few steps back: what change would you like to see in the draft that is not covered by ?
OK, after a higher-bandwidth discussion, where I went wrong is with this sentence in S4.7.3: "Upon receiving the ROUTE_ADVERTISEMENT capsule, an endpoint MAY start routing IP packets in these ranges to its peer." This implies that an endpoint should not send before this, which is not the intent. NAME and I agreed that this sentence should be deleted or changed. I recommended some sort of alternative sentence(s) in this section that clearly stated the purpose of this capsule, perhaps something that ends with "for the use cases where clients require it"
NAME I wrote up a fix for that last point as . That's what we initially intended and avoid the unintended implication

it will parse the packet's IP header, perform any local policy checks (e.g., source address validation), check their routing table to pick an outbound interface, and then send the IP packet on that interface  <ins> or pass it to a local application.  The endpoint can also choose to drop any received packets instead of forwarding them.  If a received IP packet fails any correctness or policy checks, that is a forwarding error, not a protocol violation as far as IP proxying is concerned; see error-signal. </ins> In the other direction, when an endpoint receives an IP packet, it checks to see if the packet matches the routes mapped for an IP loops, and matches the choices in IPsec IPSEC. Implementers need to ensure that they do not forward any link-local  <ins> traffic beyond the IP proxying interface that it was received on.  IP proxying endpoints also need to properly reply to packets destined to link-local multicast addresses. </ins> IPv6 requires that every link have an MTU of at least 1280 bytes IPv6.  Since IP proxying in HTTP conveys IP packets in HTTP Datagrams


receiver of the capsule MUST follow the error handling procedure defined in HTTP-DGRAM. <del> Upon receiving the ROUTE_ADVERTISEMENT capsule, an endpoint MAY start routing IP packets in these ranges to its peer. </del>  Each ROUTE_ADVERTISEMENT contains the full list of address ranges. If multiple ROUTE_ADVERTISEMENT capsules are sent in one direction,

From NAME
Link-local addresses are valid, why would they not be? This was the consensus of the editors and then of the WG. I agree with you about incentives, but this was deemed better than any alternative proposed at the time.
On the second point, OK, I figured as much. The first point is triggered by (S6): "Implementers need to ensure that they do not forward any link-local traffic onto a different interface than the one it was received on. IP proxies also need to properly reply to packets destined to link-local multicast addresses." I'm having a little trouble reasoning about this, but is it allowed for a proxy to send ADDRESS_ASSIGN containing a link-local address? Only if the MASQUE connection is on the same physical interface as the address? Or is a MASQUE connection a virtual interface? Similarly, are there conditions where a client could send an IP packet addressed to a link-local address? If so, would this be forwarded out the "internet end" of the proxy? I'm not convinced there's a problem here, but I'm confused.
Yes, why would it not be? No no no - these addresses are inside the tunnel. A MASQUE connection is a virtual interface, just like IPsec, WireGuard, OpenVPN, etc. "Virtual interface" is not a well-defined concept as far as RFCs go, but yeah it's an interface that isn't a physical cable or radio. Yes. So the use for this is the traditional scenario where both IP proxying endpoints have link-local addresses, then they can use them to communicate between one another. No, link-local traffic is by definition local to the link. Those packets cannot be forwarded onto another interface. They can only be destined to the peer.
After further high-bandwidth discussion, I believe the design covers all the bases. We agreed that the following two changes are best: (1) Both connect-IP endpoints need to reply to link-layer multicast, not just the proxy. (2) change the requirement about not forwarding link-local IPs over different interfaces (which opens up a useless what-is-an-interface discussion) with clearer language like "don't forward beyond that IP tunnel" or "beyond the HTTP stream", etc.
From NAME
This is IP networking, so there is no notion of "fear of being dropped". Any IP link or router can drop any packet any time for any reason. I wrote PR to clarify this.
I get that there are no guarantees in IP networking. The PR is fine, but I'm not afraid that someone thinks this protocol is providing delivery guarantees. But there is a clear divide between using an IP address speculatively and sending one that the peer has given an indication will succeed. It's the meaning of the phrase "due to an improper address" in the initial issue. This is the point of having ADDRESSASSIGN and ROUTEADVERTISEMENT. Put another way, what does an implementation do when it receives ROUTE_ADVERTISEMENT? Are there any other equivalent events that trigger the same behavior (e.g. A 200 on a CONNECT-IP request to a literal IP?)
No, that's not how IP networks work. Let's take the example of DHCP: a client attaches to a new network and asks for an address. The DHCP server assigns an IP to the client. The client often sends from that address, but that assignment does not represent any assurances with regards to delivery, it represents unicity. On my home network I have DHCP but also machines with static addresses - when I get address X via DHCP, I have absolutely no assurance that sending with that source address is more likely to succeed than with this static address. Whether packets gets through is a matter of either (a) policy or (b) addressing architecture - both of which were decided out of scope during the WG consensus process for draft-ietf-masque-ip-proxy-reqs, see . All this to say, I understand what you're asking for - but it's squarely out of scope
"I have absolutely no assurance that sending with that source address is more likely to succeed than with this static address." "assurance" and "more likely" are weird things to have in the same sentence -- anything dealing with likelihood is by definition not assured. Your flattening of the distinction between addresses the sender picks out of the air and those in ADDRESSASSIGNED and ROUTEADVERTISEMENT makes me wonder what the point of those capsules are. ADDRESSASSIGNED at least means "I will try to deliver packets to you if they have this destination IP", but what does ROUTEADVERTISEMENT mean if not "you have a somewhat better chance of delivering these than a randomly picked destination IP?" And whatever ROUTE_ADVERTISEMENT means, is a 200 on CONNECT to a literal IP equivalent, or do they carry different semantics?
These capsules exchange configuration data. The recipient is free to choose to apply said configuration, or ignore it. To answer your specific question: yes - if you are a split-tunnel VPN client, you'll install any routes from ROUTEADVERTISEMENT into your routing table. But in a separate scenario if you're just trying to get a point-to-point link, you're going to ignore a ROUTEADVERTISEMENT telling you the whole world is routable. Taking a few steps back: what change would you like to see in the draft that is not covered by ?
OK, after a higher-bandwidth discussion, where I went wrong is with this sentence in S4.7.3: "Upon receiving the ROUTE_ADVERTISEMENT capsule, an endpoint MAY start routing IP packets in these ranges to its peer." This implies that an endpoint should not send before this, which is not the intent. NAME and I agreed that this sentence should be deleted or changed. I recommended some sort of alternative sentence(s) in this section that clearly stated the purpose of this capsule, perhaps something that ends with "for the use cases where clients require it"
NAME I wrote up a fix for that last point as . That's what we initially intended and avoid the unintended implication

receiver of the capsule MUST follow the error handling procedure defined in HTTP-DGRAM.  <ins> Upon receiving the ROUTE_ADVERTISEMENT capsule, an endpoint MAY update its local state regarding what its peer is willing to route (subject to local policy), such as by installing entries in a routing table. </ins> Each ROUTE_ADVERTISEMENT contains the full list of address ranges. If multiple ROUTE_ADVERTISEMENT capsules are sent in one direction,


HTTP Extended CONNECT as described in EXT-CONNECT2 and EXT-CONNECT3. When using HTTP/1.x H1, it uses HTTP Upgrade as defined in HTTP. <del> This document updates CONNECT-UDP. </del>  2.

From . Let's tweak that one sentence to mention the IANA registry that we're changing. Reviewer: Bob Briscoe Review result: Not Ready This document has been reviewed as part of the transport area review team's ongoing effort to review key IETF documents. These comments were written primarily for the transport area directors, but are copied to the document's authors and WG to allow them to address any issues raised and also to the IETF discussion list for information. When done at the time of IETF Last Call, the authors should consider this review as part of the last-call comments they receive. Please always CC EMAIL if you reply to or forward this review. ==Overall comments== How can I say this politely? The HTTP aspects of this document are great work and near-complete. However, the tunnelling aspects, in particular the layering interactions need a lot of work - possibly even a partial redesign in places. Also, the security aspects seem to have been viewed through rose-coloured spectacles; sthg like "Most people who like privacy are nice". Well-written, but not an easy read in a single pass (not clear what the point is for quite a few pages and lots of forward x-references). Early overview of the scheme would help. Need to bear in mind that cross-layer work has to be addressed at a wider community who don't necessarily all subscribe to the same mind-share. ==Document Structure== I believe §§3-4 are about the tunnel config, and §§5-7 are the per-packet aspects of the tunnel. Might be worth explaining that in a doc roadmap. "Payload Format" This section needs to be split and/or re-titled, 'cos in the middle (from "Client MAY optimistically start sending...") it switches to operation, not format. At "Note that endpoints will decrement..." it switches to TTL handling. Then at "IPv6 requires that.." it switches to MTU discovery, which is another aspect of operation. Just because TTL and packet size are fields of an IP packet, doesn't mean these aspects fall under the heading of "Payload Format" - these paras are about handling these fields, not defining their format. ==Gaps== ===A) No discussion of packet ordering === Although one of the variants of HTTP (http/3) is over UDP, which is unordered, QUIC still delivers an ordered stream to the app (which, in this case, is the inner of the tunnel). So, presumably as packets arrive at the proxy, if there has been misordering or a loss, QUIC will buffer until the next packet in order can be delivered, i.e. head-of-line blocking. Hence, it's not really advisable to forward connectionless packets through a connection-oriented tunnel. The privacy benefit might make the poor latency performance worth it. But this trade off at least needs to be stated, perhaps in an applicability section. I don't think an http3 stream is any less granular than an http2 stream or an http1.1 connection in this proxy arrangement. But if it is, each need to be discussed separately. If there is a vision to use an unordered variant of QUIC, then there could be problems with Context IDs being processed out of order, which could produce all sorts of unexpected side-effects, given Context IDs are potentially stateful (caveat: you will see that I don't really understand what Context IDs might be used for). ===B) Conflicting Congestion Controllers (CCs) === Needs a section sthg like §12.1 of RFC8229, except: That text mostly just listed the problems, but the implication of publishing such a section in a spec is essentially, "We've told you the problems, but now go ahead anyway." This is not just a TCP in TCP problem. It's any nesting of two or more CC-controlled protocols (e.g. TCP within QUIC, QUIC within QUIC, etc) As above, if this is a trade off between privacy and performance, that needs stating. ===C) Overlapping connection life-cycles === If a proxy crashes, powers down, etc. can it be brought back up with all the connection state restored that it held before it failed? Otherwise, all the connections within the tunnel inner depend on the survival of their outer connection. There is no reason to believe that all the inner connections are dispensable. Would a soft-state design be more resilient than the hard-state design described? [The above points (A-C) are examples of the problems I mentioned when using a connection-oriented protocol to tunnel a connectionless protocol.] ===D) Applicable Next Headers (aka IP Protocols) === No discussion of whether some IPv6 'Next Headers' (or IPv4 Protocols) are not applicable / unsafe / poor performing. The last time that I proposed a generic UDP tunnel to the Intarea as an alternative to GUE, the criticism was that it was "too generic". I was told that the choice of tunnel protocols is about whether they are sufficiently limiting; the aim is not totally generic. === E) Applicable Address Ranges === Are anycast addresses in scope? IP multicast? Link-local multicast is mentioned. What about ARP? Service Discovery? ===F) Propagation of IP headers and header fields between inner and outer. === Some IPv6 extension headers are copied from inner to outer on encapsulation; others aren't [RFC2473; §5.1]. The outer IPv6 flow label is often zeroed. The contents of the DSCP, and ECN fields can be propagated from inner to outer and the ECN outer is propagated back to the forwarded header [RFC2983], [RFC6040]. Because there's a whole stack of headers between the inner and outer IP headers (e.g. IP, UDP, QUIC, HTTP, IP), the draft needs to make it clear that these copying and propagation rules still apply between the two IP headers. ===G) No explanation of pros & cons relative to other packet tunnelling === Yes, we can tunnel anything over anything, but why this one? AFAIK, it's to hide traffic in the HTTP crowd for privacy. But what are the merits relative to hiding in other crowds? And the drawbacks (e.g. HoL blocking as mentioned above). In particular, the pros & cons vs UDP in HTTP. ===H) Role reversal? === It's not made clear whether there's anything intrinsically 'clientish' about a client. Or 'proxyish' about a proxy. Especially in a bump in the wire topology (like the site-site VPN example), does it matter which is which? Is it just determined by the administrator setting a proxy up in listen mode? Is there anything that one or the other cannot do by virtue of its role, other than initiate a connection to the other one? Shouldn't the draft speak about this if it requires correct manual set up? Particularly for tunnels consisting of chains (or trees?) of intermediaries. ==Section by Section== Introduction (and Abstract) "...updates RFC9298" It's not at all clear to me what aspect of RFC9298 this RFC updates. It seems unlikely, given IP Proxying is an alternative to UDP Proxying, not an update. But if it does, the draft needs to say what it updates. And, if RFC9298 were updated by this draft, it would surely be a normative reference, not informative. Configuration of Clients Reasoning for each each URI template rule? I can't really judge whether this set of rules leaves the URI template flexible enough, without knowing the reason for each constraint. Is this explained in "Proxying UDP in HTTP"? If so, a ref would be useful. "IP proxy deployments SHOULD offer service at this location if they need to interoperate with such clients." Surely "MUST" to interoperate? Tunnelling IP over HTTP "When sending its IP proxying request, the client SHALL perform URI template expansion..." Surely just "... the client performs..." (just a necessary process step, not an interop requirement) "IP proxying requests [responses] do not carry any message content." Is it an error if they do? 4.1. IP Proxy Handling "URL IP proxy MUST perform DNS resolution..." Surely "... the IP proxy performs..." (just a necessary process step, not an interop requirement) "IP proxies MAY choose to tear down the tunnel due to a period of inactivity" Better? "IP proxies MAY choose to tear down the tunnel, e.g. due to a period of inactivity" Rationale: there are other possible reasons, e.g responding to an attack. "Any response other than a successful response indicates that the request has failed; thus, the client MUST abort the request." This is repeated at each instance in the subsequent sections. Either not needed here as well, or not needed in each section as well. 4.6. Limiting Request Scope "When the IP proxy knows that a request is scoped to a target prefix or protocol, it can leverage this information to optimize its resource allocation..." This highlights that the protocol relies on a perverse incentive for the client to scope its request so that the server can optimize its resources. That smells like potentially the opposite of resource optimization, i.e. a vulnerability; clients can scope their requests to force a server to frag its resources. Perhaps consider redesigning the protocol so that the server initiates the scoping (or at least it can somehow negotiate the outcome)? "target: URL IP proxy is expected to perform DNS resolution ..." Might this potentially amplify a resource exhaustion vulnerability, esp. if the client continually gives the proxy DNSSEC work? "IP proxies MAY perform access control using the scoping information provided by the client: if the client is not authorized to access any of the destinations included in the scope, then the IP proxy can immediately fail the request." I think the clause after ':' ought to be tagged as an example. I think it's intended to be a degenerate/extreme example. Whatever, its relation with the earlier words is unclear. It's possible this would be better in §4.1, which is where it would fit into the process steps. However, at that point in the draft, scope limiting hasn't ben explained. I'm in two minds. 4.7. Capsules Are all control messages to the tunnel on one stream, or can each capsule arrive in a separate stream, or is it up to the operator? IOW, do capsules have to be acted on in the order they are sent, or does it depend? The last para starting "Note that the IP forwarding tunnels described in this document..." seems more like an architectural point that ought to be stated earlier. It's related to ADDRESSASSIGN, but is it really appropriate to bury it here? IP version: Address assignment syntax presumes that two request prefixes will return two addresses. I think this means that an endpoint cannot request just one address, when it doesn't mind whether it's within a certain IPv4 address range or a certain IPv6 address range. In the happy eyeballs example, this returns two addresses. Similarly, I don't think the syntax can express no preference for a prefix length. Only a specific prefix length is possible. Correct? Should these limitations of the syntax be pointed out? "URL most recently received ROUTEADVERTISEMENT capsule..." I assume this means most recently received after reordering has been corrected. See my first point under Capsules about control message ordering. Context Identifiers The point below is in a similar vein to the earlier point about whether generic support of IP Protocols (Next Headers) is a boon or a bane... This section seems like it's early research. It's vague, with no examples and no clear purpose (to me). So one cannot reason about what security vulnerabilities it might open up (let alone what flexibility it potentially affords). There is no citation of [HTTP-DGRAM] in this section, nor explanation of the purpose of a Context ID. "The Context ID value of 0 is reserved for IP payloads, " This clearly means that non-IP payloads cannot use 0, but does it also mean that IP payloads cannot use non-zero values? It's not clear, but none of the examples (that all use IP) show a non-zero Context ID. A later para (2nd para under Fig 13 in §6) seems to more unambiguously define a 1:1 mapping between IP and Context ID=0. If so, I don't understand the point of a Context ID in these tunnelling cases. What am I missing? "it is possible for datagrams to be received with Context IDs that have not yet been registered. For instance, this can be due to reordering of the packet containing the datagram and the packet containing the registration message during transmission." So..., what happens then? HTTP Datagram Payload Format "Context ID: A variable-length integer that contains the value of the Context ID. If an HTTP/3 datagram which carries an unknown Context ID is received, the receiver SHALL either drop that datagram silently or buffer it temporarily (on the order of a round trip) while awaiting the registration of the corresponding Context ID." A number of problems here: undefined what happens if an http/2 or http/1.1 datagram carries an unknown Context ID? For TCP, the app layer doesn't know the RTT. * Isn't this a resource exhaustion vulnerability? the sender contrives packets with Context IDs that cause the receiver to buffer everything, exhausting the memory available for other senders. "Endpoints MAY implement additional filtering policies on the IP packets they forward." Eh? This is the first mention of filtering policies. Error Signalling For a bump in the wire topology, can an ICMP error be sent back, from one IP side to the other, through the HTTP tunnel and out the other side? That will probably work. However, presumably an ICMP error raised by the network within the extent of the HTTP tunnel will be directed back to the ingress tunnel endpoint but no further. 8.4. Proxied Connection Racing It might be worth pointing out in a note at the end of this example that, as well as the proxy deciding to set up parallel tunnels, the approach would also allow the client to initiate parallel tunnels. Security Considerations I find it quite lame/naïve that this section essentially says, "This Proxy design gives arbitrary clients great power, both to toast proxies and to make them appear to be the senders of arbitrary messages to arbitrary destinations" BUT, "That's not a problem, because a proxy SHOULD restrict its use to authorized users." This massive "get out of jail free" card begs the question, "What management processes are necessary for this proxy to monitor users to determine whether to remove their authorization?" It's akin to saying, "We're going to issue automatic assault rifles to everyone over the age of 6, but it's not a problem, because it's illegal to shoot someone without a permit." ==Nits== "HTTP provides the CONNECT method (see Section 9.3.6 of [HTTP]) for creating a TCP [TCP] tunnel..." Citation of IETF core protocols like [TCP] is unnecessary. And definitely not normative - this sentence is informatively comparing this draft with a TCP-based alternative. s/an URI/a URI/ (unless we're meant to pronounce URI like Cockney "In an 'urry luv?" :) Para 1: "To allow negotiation..." Para 3: "To initiate an IP tunnel..." I think these two paras repeat each other. But para 3 is better: a) initiate is a better word than negotiate (AFAICT there is no negotiation), and b) it explains that it's a /single/ HTTP stream. "IPv6 scoped addressing zone identifiers..." ref? [RFC6874]? Using 'IP Protocol' rather than 'Next Header' as the keyword within an IP Address Range is rather politically incorrect for IPv6 zealots, isn't it? :) Is 'equal than' (2 occurrences) correct in US English? It's certainly not in British. I can't find any reference to it. s/since receiving addresses and routes is/ /since receipt of addresses and routes is/ "When an endpoint receives an HTTP Datagram containing an IP packet, it..." a tunnel endpoint? MTU sometimes ought to be PMTU. "HTTP Datagrams with payloads of at least 1280 bytes" Fig 13 potentially labels two things as HTTP Datagram Payload. Which is meant here? I assume the inner one, but it needs to be clear. "URL endpoints can pad the QUIC INITIAL packets of the underlying QUIC connection that IP proxying is running over. (Assuming QUIC version 1 is in use,..." The parenthesis needs to be tagged as an example. In the format defined in §1.3 of [QUIC] and used in the examples, a value after '=' is normally numeric. the following format threw me: Payload = Encapsulated IP Packet I thought that must imply a field announcing that the type of the payload is the string "Encapsulated IP Packet". Any chance this could be bracketed off somehow, e.g. Payload = Is there any precedent in RFC9000 for an unquoted/unbracketed description of a binary blob on the RHS of '='? "The IP proxy assigns the client both an IPv4 address (192.0.2.3) and an IPv6 address (2001:db8:1234::a) to the client." Delete first occurrence of 'the client'. s/IP proxies SHOULD restrict its use to authenticated users./ /IP proxies SHOULD restrict their use to authorized users./ Reason: as well as the incorrect singular, following the literal rule as originally written would give access to authentic criminals. There's a few places in the IANA section where editor's marks might be useful to identify text that will need to be updated once approved. Cheers Bob

HTTP Extended CONNECT as described in EXT-CONNECT2 and EXT-CONNECT3. When using HTTP/1.x H1, it uses HTTP Upgrade as defined in HTTP.  <ins> This document updates CONNECT-UDP to change the "masque" well-known URI, see iana-uri. </ins> 2.


protocol is similar to UDP proxying in HTTP, but allows transmitting arbitrary IP packets.  More specifically, this document defines a protocol that allows an HTTP client to create an IP tunnel through an <del> HTTP server that acts as a proxy.  This document updates RFC 9298. </del>  1. start the Capsule Protocol; see HTTP-DGRAM. If any of these requirements are not met, the client MUST treat this <del> proxying attempt as failed and abort the connection. </del>  For example, the IP proxy could respond with:

In the abstract, the word 'proxy' is used without qualification. It would be better to use the term 'IP proxy'. In 4.3. HTTP/1.1 Response, 'abort the connection' is not typical usage (e.g., in RFC9112); suggest 'close the connection'.

protocol is similar to UDP proxying in HTTP, but allows transmitting arbitrary IP packets.  More specifically, this document defines a protocol that allows an HTTP client to create an IP tunnel through an  <ins> HTTP server that acts as an IP proxy.  This document updates RFC 9298. </ins> 1. start the Capsule Protocol; see HTTP-DGRAM. If any of these requirements are not met, the client MUST treat this  <ins> proxying attempt as failed and close the connection. </ins> For example, the IP proxy could respond with:


field has value 6, the IP Address field SHALL have a length of 128 bits. <del> Length of the IP Prefix assigned, in bits.  MUST be lesser or equal to the length of the IP Address field, in bits. </del>  3.2.2. the IP Version field has value 6, the IP Address field SHALL have a length of 128 bits. <del> Length of the IP Prefix of the advertised route, in bits.  MUST be lesser or equal to the length of the IP Address field, in bits. </del>  The Internet Protocol Number for traffic that can be sent to this prefix.  If the value is 0, all protocols are allowed.

NAME NAME Does this PR also ?
NAME not quite--it's a step, but there's more to do
I think the field description needs updates. The IP adress is after all an prefix that is masked by the specified number of bits. That is not quite clear yet. However, I think the question if this range should support excluding one or more sub-ranges needs to be sorted out also.
The specification of the field currently states . Is that unclear? If so, can you help provide text to help make it clearer? Agreed, that's discussed in
Editorial clarification that the prefix in the advertisement applies to the address in the advertisement, which is a remote prefix that the client is allowed to send to.

field has value 6, the IP Address field SHALL have a length of 128 bits.  <ins> The number of bits in the IP Address that are used to define the prefix that is being assigned.  This MUST be less than or equal to the length of the IP Address field, in bits.  If the prefix length is equal to the length of the IP Address, the endpoint is only allowed to send packets from a single source address.  If the prefix length is less than the length of the IP address, the endpoint is allowed to send packets from any source address that falls within the prefix. </ins> 3.2.2. the IP Version field has value 6, the IP Address field SHALL have a length of 128 bits.  <ins> The number of bits in the IP Address that are used to define the prefix of the advertised route.  This MUST be lesser or equal to the length of the IP Address field, in bits.  If the prefix length is equal to the length of the IP Address, this route only allows sending packets to a single destination address.  If the prefix length is less than the length of the IP address, this route allows sending packets to any destination address that falls within the prefix. </ins> The Internet Protocol Number for traffic that can be sent to this prefix.  If the value is 0, all protocols are allowed.


Upon receiving the ROUTE_ADVERTISEMENT capsule, an endpoint MAY start routing IP packets in that prefix to its peer.  4. IP packets are sent using HTTP Datagrams I-D.ietf-masque-h3-datagram.

The current version of the draft contains the ROUTEADVERTISEMENT capsule but is missing the ROUTEREJECTION capsule. It's very common for networks to want to advertise routes such as "I can handle all of IPv4 space minus RFC 1918 space" and that becomes incredibly painful if you don't have a way to subtract prefixes. An alternate solution is to use an address start/address end encoding like , but if we want to use a prefix-based encoding we need a way to cut out holes from prefixes.
Oh, is that what the rejection capsule was for? I guess I'd just rather have the route advertisement itself provide a list of exceptions, rather than tying it to a separate capsule?
Yes, that would also work. This is just a matter of encoding.
The nice thing about the rejection capsule is it allows you to remove announcements that were previous present without having to re-send a full routing table. I would prefer keeping it, as it allows for more efficient transmission of information. (I disagree it's just a matter of encoding.)
Actually sending a full routing table seems like the safer way to go. And given you don’t do that very often, I don’t think we need to worry about overhead.
I will disagree with my co-author. I think the basic case for what in most cases are the equivalent to the default route for a host on a LAN segment would be good to have in a reasonable compact form. I think the question to ask here is if we in general need a mechanism to specify an IP prefix with one or more carved out sub-prefixes. I that requirement may apply to both advertising and rejecting/removing a prefix. In the removing maybe it is possible to specify the whole prefix without carve out sub-prefixes.
Maybe call with ROUTE_WITHDRAW instead of reject
ROUTE_WITHDRAW sounds good to me.

Upon receiving the ROUTE_ADVERTISEMENT capsule, an endpoint MAY start routing IP packets in that prefix to its peer. <ins> 3.2.4. The ROUTE_WITHDRAWAL capsule allows an endpoint to communicate to its peer that it is not willing to route traffic to a given prefix.  This capsule uses a Capsule Type of 0xfff103.  Its value uses the following format: IP Version of this route withdrawal.  MUST be either 4 or 6. IP address of the withdrawn route.  If the IP Version field has value 4, the IP Address field SHALL have a length of 32 bits.  If the IP Version field has value 6, the IP Address field SHALL have a length of 128 bits. The number of bits in the IP Address that are used to define the prefix of the withdrawn route.  This MUST be lesser or equal to the length of the IP Address field, in bits. The Internet Protocol Number for traffic for this route.  If the value is 0, all protocols are withdrawn for this prefix. Upon receiving the ROUTE_WITHDRAWAL capsule, an endpoint MUST stop routing IP packets in that prefix to its peer.  Note that this capsule can be reordered with DATAGRAM frames, and therefore an endpoint that receives packets for routes it has rejected MUST NOT treat that as an error. </ins> 4. IP packets are sent using HTTP Datagrams I-D.ietf-masque-h3-datagram.