Question: Section 9.1.  The "mid" value MUST match that specified in the offer. <ins> An "a=rtcp" line, as specified in RFC3605, Section 2.1, containing the dummy value "9 IN IP6 ::", because no candidates have yet been gathered. </ins> If a local MediaStreamTrack has been associated, an "a=msid" line, as specified in I-D.ietf-mmusic-msid, Section 2.

lgtm
I think the dummy candidates should be v4 not v6 as many things just don't do v6 but other than that looks reasonable. You don't really need to specify the address at all the the lines when you don't know the port can just look like a=rtcp:9 With no IP address or family
NAME The IP6 vs IP4 is described in URL, so this isn't a JSEP thing. Given that this is part of the trickle spec, and only trickle endpoints will get these candidates, I don't see any problem. As to whether a=rtcp can just have the port, consider the case where RTP candidates have been gathered, but no RTCP candidates have yet been gathered. In that case, we certainly need to have the full a=rtcp:9 IP6 ::, so I think it makes sense to include it in all cases where RTCP candidates have not yet been gathered.
I don't care much about this so fine if not change is made. I agree it is a trickle-ice draft issue. However, when I read that, it seems that it would be fine with "a=rtcp:9" with no address. It seems the reason we used 9 was to provide something that stuff that did not implement trickle ICE would not barf on. I have no tested but an address of "IP6 ::" seems like something that has high odds of stuff barfing on. Anyways, no big deal with me one way or the other. On Sep 12, 2014, at 7:49 PM, Justin Uberti EMAIL wrote:
Only trickle endpoints will even receive an offer with these dummy addresses and ports, so compatibility with old non-trickle stuff is not an issue. LMK if you have any further concerns, otherwise I will merge later today.
I concur that we should merge this. , Justin Uberti EMAIL wrote:
On Sep 18, 2014, at 9:34 AM, Justin Uberti EMAIL wrote: ah - my bad - makes sense Merge it !


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

NAME let's discuss that on . I'd like to merge this PR first then decide on a plan for before submitting the next revision to the datatracker
Splitting {ADDRESSREQUESTROUTEADVERTISEMENT} into ...V4 and ..._V6 would result in smaller capsules that have fewer error conditions. It would also keep IPv4 and IPv6 logic distinct.
I don't think the size of these capsules matters given their rarity. I can see the error condition argument but it's pretty minor and would come at the cost of making the specification longer. I don't feel too strongly here, but I think I have a slight preference for keeping things as they are.
I agree with David that size is problem not a big concern. I think having one set of capsule is less complex.
I also have a preference for keeping the capsules as they are with versions included; it also allows the route advertisement capsule to include routes for both v4 and v6 in one capsule, which I think is very important. I wouldn't want to lose that feature.
I similarly have a preference for keeping v4 and v6 in one capsule and agree size is not a big concern.
I just chatted with NAME to see what error conditions he was thinking of. Upon discussion (v6 route advertised when only v4 address is available), we concluded that this is not an error case, it's just a route that's not yet usable. We've concluded that this is something that we're comfortable leaving as-is.
Implementing this on the client I was wondering if there should be a way for the client to ask for the server for an address without specifying what address it wants. This could allow a VPN client to mention that it wants an IPv6 address or not. If we think this could be useful, we could encode it as or .
I believe asking for the Any address is what we discussed previously, so +1
You mean ADDRESS_REQUEST(IPv4-0.0.0.0/32) don't you. I think the format of the request works fine. But we do need to before we implement this into the specification.
Yes — if we have this, one option is to always have an ADDRESS_REQUEST expected from clients, and then there doesn't need to be signaling. Or we do the simple solution to 54 to say "I expect to send N capsules with my request".


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

You're right this could be a potential solution to . Let's discuss them together tomorrow
Regarding IPv6, I think a standard request that would make sense is asking for any /64. I guess that works fine with this idea too?
Oh that's interesting, if the IP Address is or , the prefix length is a hint for the requested length. I like that.
IETF 114: Add an editorial sentence to "remember, what you ask for may not be what you get, especially with regards to address families". A request should be paired with a response, multiple requests can just say "you have the same ones you had before". Clarify that it's cumulative. Also solves unassign/removal of addresses.
So there appear to exist some downside with the timing of the interactions when one want to use Address-Request capsule. So the basic problem is simply that the proxy will assign an address prior to the Address-Request capsule has been received, thus preventing the proxy from processing the request in the right context. So lets assume that the client has already created one connect-IP request with a limited scope and been assigned IP-A. Then it want to make an additional request for another limited scope proxying and would like to get the same address assigned. Due to the separation between the HTTP request for the Connect-IP and the capsule Address-Request a server can actually process the whole HTTP request prior to receiving the Address-Request. Resulting potentially in that another IP address assignment (IP-B) be provided to the client, despite it asking for IP-A to be assigned also to the request. So does the HTTP request needs an indicator parameter to tell the proxy to wait for one or more "request" capsules from the client before processing the request?
Out of curiosity, in what scenario would the client "like to get the same address assigned"? It makes sense for the proxy to decide to reuse addresses to save its address pool when the scoping allows it, but why would the client care?
I could imagine this happening if the client was trying to resume some previous session that it lost due to an outage? Seems to be niche, but it's certainly possible.
So the most obvious use case for this is to request iproto= CMP in combination with for example UDP.


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

Then getting ICMP for another IP address then the one you already have UDP for is mostly useless if you intended to use the ICMP messages for hints when things fails for you UDP based protocol. I would note that for an endpoint liking to do P2P NAT traversal stuff getting an IP address rather than using Connect-UDP does make sense as it ensure the client has control. It enables the IP address for its UDP traffic to be Endpoint-Independent Mapping (RFC4787). This might be niche usages but I would like to avoid creating artificial barriers that makes things impossible or at least hard to realise.
Thanks, this makes sense. Should we suggest that clients bundle the ADDRESS_REQUEST in the same packet as the HTTP headers and suggest that servers check for those before responding?
I am still worried that this creates issues as your request may not fit in a single packet to begin with. My solution would be to actually move the address request part into the HTTP request itself as header field. That would ensure an atomic operation and no risk for errors.
Magnus, is your proposal to require, or to allow as an option, for the address request to be moved into the HTTP request? Why not bundle the capsules over a reliable delivery mechanism instead?
I first of all want to ensure that you can do a request that ensures that for those cases when it is necessary to interpret the Connect-IP request in the context of desired IP address it can done. Without uncertainties or requiring to have wait time to see if there are capsules incoming. So I think primarily allow as an option. I think a question back to your usages, do you have cases where one would need additional capsules to correctly interpret the option. Should we look for an other solution than the one I proposed to better cover the necessary functionality?
I want to be able to continue to do ADDRESS_ASSIGN capsules during the lifetime of the connection to support e.g., IPv6 Privacy extensions but without having to delegate the entire subnet. So I don't want to move to header-only.
I think NAME is describing something similar to the / capsules that we had in the original Google . The only difference is that we would add an HTTP header to say "start off in atomic mode and wait for atomic end before sending addresses and such". While I think this does sound useful, does it need to be in the core spec or could it be an extension?


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

Is there any reason to not bring back the capsules?
The only reason I can think of is to keep the core spec as short and simple as possible. But if we think this is an important feature then I'm not opposed to bringing back .
I agree with the sentiment of keeping the core spec short and simple, but the trade-off is also knowing what the minimum viable featureset we can always rely on is. If we conclude that capsules are in that set, that IMHO weighs towards including them. Given that both Magnus and I have now presented use-cases for atomicity, I think this finally swings towards including?
I agree with that
So why I used atomic here, was due to the split between HTTP and Capsules. So I don't see this issue currently motivates the need for ATOMIC capsules. I really would prefer that the necessary parameters for the CONNECT-IP request are in the HTTP request, either in the URI or in an HTTP field. To be clear, I understand the need for the capsules as they are useful for doing things after the initial request, but creating this binding between the HTTP request and the capsules are creating its sets of complexities. Likely bigger than duplicating the carrying of the necessary information results in, especially when they may be use cases related.
I agree I with Magnus and think we should specify a ay to add the address request to the http request. If there is a timing dependency it's better to put all needed information into the same request than specifying extra and complex logic to achieve the same in hindsight. That doesn't mean that we don't need the address request capsule (for later use in the connection). I think we need both.
I dislike having two ways of conveying the same thing. How about a simple HTTP header that tells the receiver that there are 4 capsules coming right after the HTTP headers?
I'd prefer to avoid "atomic capsule" starts and ends. If we need a way to guarantee inclusion of the local address in the first request, having it be in the HTTP request makes sense, either as another URI parameter, a header to say what address you want, or a header to say you will have capsules that need to be parsed before responding. That latter option is flexible, certainly, but could be over-engineered. Another option is to tightly scope a header to the use case we think is relevant.


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

If the use case is "please use the same address as this other request stream I already have for connect-ip or connect-UDP", we could just have a header to say for any connect- request that it is entangled with another and should share some properties. I could imagine this even without CONNECT-IP. Today with private relay, we have to ask the proxies to prefer to use the same local IP for everything in a connection from the client, but letting the client choose what gets grouped might be even nicer. This option also lets you issue multiple requests, say they should share, without needing to know exactly which IP any of them will get assigned first.
Unfortunately requests and headers are end-to-end but streams are hop-by-hop so there is no easy HTTP way to have a request refer to another request. I'd be supportive of adding the header but I'd push back on adding a header that duplicates a capsule. This is starting to feel like something best-served by an extension
You could solve the correlation by having a "group" ID that you attach to all related requests. No need to refer by stream ID.
What is the scope of a group ID? Connection? If so it's the same as stream IDs.
I think this should be some extension, but it could be a UUID too, doesn't need to be connection specific.
Ah, thanks. Yeah UUID would work. Back to the issue at hand, I propose this feature request get moved to an extension.
All of these alternatives strike me as much more complex that the semantics of . I'd rather we have a single mechanism even if it's slightly more powerful and restrain it's use than try to invent new ways to solve each problem that arises.
Atomic doesn't help coordinate between requests on different streams, etc, so it's not really solving the full problem here. Either way, I think this is something to defer to an extension.
Headers don't solve that problem either, so I'm not sure that argument really makes sense in this context. Cross stream coordination seems out of scope to me.
So you are taking this into directions I did not intended. I am just asking for how to ensure that the server does not answers the client's request prior to having received any capsules if they are coming.


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

And the real issue is that the server can't know unless the client either includes the corresponding data in the HTTP request or includes an indication that there will be capsules that are relevant to the requests. So, my main worry is if waiting for capsule to answer will actually work if there are an HTTP 1.x intermediary connection on the path between the client and the server. I guess its is sending the capsule after the request and hope it makes it. Because to my understanding in HTTP datagram the peer does not expect any data to arrive so it must be upgraded. Thus, one can end up in cases where the capsule protocol does not make it, where the HTTP request does arrive.
While we might want to have a more generic extension to relate information to multiple requests, I think the problem Magnus describes needs a solution now. The problem is that there is a dependency between replying/react to a connect request and potentially information send in capsules. The best solution is to send this information together with the connection request instead. I don't see any concern to have a http request or URI parameter and the capsule. What's the problem about that?
Magnus, what is "the client's request" here? Is it the extended-connect itself, or a response to a capsule? If it's the former, the server can't know what capsules, if any, are coming at this time, as we haven't yet established we are using the capsule protocol. If it's the latter, capsules trivially solve this, as you cannot process any of the requests until the capsule is received. Mirja, I'd like to avoid having 2 ways to do things, especially since putting it on the HTTP request is a less-generic mechanism and cannot be reused during the connection, whereas capsules can. If we believe this feature is important, I'd like us to solve it generically, rather than special-casing one use case we are aware of right now.
So the client's request is the HTTP request that is only complete in semantics when combined with the request-address capsule.
Sorry Magnus, I'm not sure I understand what you're trying to say. I don't think we can enforce a semantic that a higher-level HTTP request is only complete after some bytes on the then-negotiated protocol have been exchanged.


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

But this is really the issue, there is currently no way for a client to ask the server to only provide a targeted connect-IP forwarding if the IP address it can provide is the one the client asks for in a consistent way. My interpretation of the specification is that either; 1) the server will never take the request-addr into account initially for the request, and interpret the request-addr after it has created a Connect-IP forwarding 2) the server will sometime take the request-addr into account by have a short delay awaiting for the request-addr capsule, which may or may not make it in time for the implementation specific timer. This non-consistency or failure to address a use case that I think several was interested in resolving is a real problem. A problem I think we will have to take with us to the meeting.
This ultimately stems from us not having an explicit capsule/message to indicate that forwarding should actually begin. Right now it's implicit as soon as the capsule is assembled with the IP addressing information. This is leading to your proposal to stick more things onto the initial request, whereas I believe the correct solution is to add more capabilities to the capsule protocol to express these scenarios.
I will consider what you are saying. However, I will note that we might have different goals. I do have a need for identifiable streams that can be referred to in extension signalling. Using capsules does not achieve that with the current design as the stream identifier comes from the HTTP request, not the subsequent capsule signalling.
I hope so, constructive discussion relies on all of us considering what the others are saying Given that we're all trying to solve slightly different problems here, I see two outcomes: we have one simple generic solution that happens to work for everyone we punt this to more specific extensions since these problems are not generic
So I think the issue here is what we consider core functionality. My observation here is that Alex is promoting functionality that will make it easy to make quite rich things for the network tunnelling use case that you are promoting. While I am bringing up something that to me appear core for the single endpoint tunnelling. So I think we actually need to understand the issues as well as what usage and how usable this is in common and how to handle where the different use cases actually benefits from having the functionality in different places.


Question: IANA is requested to update the "Reference" field to include this document in addition to previous values from that field. <del> 10.3. </del> <ins> 11.3. </ins> This document will request IANA to add the following values to the "HTTP Capsule Types" registry created by HTTP-DGRAM:

I'll reiterate my suggestion from the meeting: it would be better to have IP-version-specific capsule types for each capsule. It saves a byte and also avoids problems with version mismatches.Thanks! I left 2 minor editorial questions, but feel free to merge as-is.


Question: Packets containing only ACK frames are not congestion controlled, so there are limits on how frequently they can be sent.  An endpoint MUST NOT send more than one ACK-frame-only packet in response to <del> receiving an ack-eliciting packet (one containing frames other than ACK and/or PADDING).  An endpoint MUST NOT send a packet containing only an ACK frame in response to a non-ack-eliciting packet (one containing only ACK and/or PADDING frames), even if there are packet gaps which precede the received packet.  Limiting ACK frames avoids an infinite feedback loop of acknowledgements, which could prevent the connection from ever becoming idle.  However, the endpoint acknowledges non-ack-eliciting packets when it sends an ACK frame. </del> <ins> receiving an ack-eliciting packet.  An endpoint MUST NOT send a non- ack-eliciting packet in response to a non-ack-eliciting packet, even if there are packet gaps which precede the received packet.  Limiting ACK frames avoids an infinite feedback loop of acknowledgements, which could prevent the connection from ever becoming idle.  However, the endpoint acknowledges non-ACK-eliciting packets when it sends an ACK frame. </ins> An endpoint SHOULD treat receipt of an acknowledgment for a packet it did not send as a connection error of type PROTOCOL_VIOLATION, if it

Fixing
changed the rules regarding what kind of packet an endpoint is allowed to send after receiving a non-ack-eliciting packet. The intention of that text used to be to prevent peers from getting stuck in an ACK-loop, but now the text says: Among others, this means that once an endpoint receives a non-ack-eliciting packet, it's not allowed to send a packet containing only PADDING. This would be valuable for defeating traffic analysis. While it would be possible to hack your way out of this by sending a PING + PADDING packet, I'm not sure if this was the intention of .
To me, the key phrase here is 'in response to'. If you want to send PADDING for some other reason and the congestion controller allows it, then you can send it.
This feels editorial...
I don't intend to do anything about this one. As Ian notes, you can use other reasons to justify sending of anything, just don't justify the sending on the basis of having received a non-ack-eliciting packet or you will get into the sort trouble that doesn't end.
I think the text is clear that sending PADDING is allowed at any time. I'm closing this with no action.
quic-transport draft 13.2.1: An endpoint MUST NOT send a packet containing only an ACK frame in response to a non-ACK-eliciting packet (one containing only ACK and/or PADDING frames), NAME points out that this allows one to send an ACK+PADDING packet, which seems to violate the spirit of the rule. This loophole breaks . I believe this may be Editorial if we all know what we meant.
Yes, it was intended that ACK should not elicit an ACK+PADDING packet.
I agree with this change, but I disagree that this is a satisfactory fix for .
This issue should have been
LGTM. Though all the "non-ACK-eliciting packets" is a bit of a mouth full.


Question: For example, the IP proxy could respond with: <del> 4.5. </del> <ins> 4.6. </ins> Unlike UDP proxying requests, which require specifying a target host, IP proxying requests can allow endpoints to send arbitrary IP packets

I'll just use a single example here because I think it makes it easier to express my point but the problems might be wider The URI template may include a variable, which is later defined in URL as . The value can only be between 0 through 255, I presume this is a decimal value. What is expected to happen if I send some bad values like: I presume that the recipient would reject the request with a bad path, by virtue of applying the requirement in section 4 that :path SHALL NOT be empty and following the expansion requirements in Section 3 and following those requirements on to Section 4.5. That's a lot of hops to get things right. Is there any easier way to present these?
Agreed, we need better text to specify server handling. For example, we don't currently explicitly that the server has to percent-decode these variables (but we say they have to be percent-encoded). When we add new text about how to extract the variables and decode them, let's also say that the server has to validate that they match requirements and has treat the request as malformed if they don't
NAME can you write up some text?
Appear to look good.


Question: 2.1. <del> A quota policy is described in terms of service-limit and a time- window.  It is an Item whose bare item is a service-limit, along with associated Parameters. </del> <ins> A quota policy is maintained by a server to limit the activity (counted in quota units) of a given client over a period of time (known as the time-window) to a specified amount (known as the service-limit). </ins> <del> The following parameters are defined in this specification: </del> <ins> Quota policies can be advertised by servers (see ratelimit-policy- field), but they are not required to be, and more than one quota policy can affect a given request from a client to a server. </ins> <del> The REQUIRED "w" parameter value conveys a time window value as defined in time-window. Other parameters are allowed and can be regarded as comments.  They ought to be registered within the "Hypertext Transfer Protocol (HTTP) RateLimit Parameters Registry", as described in iana-ratelimit- </del> <ins> A quota policy is expressed in Structured Fields STRUCTURED-FIELDS as an Integer that indicates the service limit with associated </ins> parameters. <del> For example, a quota policy of 100 quota units per minute: The definition of a quota policy does not imply any specific distribution of quota units within the time window.  If applicable, these details can be conveyed as extension parameters. </del> <ins> The following Parameters are defined in this specification: </ins> <del> For example, two quota policies containing further details via extension parameters: </del> <ins> The REQUIRED "w" parameter value conveys a time window (time- window). </ins> <del> To avoid clashes, implementers SHOULD prefix unregistered parameters with a vendor identifier, e.g. "acme-policy", "acme-burst".  While it is useful to define a clear syntax and semantics even for custom parameters, it is important to note that user agents are not required to process quota policy information. </del> <ins> For example, a quota policy of 100 quota units per minute is expressed as: </ins> <del> 2.2. </del> <ins> Other parameters are allowed and can be regarded as comments. Parameters for use by more than one implementation or service ought to be registered within the "Hypertext Transfer Protocol (HTTP) RateLimit Parameters Registry", as described in iana-ratelimit- parameters. </ins> <del> Rate limit policies limit the number of acceptable requests within a given time interval, known as a time window. </del> <ins> Implementation- or service-specific parameters SHOULD be prefixed parameters with a vendor identifier, e.g. "acme-policy", "acme- burst". </ins> <del> The time window is a non-negative Integer value expressing that interval in seconds, similar to the "delay-seconds" rule defined in Section 10.2.3 of HTTP.  Subsecond precision is not supported. </del> <ins> 2.2. </ins> <del> 2.3. </del> <ins> The service limit is a non-negative Integer indicating the maximum amount of activity that the server is willing to accept from what it identifies as the client (e.g., based upon originating IP or user authentication) during a time-window. </ins> <del> The service limit is associated with the maximum number of requests that the server is willing to accept from one or more clients on a given basis (originating IP, authenticated user, geographical, ..) during a time-window. </del> <ins> The activity being limited is usually the HTTP requests made by the client; for example "you can make 100 requests per minute".  However, a server might only rate limit some requests (based upon URI, method, user identity, etc.), and it might weigh requests differently. Therefore, quota policies are defined in terms of "quota units". Servers SHOULD document how they count quota units. </ins> <del> The service limit is a non-negative Integer expressed in quota units. </del> <ins> For example, a server could count requests like "/books/{id}" once, but count search requests like "/books?author=WuMing" twice.  This might result in the following counters: </ins> <del> The service limit SHOULD match the maximum number of acceptable requests.  However, the service limit MAY differ from the total number of acceptable requests when weight mechanisms, bursts, or other server policies are implemented. </del> <ins> Often, the service limit advertised will match the server's actual limit.  However, it MAY differ when weight mechanisms, bursts, or other server policies are implemented.  In that case the difference SHOULD be communicated using an extension or documented separately. </ins> <del> If the service limit does not match the maximum number of acceptable requests the relation with that SHOULD be communicated out-of-band. </del> <ins> 2.3. </ins> <del> Example: A server could </del> <ins> Quota policies limit the number of acceptable requests within a given time interval, known as a time window. </ins> <del> count once requests like "/books/{id}" </del> <ins> The time window is a non-negative Integer value expressing that interval in seconds, similar to the "delay-seconds" rule defined in Section 10.2.3 of HTTP.  Subsecond precision is not supported. </ins> <del> count twice search requests like "/books?author=WuMing" </del> <ins> By default, a quota policy does not constrain the distribution of quota units within the time window.  If necessary, these details can be conveyed as extension parameters. </ins> <del> so that we have the following counters </del> <ins> For example, two quota policies containing further details via extension parameters: </ins> 3.

Section 2.2: Section 2.3: This appears to be a circular definition -- what's actually being defined here?
(noting that 2.2 doesn't actually define quota-units)
Quota unit is now defined as the measurement unit for service limits.
PTAL - I tried to rearrange to address this a bit more holistically.
Looks good!LGTM


Question: Pass AD_1 to the security application. <del> If any verification step fails, the Responder MUST send an EDHOC error message back, formatted as defined in error, and the protocol MUST be discontinued. </del> <ins> If any processing step fails, the Responder SHOULD send an EDHOC error message back, formatted as defined in error, and the session MUST be discontinued.  Sending error messages is essential for debugging but MAY e.g. be skipped due to denial of service reasons, see security. </ins> 5.4.

Looks good.
The current draft has the following text in several places: "If any verification step fails, the Responder MUST send an EDHOC error message back, formatted as defined in {{error}}, and the protocol MUST be discontinued." I am not sure this is a good idea. This means that the availability of EDHOC will be low. An attacker can e.g. send a single byte as message_4 and it would make EDHOC shut down imidiatly. I think we need to soften this and give the implementation some more choice here. Are there constrained radio protocols where noice could be mistaken for an actual message and forwarded to EDHOC or do all constrained radio have strong enough CRC to make sure that that more or less never happens?
I just changed the following text OLD: If the Initiator previously received from the Responder an error message with error code 1 (see Section 6.3) indicating cipher suites supported by the Responder which also are supported by the Initiator, then the Initiator SHALL select the most preferred cipher suite of those. NEW: If the Initiator previously received from the Responder an error message with error code 1 (see Section 6.3) indicating cipher suites supported by the Responder which also are supported by the Initiator, then the Initiator SHOULD select the most preferred cipher suite of those (note that error messages are not authenticated and may be forged). Made me think about that I don't think the group has discussed if some error messages should be authenticated. Some error messages to message2 could include a MAC to prove that the error was sent by the same party that sent message3. error messages to message3 and message4 could be authenticated. I am uncertain if this is worth specifying. At least not as long as there are easier ways to an attacker to end the protocol. I think what needs to be done is to specify that a processing error does not need to discontinue the protocol, the received message can have been an attack. receiveing an error does not need to discontinue the protocol, the received error can have been an attack.


Question: Pass AD_1 to the security application. <del> If any verification step fails, the Responder MUST send an EDHOC error message back, formatted as defined in error, and the protocol MUST be discontinued. </del> <ins> If any processing step fails, the Responder SHOULD send an EDHOC error message back, formatted as defined in error, and the session MUST be discontinued.  Sending error messages is essential for debugging but MAY e.g. be skipped due to denial of service reasons, see security. </ins> 5.4.

from 20210422 interim: CB perhaps wisely said: "Use cases exist for multiplexing over same port/URI, so applications should normally sort/demultiplex traffic before start interpreting as EDHOC, which implies treating invalid messages that get to EDHOC code as an error or attack"
Yes, my understanding is that we only need to be concerned about attacks where an attacker sends a packet crafted so that it will be processed by EDHOC (which is not hard).
I made a pull request addressing this issue Added text on demultiplexing. Changed procession so implementation are not mandated to shut down the session if an attacker sends a few bytes to the EDHOC resource / port.. Added more security consideration on Denial of service.
Writing this PR made me think about whether we want to mandate that error messages are always fatal as well as downgrade protection. The ""Wrong selected cipher suite" error is fatal because it is sent in repsponse to message1. You could consider similar types of error sent in response to message2 and message3. E.g. IDCRED format not supported or CRED format not supported or X.509 public key algorithm not supported. [BBFGKZ16] defines the following theoretical downgrade protection for a session: The cryptographic parameters should be the same on both sides and should be the same as if the peers had been communicating in the absence of an attack. But this definition has very little to do with practical security. In practice it does not matter if an attacker can influence the chosen parameter in the current session or a following session. I am still confused regarding the purpose of the applicability statement. Is it a informal section describing things the parties need to both support to make the protocol work or is a normative security section relevant for policy and downgrade. If we want downgrade protection over multiple sessions, the parties need to agree or securely negotiate everything. Downgrade protection for a session does not make much sense to me if an attacker can force the parties to set up a second session with lower security.
Do we need to align the terminology, we use both "session" and "instance" in the draft?
Yes, I just changed "protocol" to "session" not remembering that the draft use instance in other places.
We can resolve this later, I opened . Unless there are other comments we will soon merge this.
The PR has been discussed and merged.


Question: Pass AD_1 to the security application. <del> If any verification step fails, the Responder MUST send an EDHOC error message back, formatted as defined in error, and the protocol MUST be discontinued. </del> <ins> If any processing step fails, the Responder SHOULD send an EDHOC error message back, formatted as defined in error, and the session MUST be discontinued.  Sending error messages is essential for debugging but MAY e.g. be skipped due to denial of service reasons, see security. </ins> 5.4.

Closing
Current specification mandates sending error messages upon certain failures. But in cases when message processing fails when no state has been allocated or when no connection identifier has been found or then a more appropriate action would be to just silently drop the message.
I think the MUST (if possible) is good. Debugging without any error messages is not nice. We now other protocols that it is good to mandate error messages. It is kind of obvious that can not send an error if you don't now where/how to send it. Don't know if that has to be pointed out....
Migth be good to not sent error if you are under a DoS attack.
This issue is addressed by pull request that also address availability
The PR has been discussed and merged. Closing


Question: or preferably send coded packets instead of the following packets in the send buffer. <del> The advantage of this solution is that it does not contribute in adding more congestion than the congestion window allows.  Indeed, all traffic (source and redundancy) is controlled by one congestion control only and TCP metrics for fairness can be indifferently applied in this case. </del> <ins> The advantage of this solution is that it does not add more traffic than the congestion window allows.  Indeed, all traffic (source and redundancy) is controlled by one congestion control only and TCP metrics for fairness can be indifferently applied in this case. </ins> The main drawback is the decrease of goodput if coded packets are sent but are not used at the client side. 6. <del> Delay-based congestion controls ignore packets that have been repaired with coding.  There is no need to define best current </del> <ins> [MICHAEL: I would remove this section entirely: it only adds to confusion.  If the inputs are seen as distinct, and we say that the raw inputs shouldn't be shared, then why would one even think about what delay-based CC does with this input?  It's just not the right input.]  Delay-based congestion controls ignore packets that have been repaired with coding.  There is no need to define best current </ins> pratices in this case.  However, more discussions are required for congestion controls that use loss as congestion signals (potentially among other congestion detection mechanism). 6.1. <del> In this solution, the server reacts to repaired packet signals as to congestion-implied packet losses.  That being said, this does not necessarily means that the packets have actually been lost.  The server may have other means to identify that the packet was just out- of-ordered and ignore the repaired packet signals. </del> <ins> [MICHAEL: As above, lets remove all of this please.  This text gets in the way of a clean separation.]  In this solution, the server reacts to repaired packet signals as to congestion-implied packet losses.  That being said, this does not necessarily mean that the packets have actually been lost.  The server may have other means to identify that the packet was just out-of-order and ignore the repaired packet signals. </ins> The advantages of the solution are (1) that coding mechanisms do not hide congestion signals, such as packets voluntary dropped by a AQM <del> RFC7567 and (2) packets may be repaired faster than with traditionnal retransmission mechanisms. </del> <ins> RFC7567 and (2) packets may be repaired faster than with a traditional retransmission mechanisms. </ins> The drawback of this solution is that, if there is a high non- congestion loss rate, the congestion control throughput may decrease

This proposes a complete re-vamp of the document. I would also suggest to completely remove sections 6 and 7, but rather than doing this yet, I inserted comments that explain why.
Le 17/01/2020 à 09:28, mwelzl a écrit : Yes ! Definitely agree.
Le 17/01/2020 à 13:50, francoismichel a écrit : OK for me.


Question: 3. <del> Names are formed using Port-Prefix Naming (Section 2.3 of SVCB), with a scheme of "dns".  For example, SVCB records for a DNS service identified as ""dns1.example.com"" would be located at ""_dns.dns1.example.com"". </del> <ins> SVCB record names (i.e.  QNAMEs) are formed using Port-Prefix Naming (Section 2.3 of SVCB), with a scheme of "dns".  For example, SVCB records for a DNS service identified as ""dns1.example.com"" would be queried at ""_dns.dns1.example.com"". In some use cases, the name used for retrieving these DNS records is different from the server identity used to authenticate the secure transport.  To distinguish them, we use the following terms: Binding authority - The service name (Section 1.4 of SVCB) and optional port number used as input to Port-Prefix Naming. Authentication name - The name used for secure transport authentication.  It must be a DNS hostname or a literal IP address.  Unless otherwise specified, it is the service name from the binding authority. </ins> 3.1.

This should help with the case in DDR. See URL
Much better. Thanks for indulging me.


Question: scope for this document but can be implemented using CONNECT-IP extensions. <del> Since CONNECT-IP endpoints can proxy IP packets send by their peer, they SHOULD follow the guidance in BCP38 to help prevent denial of service attacks. </del> <ins> Falsifying IP source addresses in sent traffic has been common for denial of service attacks.  Implementations of this mechanism need to ensure that they do not facilitate such attacks.  In particular, there are scenarios where an endpoint knows that its peer is only allowed to send IP packets from a given prefix.  For example, that can happen through out of band configuration information, or when allowed prefixes are shared via ADDRESS_ASSIGN capsules.  In such scenarios, endpoints MUST follow the recommendations from BCP38 to prevent source address spoofing. </ins> 10.

Connect-IP enables the Masque client to set the source address for any IP packets it requests the MASQUE proxy to forward to the external network. This enables the potential for source address spoofing by the MASQUE client or an entity prior to it. For proxies that assign addresses to the client and allows general access to Internet I think it would be really good to recommend or require the masque server to perform source address validation. However, there clearly exist some use cases where the MASQUE will be used to establish a virtual path between two networks and where source address validation is hard as neither network may be stubs networks. However, I think there are several things to address in the document. 1) Include in security description a discussion of the risks here and when it would be useful to perform source address validation. Especially for the assigned address(es) use case where rejecting all but the provided address range would be possible. 2) Consider if the security risks for certain deployments are such that source address validation is RECOMMENDED or REQUIRED
I don't think this is correct. I thought there was text in the draft that enforced that the source address was in the set of addresses the endpoints agreed were routable. [4.2.1] ADDRESSASSIGN capsule says "Any of these addresses can be used as the source address on IP packets originated by the receiver of this capsule.". I suppose this means we need a clarification that a MASQUE proxy MUST drop any packets whose source address is not in the set of addresses agreed upon in ADDRESSASSIGN capsules.
I think we can write a PR that addresses this. Here's a rough shape of a paragraph: how does that sound?
+1 to this text.


Question: SHOULD be able to read longer connection IDs from other QUIC versions in order to properly form a version negotiation packet. <del> The Destination Connection ID field follows the DCID Length field and is between 0 and 20 bytes in length. negotiating-connection- ids describes the use of this field in more detail. </del> <ins> The Destination Connection ID field follows the Destination Connection ID Length field and is between 0 and 20 bytes in length.  negotiating-connection-ids describes the use of this field in more detail. </ins> The byte following the Destination Connection ID contains the length in bytes of the Source Connection ID field that follows it.

Editorial NiTs when reviewing the invariant text. These NiTs address readability issues, and do not intend to change the meaning of the text.
Is there an associated issue?
Thanks Gorry, these are all quite helpful. 1) I understand the acronyms DCID and SCID, but these aren't really expanded on first use in sect 5.1. 2) There's mention of "the high bit", but there doesn't seem to be any statement of bit order saying. Is it worth declaring network byte/bit order earlier in section 4? This also clarifies the placement of fields within a byte, which was basically assumed knowledge otherwise. 3) Personally, I don't think: "The length of the Destination Connection ID is not specified" is a great choice of words. Surely, this needs to be specified somewhere for a protocol instance to use it? This reads better as something like: The length of the Destination Connection ID is not encoded in packets with a short header and is not constrained by this specification. 4) The brackets here seem to point to connection IDs in general, not the DCID "(see Section 5.3)". Is it worth writing that as "Connection IDs are described in Section 5", rather than use brackets? The same is true for versions. 5) In section 5.3: "the wrong endpoint" is taken as the wrong transport endpoint, but some of our IP and subIP colleagues would use the term endpoint for other uses, so one insertion of "transport" would perhaps help? 6) In the appendix A, this: "QUIC forbids acknowledgments of packets" - still has me wondering what is actually intended to be understood, because the list of bullets is not guarenteed ... : /The last packet before a long period of quiescence might be assumed to contain an acknowledgment (it should be assumed that QUIC could allow acknowledgments of packets that only contain ACK frames)/ I'm not sure what to say here I think the combination of not... forbids threw me off the meaning. Changes proposed in
Thanks for changing SCID/DCID to "Source Connection ID" and "Destination Connection ID", that seems like a good change.


Question: However, all have an internal inconsistency or an unrecognized suffix key/ <del> value, so a recipient MUST treat the Internet Date/Time Format string as erroneous. </del> <ins> value, so a recipient MUST treat the IXDTF string as erroneous. </ins> Note that this does not mean that an application is disallowed to perform additional processing on elective suffix tags, e.g., asking

We need a name that people will use until they can say RFC9999 timestamps (and maybe even when they can).
"Extended Timestamps" or "Extended Internet Timestamps" ?
RFC 3339 says "Internet Date/Time Format". That is what sedate says at the moment as well, but that can't stay the same. So I'm considering moving to: Internet Date/Time Format Extended The alternative .... Extended Internet Date/Time Format sounds like a date/time format for the Extended Internet (EI is actually in use as "Extensible Internet", which this shouldn't be confused with). I'd rather call it Fritz, but I haven't found a way to retronym this...
Thanks


Question: The "version" and "ciphersuite" values in the Welcome MUST be the same as those used by the old group. <del> Each LeafNode in the new group's tree MUST be a leaf in the old group's tree at the epoch indicated in the PreSharedKey. </del> <ins> Each LeafNode in a new subgroup MUST match some LeafNode in the original group.  In this context, a pair of LeafNodes is said to "match" if the identifiers presented by their respective credentials are considered equivalent by the application. </ins> In addition, to avoid key re-use, the "psk_nonce" included in the "PreSharedKeyID" object MUST be a randomly sampled nonce of length

Based on , it should be made explicit that sub-group branching requires a fresh key package for each member. I think there is still a conflict of wording here that I would like feedback on because of this line (which is what triggered me thinking there was a bug)
Thanks for the PR and thanks for digging into this. I think what the sentence is meant to say is that the receiver MUST check that the members of the new group are a subset of the members of the old group at that specific epoch. Since we're using new LeafNodes in the new group and we don't have a fixed notion of identity (at least not within MLS), we have to refer to the application/the AS to ensure that the identity expressed by the credential in each LeafNode in the subgroup has a corresponding identity (i.e. one that represents the same party) expressed by a credential in a LeafNode in the original group. Maybe something like: This leaves the possibility of a collision, where the identifiers in a given leaf in the new group would be valid updates to more than one member in the old group. This should probably be forbidden in general, although outside of this case it's not really a problem, because updates are always specific to one leaf. Alternatively, we could somehow include LeafNodeRefs that specifically indicate which member represents which other member. Or just leave it up to the application to sort this all out.
Curious what you think about saying the the credential has to be equal? We can determine equality of the credential itself just by doing tls serialization.
Sure, requiring the credential to be exactly the same would be a simple way to figure out if it's the same party in both groups. However, I can imagine that some applications will want distinct credentials for each group. If we mandate that credentials are the same, this would force the application to use the same credential in every key package/LeafNode. Since subgroups can potentially be branched at any time and in any group, all key packages that a party publishes then have to have the same credential as all of the groups that party is in, so another party branching a subgroup can get hold of a KeyPackage with the same credential as the group the subgroup is branched off of. Personally, I'd prefer asking the application to check that the identities of the new group are a subset of the identities of the original group.


Question: The "version" and "ciphersuite" values in the Welcome MUST be the same as those used by the old group. <del> Each LeafNode in the new group's tree MUST be a leaf in the old group's tree at the epoch indicated in the PreSharedKey. </del> <ins> Each LeafNode in a new subgroup MUST match some LeafNode in the original group.  In this context, a pair of LeafNodes is said to "match" if the identifiers presented by their respective credentials are considered equivalent by the application. </ins> In addition, to avoid key re-use, the "psk_nonce" included in the "PreSharedKeyID" object MUST be a randomly sampled nonce of length

I can see that being an issue, although I am somewhat worried about us not being opinionated in same way about how to determine equality here, mainly because of interop type things. We punt on how to validate the credentials as well in general so I guess this is in line with prior decisions
Hey NAME and NAME check the change I just posted. NAME and I put that together, it's a bit tough to get a generic definition of equivalency.
There is currently a logical flaw in the subgroup branching flow. In order to branch, you need to compose a message . A Welcome message includes which is defined as follows: The problem with this is that the field of type cannot be made for existing members of the group because the leaf nodes are now types. is now only used to add new members to the group, so we can't reuse this for sub group initialization.
I'm not sure I understand correctly. Are you suggesting when branching a group off of another group, one re-uses the leaves of the old group? If so, that's not how it's meant to work. The new group created in the process of subgroup branching should be independent from the "parent" group safe for the PSK, which all member have to provide upon creation of the group. In fact one should never use the same key material in the leaves of multiple groups except when the supply of key packages that a party provides via the DS is exhausted (see Section 17.4).
That was part of my question. When there were key packages in the leaves, you theoretically could fork the group from a given point in time and reuse the current tree, but I wasn't sure if that was a proper solution or not. Sounds like it isn't, but either way, I think there should be clarification in the document about this. Let me write up a quick PR on it.
NAME opened URL Would like your feedback there. We have conflicting wording here as well. What threw me off in the first place was the line indicating that LeafNodes should be the same in the sub-group, and if we are fetching new key packages they will not be the same.
NAME Konrad, could you safely derive new keys for the members of the subgroup instead? If so, that would be an enormous increase in efficiency and (especially in the federated case) make group creation timing consistent enough to do dynamically.
NAME Nice idea!


Question: The "version" and "ciphersuite" values in the Welcome MUST be the same as those used by the old group. <del> Each LeafNode in the new group's tree MUST be a leaf in the old group's tree at the epoch indicated in the PreSharedKey. </del> <ins> Each LeafNode in a new subgroup MUST match some LeafNode in the original group.  In this context, a pair of LeafNodes is said to "match" if the identifiers presented by their respective credentials are considered equivalent by the application. </ins> In addition, to avoid key re-use, the "psk_nonce" included in the "PreSharedKeyID" object MUST be a randomly sampled nonce of length

But it's tricky, since we're dealing with public key pairs that the creator of the new group doesn't know the private keys for. If we were only using HPKE schemes that support updateable public key encryption, the creator of the new group could indeed update the key in the existing group and send the "delta" encrypted to each corresponding member (which would still represent an overhead, but we might be able to optimize this somehow). This is similar to the RTreeKEM mechanism that NAME et al. proposed at some point. To go all the way here, we'd have to do the same for the public key material in the credentials as well, which is not something we had considered before. It would be a new primitive, something like an updateable signature scheme? Probably something to consider for HPKE/MLS 2.0. We could also allow the re-use of LeadNodes for this particular case. It would be the simpler solution and I don't think it would be catastrophic, since we have to assume that LeafNode (or KeyPackage) key material is re-used in the "last resort" scenario anyway, but this would definitely be something we should discuss on the mailing list, as it would break a pretty basic assumption we've made until now.
Just catching up on this. NAME nice catch here. It seems like we have two options here: Require new KeyPackages (as in ) Invent some way to make a new group based on LeafNodes alone I probably agree that we should do (1) in the short term, but (2) also has some appeal -- it doesn't feel right to require new KeyPackages for folks you're already in touch with -- despite it probably being more spec text. So here's a sketch of (2) in the interest of completeness. Suppose we defined a message of the following form: ... which would pretty closely parallel to Commit. You would send it in MLSMessage and require a in MLSMessageAuth. Where Commit instructs the recipient to create a new epoch from the current one within the same group, Branch would instruct the recipient to create a new epoch that is the first epoch of a new group. In both cases, you would form an epoch / GroupContext as specified, then use the to ratchet into the new epoch.


Question: The "version" and "ciphersuite" values in the Welcome MUST be the same as those used by the old group. <del> Each LeafNode in the new group's tree MUST be a leaf in the old group's tree at the epoch indicated in the PreSharedKey. </del> <ins> Each LeafNode in a new subgroup MUST match some LeafNode in the original group.  In this context, a pair of LeafNodes is said to "match" if the identifiers presented by their respective credentials are considered equivalent by the application. </ins> In addition, to avoid key re-use, the "psk_nonce" included in the "PreSharedKeyID" object MUST be a randomly sampled nonce of length

I'm pretty sure that would work and have the expected security properties, though obviously formal analysis would be appreciated. The main awkardness that occurs to me is that any members joining after the branch would have to provide new key packages. And obviously, it would require a fair bit more spec text. All that said, though, the exercise of working all that out has increased my impression that we should do (1) for now. If we want something like (2) later, it can be done pretty cleanly in an extension.
Fixed by
Well put!


Question: sender should not consider itself application limited if it would have fully utilized the congestion window without pacing delay. <del> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations SHOULD either use pacing or reduce their congestion window to limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </del> A sender MAY implement alternative mechanisms to update its congestion window after periods of under-utilization, such as those proposed for TCP in RFC7661.

Came from the discussion of
NAME : I realized after we did this PR yesterday that this does not I It reduces burstiness in general, which is still a good thing, but it doesn't change slow start increase. I'll send a PR or ask Vidhi if she wants to.
When an ACK arrives that acknowledges N packets (where N could be very large), QUIC will increase the congestion window by more than 1MSS per congestion window during Congestion Avoidance causing bursty send. This could also affect the slow start. if (congestionwindow < ssthresh): // Slow start. congestionwindow += URL else: // Congestion avoidance. congestionwindow += kMaxDatagramSize * URL / congestionwindow One could argue that QUIC ACKs every other packet, but there ACK packet could get lost or ACK for ACK packet could get lost. The draft is probably assuming packet pacing but not all implementations support that. I discussed this with Jana and he thinks that we should add something in pseudo code or some specific text in the draft.
PR added more specific text on avoiding bursts into the network, FYI.
Please note that PR addresses the issue of app-limited or pacing-limited cases to not increase cwnd when it is under utilized. My concern is cwnd being inflated due to an ACK frame containing ACKs for large number of packets.
NAME : The problem here is that we don't talk about burstiness that can occur when pacing is not in place, and a stretch-ack is received. PRR handles this, but we don't do PRR in the draft.
No we need to spend lots of time on Reno as everybody appears to be doing Cubic or BBR?
Cubic has this problem. BBR cannot be assumed.
Except Cubic opens the window based on time spent, not just ack received
I don't get the scenario. It seems that NAME is worried about receiving an ACK for a large number of packets. This is not a congestion window problem, because it happens even if the congestion windows size remains constant. The root cause is that the ACK of N packets now reduces the number of packet in flow by N. So this is strictly about pacing, not about congestion control.


Question: sender should not consider itself application limited if it would have fully utilized the congestion window without pacing delay. <del> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations SHOULD either use pacing or reduce their congestion window to limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </del> A sender MAY implement alternative mechanisms to update its congestion window after periods of under-utilization, such as those proposed for TCP in RFC7661.

NAME yes, and it can and still does burst because of stretch acks
Not just stretch Acks -- deliberate Ack compression by the network happens too. Very few alternative to pacing.
URL describes
Discussed in Cupertino. NAME to prepare a PR that hopefully can incorporate some ideas from RFC3465 to add safety features for non-pacing stacks.
But 3465 does not solve the burst problem. It limits the growth of the window, but does not do pacing of any kind.
I think we can change to something like this
NAME I think we need to do 2MSS clamping per ACK received and not per packet acked. I am thinking that we can remove OnPacketAckedCC and instead do OnAckReceivedCC. Pseudocode change something like this:
I think we can keep but just move cwnd update to as you propose.
Yup, that's an important missing fix, though it needs to be applied only when not pacing. Additionally, helps with burstiness in general. NAME : I would make a variable, and apply the min here when not pacing.
The proposed change has the effect of reducing the effective Window if ACKs are compressed. Say you have a window of 12 packets, acks are delayed, and a single ACK acknowledges 12 packets. Now you have a window of 2 packets, your transmission rate is 6 times slower than before, and it will take you 10 RTT to recover. Is that really what you want?
NAME This is what ABC (RFC 3465) does for TCP. ACK compression has side-effects, and the way to deal with it is, as you say, to pace packets out. This reduction in performance is only when the endpoint does not pace, and it is the only way to limit bursts in that case.
Also, ACK compression does not necessarily imply ACK pruning. I have traces in which 1 RTT worth of ACKs is compressed and delivered back to back. In that case, the proposed algorithm will do nothing: you will get 2 MSS added for each ACK, back to back within less than 1 ms.
FYI.


Question: sender should not consider itself application limited if it would have fully utilized the congestion window without pacing delay. <del> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations SHOULD either use pacing or reduce their congestion window to limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </del> A sender MAY implement alternative mechanisms to update its congestion window after periods of under-utilization, such as those proposed for TCP in RFC7661.

FreeBSD implements rfc3465 (and enabled by default) URL Linux removed tcpabc implementation but saying it does in a different way: URL Considering FreeBSD doesn't have pacing by default, I think current proposed algorithm is not worse (or aggressive) than what tcp implementation does.
NAME I am working on the PR for pseudocode changes.
I agree that when not pacing, using an ABC limit is appropriate. FWIW Windows TCP was using a limit of 4 and not 2 for a long time and now uses 8 which is pretty close to IW10 burst in slow start phase.
For the WG: The proposed PR attempts to include a mechanism to limit CWND increase during slow start when not pacing. I'll note that by itself, it does not guarantee we follow the existing MUST: "Implementations MUST either use pacing or limit such bursts to the initial congestion window, which is recommended to be the minimum of 10 maxdatagramsize and max(2 maxdatagramsize, 14720)), where maxdatagramsize is the current maximum size of a datagram for the connection, not including UDP or IP overhead." I don't think we should add this to the pseudocode, because we say SHOULD pace packets and the pseudocode currently only covers SHOULDs, not MAYs. Adding all MAYs to the pseudocode is too complex. I don't have a concern about adding a reference to the existing RFC as a mechanism that MAY help limit bursts during slow start. I'd like a decision from the WG on whether to include this change and if so, some criteria on what should be included going forward.
I agree with the comment that burst from ACK compression or Stretch-ACKs result in bursts. I think the ways to change that is implement a maximum burst size or use pacing. The bursts do not appear a CC function to me.
Bringing conversation in from the list: With regards to , one of the things we found in testing was that it could (a) still allow an implementation to be vulnerable to too much bursting (the original problem), but more importantly (b) locked receivers into an ack pattern of acking every other packet. My main concern is that this causes problems if receivers want to experiment with and change acking strategies going forward in way that otherwise would be fine.


Question: sender should not consider itself application limited if it would have fully utilized the congestion window without pacing delay. <del> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations SHOULD either use pacing or reduce their congestion window to limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </del> A sender MAY implement alternative mechanisms to update its congestion window after periods of under-utilization, such as those proposed for TCP in RFC7661.

One way to look at the problem described by this issue is that the existing text has a minor underspecification, in which it has the notion of a burst limit but says nothing about the frequency of such bursts. Two "bursts" of 10MSS that are sent within a couple nanoseconds are really one burst that's too big. Another way of fixing this is to remove even the specification of the 10MSS limit if we really don't want too much text about the non-pacing cases. Essentially, what this comes down to is: pace, or even if you don't pace, you need to not send bursts above some frequency; and if you don't set some pacing timers, you'll likely underutilize the link.
I'm going to put this out there: the answer is MUST pace. You might formalize this by saying the number of packets sent in any interval cannot exceed by more than the initial cwnd (i.e., the 10MSS). That allows for bursting, but requires a period of quiet either preceding or following any burst.
NAME Yes, it does largely reduce to "implementations MUST pace" (even if the pacing algorithm isn't very nuanced, in which case you'll perform poorly). The formalization of the rate, one option for which was specified in , I think is the heart of what should be done here.
There are two routes that we can take: Specify clearly what 'delay` refers to in the below statement, which is done in OR Change MUST pace to SHOULD and remove the 10 MSS burst size limit and provide general recommendation if an implementation doesn't pace. Something like:
I'm sympathetic to saying MUST pace, and I like the formatlization that NAME suggests. I've heard some pushback on saying MUST pace in the past, but it might be worth giving it a shot again. NAME NAME NAME : What do you think?
That said... I will note that NAME 's formalization allows for a burst at the end of an RTT. Consider for example when a single ACK is received that acknowledges an entire window. That would be legal by this definition. I think that's ok.
Discussed in ZRH. Proposed resolution is to define and REQUIRE pacing.
NAME I think requiring pacing makes good sense, with some formalization of what that means.


Question: sender should not consider itself application limited if it would have fully utilized the congestion window without pacing delay. <del> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations SHOULD either use pacing or reduce their congestion window to limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </del> A sender MAY implement alternative mechanisms to update its congestion window after periods of under-utilization, such as those proposed for TCP in RFC7661.

To clarify the status here, my understanding is that the proposal is to close this design issue with no action. The discussions have identified editorial improvements that will be addressed independently.
Let's continue the editorial discussion on .
Closing this issue and continuing discussion on
This needs to run through the consensus call procedure, so we'll keep it open for another week.
Let's get this in -- it addresses some burstiness anyway.LGTM


Question: Modification of the ciphertext can go undetected if authentication is not also used, which is the case when sending EnvelopedData without <del> wrapping it in SignedData or enclosing SignedData within it. </del> <ins> wrapping it in SignedData or enclosing SignedData within it.  This is one of the reasons for moving from EnvelopedData to AuthEnvelopedData as the authenticated encryption algorithms provide the authentication without needing the SignedData layer. </ins> If an implementation is concerned about compliance with National Institute of Standards and Technology (NIST) key size

This adds a security consideration for padding. THis addresses issue
With the move from CBC to GCM as a padding mode, there is now no padding for a S/MIME message at all. We should probably add a security consideration dealing with the fact that in some cases traffic analysis might be able to get at the content of an encrypted message based on its size.


Question: connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration. <del> 9.5. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del> 10. TBD.

I don't fully understand when would someone want to set ignore-order = true, i.e., what is a valid use case for this? Lets say for whatever reason the sender sets this to True, this would if there is actual packet loss and receiver receives OOO packets, it won't send an immediate ACK. Meaning the sender won't enter loss recovery immediately and will continue sending packets at the same rate. This is not good, as it directly increases queuing on the network node and for a tail drop queue (most widespread deployment), it will also affect other flows. Meaning, other flows will experience packet loss due to non-responsiveness of this flow for certain period of time. I probably missed past conversations about ignore-order field, so my apologies if this has already been discussed. I read the draft and didn't see any explanation about where would this be useful and what are the fallbacks of setting this to true.
One use case that I know and care is for sending QUIC traffic from a server cluster. Some packets would be sent directly from a server node that governs the connections, but others would be sent via different nodes within the same cluster. Once we deploy a sender like this, the receiver would observe what looks like reordering (because most packets will be essentially delivered through an additional hop, and that would cause delays). But we do not want the receiver to send ACK for each packet being received. Regarding the problem, I'm not sure I agree with the impact. Typically, congestion controllers react to congestion after 1 RTT. When packet-number-based detection is turned off, that changes to 9/8 RTT. That does cause more pressure on the bottleneck queue, but it is no worse than that caused by a path with an 9/8 greater RTT. Assuming that congestion controllers are designed to be fair against flows having different RTTs, I tend to believe that this is a non-issue.
I agree with NAME though I think adding a SHOULD NOT use a delay longer than an RTT(URL) would be a good addition, since if the delay is extremely large(ie multiple RTTs), that could be bad.
In general, the spirit of this draft is to provide control over acking behavior to the sender, since it is the consumer of this information and ought to be able to control how frequently it needs to see this information.


Question: connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration. <del> 9.5. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del> 10. TBD.

If there are subtle consequences to these decisions, it is worth noting them in the draft. It seems useful to add some text on the consequences of using Ignore Order, so that senders can make informed decisions. We can do that.
NAME is this something that Fastly does or is planning to do? How would you share the connection secrets between different server nodes? When we set ignore-reorder = true, and lets assume that max ACK delay > 1RTT, it can be 1RTT or 2 or 10RTT. this would result in loss recovery to be delayed by at least an additional RTT, i.e. it will take >16/8RTT (>2RTT) instead of 9/8RTT to declare packets lost. That is significant IMO. >Assuming that congestion controllers are designed to be fair against flows having different RTTs, I tend to believe that this is a non-issue. CUBIC throughput is inversely proportional to RTT in New Reno mode. Nonetheless, I am more concerned about high queuing in bottleneck due to late loss recovery. Specifying the use-cases where ignore-order = true SHOULD be used will prevent new implementors from using it randomly. And as Jana said, some text around the consequences when it is used would allow informed decision making.
NAME I do not speak for Fastly's plan, but the OSS branch of H2O has a working prototype that does this: URL The calculation is correct. At the same time, I do not think that senders will be willing to use Max Ack Delay as large as that, when setting the Ignore Order bit. The problem here is the impact on loss recovery. If Max Ack Delay is set to a value as large as 1 RTT, then the sender needs to spend more than 2 RTTs for detecting a loss. That means that the size of the send and receive buffers have to be twice as large, and that it would take as twice as long to recover from a loss. Based on existing advice that we have in other RFCs, I think we should discourage Max Ack Delay that is greater than 9/8 RTT when Ignore Order bit is used (please see my comment on ).


Question: connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration. <del> 9.5. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del> 10. TBD.

I'd suggest 5/4, but otherwise agree with you NAME
Should the Max ACK Delay be restricted to 1/8 or 1/4 RTT as there is inherent 1RTT time spent while sending data and receiving ACKs? That would make a total of 1 + 1/8 or 1 +1/4 RTT total/
I think this is best as a sender-side SHOULD, since it knows what time threshold it's using. For example, we use 1/4 RTT, but have considered making it adaptive(ie: 1/16 RTT to 1 RTT) based on observed reordering. Also, if your RTT is 100us, and your timers have coarser granularity, 1/8 RTT or 1/4 RTT just doesn't make sense. I'm not sure what does, because I'm not an expert in datacenter networking, but that's why I think this is a SHOULD, not a MUST. Of course, it's also unenforceable, which is a good reason for a SHOULD.
+1 to SHOULD. The only argument I might disagree with NAME is that it is unenforceable (IMO a receiver can enforce by capping Ack Delay to a fraction of the RTT that the receiver has observed). But I do not think there's any reason to require the receiver to enforce, considering the fact that a sender can send as many packets as it likes, regardless of ACKs the receiver sends (or lack of).
I am fine with SHOULD and with a mention of how a sender would compute Max ACK Delay when he sets ignore-order = true. An example is fine too.
I believe this is the same issue as
There are two things that are impacted by setting a high value for ack delay: congestion control and time-threshold loss detection. On congestion control, we need some protection for the network, so we should recommend something. On loss detection, a sender that chooses and sets an ack delay higher than the time-threshold loss detection time period risks triggering unnecessary retransmissions.


Question: connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration. <del> 9.5. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del> 10. TBD.

So, I propose adding the following for a sender: SHOULD set the ack frequency to be at least one ack per RTT (so that congestion control responses are reasonably quick) a word of caution that setting the ack delay to be longer than time threshold can cause the sender to unnecessary retransmit
In 9.3. Window-based Congestion Controllers I thought that unless there is loss reported, a QUIC ACK Frame releases sending window. In a similar manner as the accurate byte counting style in TCP, a QUIC sender solely operates on the basis of bytes acked, not the number of ACK frames received. So while a delayed ACK could delay a round of growth when the ACK Ratio is larger, it is only delayed by the time to ACK the set of received packets. In looking at various QUIC CC over medium and longer path RTTs this effect was quite small, and the default ACK delay was not unreasonable; for shorter path RTTs this might be different
See PR
To me, ACK Clocking is a separate point that applies to any type of CC when the cwnd limits the sender. I agree there could be a concern is around whether a less frequent ACK policy can induce a cwnd-limited sender to send bursts of packets that could induce loss or disrupt sharing of the path with other flows. The QUIC specification already permits an initial window of 10 packets, and motivates the need for pacing. I think it is important this text refers to the QUIC transport section on pacing to mitigate bursts.
Better worded perhaps in PR .
Section 9.1 - There are CC considerations with respect to how long it is reasonable for a flow to hold-off detecting congestion and responding. This needs to be discussed. When an endpoint detects persistent congestion, it MUST promptly reduce the rate of transmission when it receive or detects an indication of congestion (e.g., loss or ECN marking) [RFC2914], the Ignore Order value of true (0x01) in this ID allows a sender to extend that period, postponing detection of loss. That might be reasonable, but excessive delay can be dangerous - and therefore the impact really needs to be discussed: delaying a fraction of a RTT is in my mind safe, intentionally delaying by an RTT is arguable.


Question: connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration. <del> 9.5. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del> 10. TBD.

A delay of many RTTs is endangers other flows, and we need to at least say that in some way ([RFC8084] took an alternate view of how long might be safe).
See PR
I think this warrants a note about how a sender SHOULD NOT use a delay that is larger than an RTT unless the sender has other information about either the network or current network conditions. Otherwise, the receiver does not need to enforce anything here.
NAME Delay of loss detection has negative impact on loss recovery as well. Considering that the time threshold defined in RFC 9002 is 9/8 RTT, I might ague that, when Ignore Order is set to true, then the maximum delay being advertised SHOULD be no greater than 9/8 RTT. These values provide responsiveness comparable to Rack when a packet is lost - the loss would be detected within 5/4 RTT. (stuck out, as this point is already covered by Section 8).


Question: 3.4.1. <del> Attestation is an important part of the issuance protocol.  In Privacy Pass, attestation is the process by which an Attester bears witness to, confirms, or authenticates a Client so as to verify a property about the Client that is required for Issuance.  Clients explicitly trust Attesters to perform attestation correctly and in a way that does not violate their privacy. </del> <ins> In Privacy Pass, attestation is the process by which an Attester bears witness to, confirms, or authenticates a Client so as to verify properties about the Client that are required for Issuance.  Issuers trust Attesters to perform attestation correctly. </ins> RFC9334 describes an architecture for attestation procedures.  Using that architecture as a conceptual basis, Clients are RATS attesters

In a successful issuance exchange, the attester provides the issuer with information about the client. The text in Section 3.2.1 points out that the way in which information about the client is combined could reduce anonymity set size in ways that affect privacy. Given that we have a chain of custody, I imagine that the privacy property here is about what the issuer learns about a client. More information means more information that might then propagate from the issue onward to the origin. This means that the attester needs to limit what it passes along to only that which is relevant. The client needs to trust the attester to do this. ... or does it? The text in Section 3.2.1 implies strongly that this anonymity set size is important, but the constraints on the client-issuer interaction, especially consistency rules, very much limits what the issuer can pass along to the origin. So maybe the system depends less on trusting the attester and more on the combination of the cryptographic properties of the token and the consistency system that mitigates against misuse. None of this appears in the privacy considerations. Should it?
On this point: "Clients do not explicitly trust Issuers." (Section 3.2.2) This would invalidate much of the discussion of anonymity sets in attestations. This is quite confusing. The client doesn't need to trust the issuer, because the issuer is unable to pass information on to others. However, the client cannot trust the issuer with information, so it has to trust the attester not to pass stuff along AND it has to use an anonymizing proxy to interact with the issuer so that nothing leaks. This is quite contradictory overall.
There are issuance protocols wherein the issuer learns information about the origin by design, like the . In this variant, if the attester were to pass information about the client on to the issuer, then the issuer would be able to reconstruct the (client, origin) pair, breaking the unlinkability goals. I agree that in the case where the issuer learns nothing about the origin in the protocol then reliance on the attester is lessened, but we need to make sure we accommodate future issuance protocols here. I'll think about ways in which we can try to make this more clear. This might go into the privacy considerations, as suggested.


Question: "encrypted_client_hello" extension and proceeds with the handshake as usual, per RFC8446, Section 4.1.2. <del> If it supports ECH but does not recognize the configuration specified by the client, then it ignores the extension and </del> <ins> If it supports ECH but cannot decrypt the extension, then it </ins> terminates the handshake using the ClientHelloOuter.  This is referred to as "ECH rejection".  When ECH is rejected, the server sends an acceptable ECH configuration in its EncryptedExtensions message. <del> If it supports ECH and recognizes the configuration, then it attempts to decrypt the ClientHelloInner.  It aborts the handshake if decryption fails; otherwise it forwards the ClientHelloInner to the backend, who terminates the connection.  This is referred to as "ECH acceptance". </del> <ins> If it supports ECH and decrypts the extension, it forwards the ClientHelloInner to the backend, who terminates the connection. This is referred to as "ECH acceptance". </ins> Upon receiving the server's response, the client determines whether or not ECH was accepted and proceeds with the handshake accordingly.

The spec describes an optional trial decryption mode, but most of the text contradicts it. This PR fixes the text up and tries to unify their processing models. In doing so, it flips the error handling from decrypterror to fallback to be consistent. This, combined with the ClientHelloOuterAAD change, plugs an active sticking out attack for free. It also makes easier because GREASE configid collisions with real configids are now harmless. Along the way, NAME and NAME observed that we're not authenticating the ECHConfig at all. (It used to be authenticated by way of the configid, which was a digest.) Instead, just pass the ECHConfig into the info field of the HPKE context. They also noticed the server rule about PSKs on ClientHelloOuter didn't work with GREASE. Instead, we can simply remove it.
This matches the acceptance signal length, and we've already accepted that probability of collision.


Question: Attester: An entity that attests to properties of Client for the purposes of token issuance. <ins> Redemption context: The interactions and set of information shared between the Client and Origin. Issuance context: The interactions and set of information shared between the Client, Attester, and Issuer. Attestation context: The interactions and set of information shared between the Client and Attester only, for the purposes of attesting the vailidity of the Client. </ins> 3. The Privacy Pass architecture consists of four logical entities - <del> Client, Origin, Issuer, and Attester - that work in concert as shown in introduction for token issuance and redemption.  This section describes the purpose of token issuance and redemption and the requirements therein on the relevant participants. </del> <ins> Client, Origin, Issuer, and Attester - that work in concert as for token issuance and redemption.  This section describes the purpose of token issuance and redemption and the requirements on the relevant participants. The typical interaction flow for Privacy Pass tokens uses the following steps: A Client interacts with an Origin by sending an HTTP request.  The Origin sends an HTTP response that contains a token challenge that indicates a specific Issuer to use.  Note that the request might be made as part of accessing a resource normally, or with the specific intent of triggering a token challenge. If the Client already has a token available that satisfies the token challenge, it can skip to step 6 and redeem its token. Otherwise, it invokes the issuance protocol to request a token from the designated Issuer. The first step in the issuance protocol is attestation. Specifically, the Attester performs attestation checks on the Client.  These checks could be proof of solving a CAPTCHA, device trust, hardware attestation, etc (see attester). If attestation succeeds, the client creates a Token Request to send to the designated Issuer (generally via the Attester).  The Attester and Issuer might be functions on the same server, depending on the deployment model (see deployment).  Depending on the details of Attestation, the Client can send the Token Request to the Attester alongside any attestation information.  If attestation fails, the Client receives an error and issuance aborts without a token. The Issuer generates a Token Response based on the Token Request, which is returned to the Client (generally via the Attester). Upon receiving the Token Response, the Client computes a token from the token challenge and Token Response.  This token can be validated by anyone with the per-Issuer key, but cannot be linked to the content of the Token Request or Token Response. If the Client has a token, it includes it in a subsequent HTTP request to the Origin, as authorization.  This token is sent only once.  The Origin validates that the token was generated by the expected Issuer and has not already been redeemed for the corresponding token challenge.  If the Client does not have a token, perhaps because issuance failed, the client does not reply to the Origin's challenge with a new request. </ins> 3.1.

In this image: ! It isn't very clear where messages originate and who gets to see them. In particular, it isn't clear where the TokenRequest originates (the Client) and whether the Attester gets to see it (¯(°_o)/¯).
That's a fair point. It should be clear that the TokenRequest comes from the Attester. I wonder if we also somehow need to illustrate that there's a trust relationship between the Attester and Issuer here. Something to at least imply that the Attester is either implicitly trusted to do attestation, or, perhaps in future versions of Privacy Pass, attestation proofs are sent directly to the Issuer.
Move diagram to section 3 (architecture). Also move much of the second intro paragraph down. Add more text about the actual steps to section 3, such as a numbered list
In here, introduce the basic privacy premise for how the redemption and issuance contexts are separated
The architecture references [AUTHSCHEME] for key concepts far more than I expected. For instance: Or: Can the architecture define the messages in their own right, then point to [AUTHSCHEME] for example implementations?
Is the suggestion here to describe -- conceptually -- what Token and TokenChallenges are in the architecture document? If so, that seems quite reasonable.
Yeah. An architecture is most useful if you don't have to dig into the details to understand it and those references are somewhat critical to comprehension.


Question: 4.1.3. <del> When the Push method is assigned to a binding, the source endpoint sends PUT requests to the destination resource when the Conditional Notification Attributes are satisfied for the source resource.  The source endpoint SHOULD only send a notification request if any included Conditional Notification Attributes are met.  The binding entry for this method MUST be stored on the source endpoint. </del> <ins> The Push method can be used to allow a source endpoint to replace an outdated resource state at the destination with a newer representation.  When the Push method is assigned to a binding, the source endpoint sends PUT requests to the destination resource when the Conditional Notification Attributes are satisfied for the source resource.  The source endpoint SHOULD only send a notification request if any included Conditional Notification Attributes are met. The binding entry for this method MUST be stored on the source endpoint. 4.1.4. An alternative means for a source endpoint to deliver change-of-state notifications to a destination resource is to use the Execute Method. While the Push method simply updates the state of the destination resource with the representation of the source resource, Execute can be used when the destination endpoint wishes to receive all state changes from a source.  This allows, for example, the existence of a resource collection consisting of all the state changes at the destination endpoint.  When the Execute method is assigned to a binding, the source endpoint sends POST requests to the destination resource when the Conditional Notification Attributes are satisfied for the source resource.  The source endpoint SHOULD only send a notification request if any included Conditional Notification Attributes are met.  The binding entry for this method MUST be stored on the source endpoint. Note: Both the Push and the Execute methods are examples of Server Push mechanisms that are being researched in the Thing-to-Thing Research Group (T2TRG) I-D.irtf-t2trg-rest-iot. </ins> 4.2.

NAME NAME I've created a pull request to incorporate the exec binding method in the draft. This brings it in line with and also now has a reference to the draft itself. It would be great if you can quickly review the proposed text and see if you are ok with it
Now merged, after review comments received from NAME to highlight differences between the Push and Exec binding methods


Question: frames should therefore not be paced, to avoid delaying their delivery to the peer. <ins> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet scheduler (fq qdisc) in Linux (3.11 onwards).


Question: frames should therefore not be paced, to avoid delaying their delivery to the peer. <ins> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet scheduler (fq qdisc) in Linux (3.11 onwards).


Question: frames should therefore not be paced, to avoid delaying their delivery to the peer. <ins> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet scheduler (fq qdisc) in Linux (3.11 onwards).


Question: frames should therefore not be paced, to avoid delaying their delivery to the peer. <ins> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet scheduler (fq qdisc) in Linux (3.11 onwards).


Question: frames should therefore not be paced, to avoid delaying their delivery to the peer. <ins> Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses.  Implementations MUST either use pacing or limit such bursts to minimum of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)), the same as the recommended initial congestion window. </ins> As an example of a well-known and publicly available implementation of a flow pacer, implementers are referred to the Fair Queue packet scheduler (fq qdisc) in Linux (3.11 onwards).


Question: If Observe is implemented: <del> Replace step 1 in ver-req with: A.  Discard Code and all options marked in fig-option-protection with 'x' in column E, except for Observe, present in the received message. For example, an If-Match Outer option is discarded, Uri-Host Outer option is not discarded, Observe is not discarded. </del> <ins> Insert the following step before step 1 in ver-req: </ins> <del> Replace step 3 in ver-req with: </del> <ins> A.  Check if the Outer Observe option is present and has value zero. </ins> <del> B.  If Observe is present in the received message, and has value 0, check if the Token, kid and Partial IV are identical to a previously received Observe registration.  In this case, replay verification is postponed until step C.  Otherwise verify the 'Partial IV' parameter using the Replay Window, as described in replay-protection. </del> <ins> Insert the following step between step 6 and 7 of ver-req: </ins> <del> Insert the following steps between step 6 and 7 of ver-req: C.  If Observe was present in the received message (in step 1): If the value of Observe in the Outer message is 0: If Observe is present and has value 0 in the decrypted options, discard the Outer Observe.  If the Token, kid and Partial IV are identical to a previously received Observe registration, respond with a notification as described in observe-replay- processing; Otherwise, discard both the Outer and Inner (if present) Observe options and verify the 'Partial IV' parameter using the Replay Window, as described in replay-protection. If the value of Observe in the Outer message is not 0, discard the decrypted Observe option if present. </del> <ins> B.  If Inner Observe is present and has value zero, and Outer option is either not present or has not value 0, then remove the Observe option. </ins> 8.3.

Back to one processing description Observe is now primarily inner Simplified processing Explicit cancellation by intermediary not supported