Question: much previous information as possible.  EDHOC is furthermore designed to be as compact and lightweight as possible, in terms of message sizes, processing, and the ability to reuse already existing CBOR, <del> COSE, and CoAP libraries. </del> <ins> COSE, and CoAP libraries.  Like (D)TLS, authentication is the responsibility of the application, EDHOC identifies (and optionally transports) authentication credentials, and provides proof-of- possession of the private authentication key. </ins> To simplify for implementors, the use of CBOR and COSE in EDHOC is summarized in CBORandCOSE.  Test vectors including CBOR diagnostic

>Classical selfie attacks are when there is a pre-shared key between an initiator and a receiver, >and the initiator will be talking to itself while it believes to be talking to the receiver. >When there are only public keys, as in EDHOC, it is unclear to me if what is currently >called in the draft is indeed a selfie attack. The selfie attack mitigation is intended for Trust On First Use (TOFU) use cases, where there is no authentication in the initial setup. I don't think an initiator talking to itself in a TOFU use case would not know it except if they checked R's public key. Do you some better suggestion than "Selfie attack". I agree that it is not perfect. "Selfie attacks" has in older papers been called reflection attacks, but the term reflection attacks has also been used for very different attacks. One option is to not give the attack any name and instead just describe the attack.
I think I like to not give any name, as it does not perfectly match the classical definition. Here, the property which is violated is "If an EDHOC exchange is completed, two distinct identities/computers/agents were active". Which is different to violating the authentication of the protocol as is the case in classical selfie attacks. Good point. So what we are talking about in this issue is a slightly different privacy leak, which happens when the set of parties you are willing to talk to is equal to all responders minus yourself. To be more concrete, let me try to put it in a kind of drafty formal description that could replace the existing formulation. First the existing formulation: Now a possible replacement:
Thanks for the input! This issue is related to the TOFU use case which is still to be detailed (Appendix D.5). We probably should wait with the update until we have progressed that.
Relates to
I made PR for this issue. This is also related to PR and PR . The suggested text in is largely based on the suggested text above but I made some changes. I did not think this fitted well with the rest of the draft. The sentence was also not really needed. This is only true in the case where the set of identifiers is a small finite set. In the general case the set of identifiers the Initiator is not willing to communicate with is infinite.


Question: much previous information as possible.  EDHOC is furthermore designed to be as compact and lightweight as possible, in terms of message sizes, processing, and the ability to reuse already existing CBOR, <del> COSE, and CoAP libraries. </del> <ins> COSE, and CoAP libraries.  Like (D)TLS, authentication is the responsibility of the application, EDHOC identifies (and optionally transports) authentication credentials, and provides proof-of- possession of the private authentication key. </ins> To simplify for implementors, the use of CBOR and COSE in EDHOC is summarized in CBORandCOSE.  Test vectors including CBOR diagnostic

I suggest to add the following recommendation for TOFU To not leak any long-term identifiers, it is recommended to use a freshly generated authentication key as identity in each initial TOFU exchange.
I merged the PR to master. Keeping the issue open for a while.
The current text is not really explaining how TOFU works and the security considerations. Would be good with some more text. TOFU might also go agains requirements in other parts of the document that says that "EDHOC is mutually authenticated.
This is conflicting with present use of COSE. Requires a separate section in the draft, preferably an appendix. We need to describe the use case, trust model, how to use EDHOC and the security properties. Can we reference some other RFC?
Looking at adding text on TOFU I think there is some more work to do. I don't TOFU should require anything specicial. The Section "Identities and trust anchors {#identities}" is fluffy. It is not clear that this is just general recommendations that is outside the scope of the EDHOC protocol and the reposability of the application. EDHOC provides proof-of-possesion and transfers a credential that enables authentication. Thats it. An EDHOC implementation might implemend Authentication for a specific use case, but that is still outside the EDHOC protocol. Any description of the interface between EDHOC and the application when it comes to credential is missing. In general EDHOC provides proof-of-possesion of the private key and then gives CRED_x to the application that says YES/NO. How the application does chain validation and identity validation (or the lack of it like in TOFU) is outside of EDHOC.
Status: This issue is waiting on a restructure, shortening, clarification on the responsibility of the EDHOC protocol and the application. and
The restructuring is done and merged with the master. Appendix D.5 is placeholder for TOFU.
I made PR for TOFU. As Marco pointed out this should be more general than TOFU. I changed the heading to "unauthenticated opearation" which is the term used by TLS 1.3
Merged adding text to the empty TOFU section. Closing
I made some minor updates, have a look.


Question: A signing key pair used to authenticate the sender of a message. <ins> A message that proposes a change to the group, e.g., adding or removing a member. A message that implements the changes to the group proposed in a set of Proposals. An MLS protocol message that is signed by its sender and authenticated as coming from a member of the group in a particular epoch, but not encrypted. An MLS protocol message that is both signed by its sender, authenticated as coming from a member of the group in a particular epoch, and encrypted so that it is confidential to the members of the group in that epoch. </ins> A PublicMessage or PrivateMessage carrying an MLS Proposal or Commit object, as opposed to application data.

URL This definition of a handshake message is being defined in terms of a Proposal or Commit object, neither of which are defined in this session. Furthermore, PublicMessage or PrivateMessage aren’t defined either as this point in the text. To improve clarity, consider defining these key terms. The use of "respectively" in the text is suggesting that PrivateMessages don’t have integrity protection which is not accurate. (see the Cryptographic Dependencies section of the HPKE specification for more information). Is this Section 4 of RFC9180?  If so, why not say that? What would be the circumstance where the application_id extension would be treated with equal standing as something from the AS?  Why can’t this be a "MUST"? Unsaid is what to do if the proposal list is not valid.  Please clarify. Is this normative behavior required, or could it be left up to application?  The mixing of updates/removes on the same node and the SHOULD guidance already means that this "recovery from an invalid node" may not be consistent across clients/DS-es. Same observation on recovering from ReInit with any other proposals. Is there any additional retry mechanism?  Let’s say the sender of the proposal doesn’t see it reflect in the epoch after it sent proposal.  And then not in the next epoch.  Does it try resending indefinitely? This setup seems a little simplistic. If the application data is encrypted to begin with, how does the adversary know the question being posed by Alice?


Question: control across the entire connection, QUIC has the capability to improve the performance of HTTP compared to a TCP mapping.  QUIC also incorporates TLS 1.3 (TLS13) at the transport layer, offering <del> comparable security to running TLS over TCP, with the improved connection setup latency of TCP Fast Open (TFO). </del> <ins> comparable confidentiality and integrity to running TLS over TCP, with the improved connection setup latency of TCP Fast Open (TFO). </ins> This document defines a mapping of HTTP semantics over the QUIC transport protocol, drawing heavily on the design of HTTP/2.  While

Mostly because QUIC doesn't prevent all forms of request forgery. Thankfully, this is dealt with in detail in the transport draft.
NAME this looks good. Can you also change one sentence in Sec 1.2, from: to .
Hilarie Orman wrote: all this is assumed to be provided by QUIC. Section 10.2 says that all QUIC packets are encrypted; I'm not sure if that's true, or if QUIC has an option for "non-modifiable" without encryption.
Actually, we now know that this is not true, so this really needs to be fixed: -- from . The real solution here is to cite of the transport draft.
The version of QUIC required by this draft is always encrypted; that seems sufficient for the original issue. NAME issue is distinct, and worth fixing. I'll use this issue to track it.
... and we could add some text stating the integrity point in Section 1.2. NAME suggests: "comparable integrity and confidentiality to TLS over TCP"
Could we make some progress on this one?
Progress made; the PR now needs review.


Question: 6.2. <del> Error handling in TLS is very simple.  When an error is detected, the detecting party sends a message to its peer.  Upon transmission or receipt of a fatal alert message, both parties immediately close the connection.  Servers and clients MUST forget keys, and secrets associated with a failed connection.  Stateful implementations of session tickets (as in many clients) SHOULD discard tickets associated with failed connections. Whenever an implementation encounters a condition which is defined as a fatal alert, it MUST send the appropriate alert prior to closing the connection.  For all errors where an alert level is not explicitly specified, the sending party MAY determine at its discretion whether to treat this as a fatal error or not.  If the implementation chooses to send an alert but intends to close the connection immediately afterwards, it MUST send that alert at the fatal alert level. If an alert with a level of warning is sent and received, generally the connection can continue normally.  If the receiving party decides not to proceed with the connection (e.g., after having received a "user_canceled" alert that it is not willing to accept), it SHOULD send a fatal alert to terminate the connection.  Given this, the sending peer cannot, in general, know how the receiving party will behave.  Therefore, warning alerts are not very useful when the sending party wants to continue the connection, and thus are sometimes omitted.  For example, if a party decides to accept an expired certificate (perhaps after confirming this with the user) and wants to continue the connection, it would not generally send a "certificate_expired" alert. </del> <ins> Error handling in the TLS Handshake Protocol is very simple.  When an error is detected, the detecting party sends a message to its peer. Upon transmission or receipt of a fatal alert message, both parties immediately close the connection.  Whenever an implementation encounters a condition which is defined as a fatal alert, it MUST send the appropriate alert prior to closing the connection. </ins> The following error alerts are defined:

NAME NAME PTAL
LGTM
lgtm
Don't forget no_certificate.
Not relevant: nocertificateRESERVED(41), / fatal / , Martin Thomson EMAIL wrote:
Right. I just noticed that we send an empty certificate instead.


Question: Each PSK SHOULD be derived from at least 128 bits of entropy, MUST be at least 128 bits long, and SHOULD be combined with a DH <del> exchange for forward secrecy.  Low entropy PSKs, i.e., those derived from less than 128 bits of entropy, MUST be combined with a Password Authenticated Key Exchange (PAKE) mechanism. </del> <ins> exchange for forward secrecy.  As discussed in sec-properties, low entropy PSKs, i.e., those derived from less than 128 bits of entropy, are subject to attack and SHOULD be avoided.  Low entropy keys are only secure against active attack if a Password Authenticated Key Exchange (PAKE) is used with TLS. </ins> Each PSK MUST NOT be shared between with more than two logical nodes.  As a result, an agent that acts as both a client and a

FIxed up: some nits on recommendations. I think the wording was a bit off on low entropy PSKs, so I lifted from ekrs text from earlier in the draft. some of the stack interface stuff on hints is not valid for TLS1.3 (hints are TLS1.2 and earlier), so removed it. Some prelim text on collisions. For completeness, will take a look at gnutls and wolfssl order too. Note, even with the OpenSSL callback sequence, the application still does not know if there is a collision...
Starter text from NAME
NAME can you please take this?
Ping NAME


Question: Identity Validation (IV): During a handshake, the security protocol will conduct identity validation of the peer.  This can <del> call into the application to offload validation. </del> <ins> offload validation or occur transparently to the application. </ins> TLS

We got another Secdir review: Reviewer: Paul Wouters Review result: Has Nits I have reviewed this document as part of the security directorate's ongoing effort to review all IETF documents being processed by the IESG. These comments were written primarily for the benefit of the security area directors. Document editors and WG chairs should treat these comments just like any other last call comments. The summary of the review is Has Nits Compared to my last review (-09) a lot of text has been removed, reducing the technical details and giving a briefer (but arguably cleaner) overview. I do still have a personal preference of dropping CurveCP and MinimalT as I don't really think these are anything but abandoned research items. I have never seen or heard of these being deployed. I would be more tempted to list openconnect (draft-mavrogiannopoulos-openconnect) which actually does see quite some deployment. If the intent is really to show different kind of API's, than there are other esoteric examples that could be included, such as Off-The-Record(OTR) or Signal, which are mostly encrypted chat programs, but with the ability to generate session keys for encrypted bulk transport (eg for video/audio or file transfer) Section 5.1 "Session Cache Management (CM):" which does not include IKEv2/IPsec, even though it does have session resumption (RFC 5723). I guess this is because the section limits itself to "the application" that can restart the session. But for IKEv2/IPsec the same could be said. An application that after a long idle period sends a packet, triggers a kernel ACQUIRE, which triggers an IKEv2 session resumption. WireGuard does not have this capability as there are no API/hooks for packet trigger tunnel events (AFAIK) "Pre-Shared Key Import (PSKI):" lists WireGuard, but AFAIK it does not support PSK based authentication - only public key based authentication. While I understand the IKEv2 entry (PSKs are used for authentication of peers), I am not sure the ESP entry should be here.


Question: Identity Validation (IV): During a handshake, the security protocol will conduct identity validation of the peer.  This can <del> call into the application to offload validation. </del> <ins> offload validation or occur transparently to the application. </ins> TLS

ESP does not "authenticate peers", unless you call "being able to decrypt and authenticate packets" as an instance of "authenticating peer" Section 5.2 This states "This can call into the application to offload validation.". This "can" is only not supported by WireGuard, as all of this is happening inside the kernel. Maybe a note could be useful here? "Source Address Validation" - It is a little unclear why TCP based protocols are not listed here. They (implicitly) do source address validation. Perhaps the introduction in this paragraph can state this more explicitly. Eg "for those protocols that do not use TCP and therefor do not have builtin source address validation ......."
On which protocols to include, MinimalT and CurveCP have different feature sets and interfaces exposed, which I think warrants their inclusion. Things like Signal and OTR indeed have seen very wide deployment, though they're asynchronous, application-layer protocols akin to MLS, which I think is out of scope. I'd also not like to add draft-mavrogiannopoulos-openconnect, if for no other reason than to draw a line in the sand. (We run the risk of indefinitely delaying this while adding more protocols.) On Session Cache Management, this is an explicit interface, and the example Paul mentions, while correct, does not exercise such an explicit interface. On WireGuard and PSK import, WireGuard uses the IKpsk2 Noise pattern (see URL, and URL), in which a responder uses its PSK to additionally authenticate a connection. On ESP and PSK import, we note that importing a PSK can be used for "encrypting (and authenticating) communication with a peer," which remains true for IPsec. (Right NAME I'll address the issues in 5.2 in a PR!


Question: 9. <del> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. </del> <ins> This section provides some guidance on a sender's choice of acknowledgment frequency and discusses some additional considerations.  Implementers can select an appropriate strategy to meet the needs of their applications and congestion controllers. </ins> 9.1. <del> A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. </del> <ins> A sender needs to be responsive to notifications of congestion, such as a packet loss or an ECN CE marking.  Also, window-based congestion controllers that strictly adhere to packet conservation, such as the one defined in QUIC-RECOVERY, rely on receipt of acknowledgments to send additional data into the network, and will suffer degraded performance if acknowledgments are delayed excessively. To enable a sender to respond to potential network congestion, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </ins> 9.2. <del> Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. </del> <ins> Receiving an acknowledgement can allow a sender to release new packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </ins> 9.3. <del> Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </del> <ins> Acknowledgements are fundamental to reliability in QUIC. Consequently, delaying or reducing the frequency of acknowledgments can cause loss detection at the sender to be delayed. A QUIC sender detects loss using packet thresholds on receiving an acknowledgement (Section 6.1.1 of QUIC-RECOVERY); delaying the acknowledgement therefore delays this method of detecting losses. Reducing acknowledgement frequency reduces the number of RTT samples that a sender receives (Section 5 of QUIC-RECOVERY), making a sender's RTT estimate less responsive to changes in the path's RTT. As a result, any mechanisms that rely on an accurate RTT estimate, such as time-threshold loss detection (Section 6.1.2 of QUIC- RECOVERY) or Probe Timeout (Section 6.2 of QUIC-RECOVERY), will be less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. 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. </ins> 9.4.

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: 9. <del> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. </del> <ins> This section provides some guidance on a sender's choice of acknowledgment frequency and discusses some additional considerations.  Implementers can select an appropriate strategy to meet the needs of their applications and congestion controllers. </ins> 9.1. <del> A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. </del> <ins> A sender needs to be responsive to notifications of congestion, such as a packet loss or an ECN CE marking.  Also, window-based congestion controllers that strictly adhere to packet conservation, such as the one defined in QUIC-RECOVERY, rely on receipt of acknowledgments to send additional data into the network, and will suffer degraded performance if acknowledgments are delayed excessively. To enable a sender to respond to potential network congestion, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </ins> 9.2. <del> Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. </del> <ins> Receiving an acknowledgement can allow a sender to release new packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </ins> 9.3. <del> Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </del> <ins> Acknowledgements are fundamental to reliability in QUIC. Consequently, delaying or reducing the frequency of acknowledgments can cause loss detection at the sender to be delayed. A QUIC sender detects loss using packet thresholds on receiving an acknowledgement (Section 6.1.1 of QUIC-RECOVERY); delaying the acknowledgement therefore delays this method of detecting losses. Reducing acknowledgement frequency reduces the number of RTT samples that a sender receives (Section 5 of QUIC-RECOVERY), making a sender's RTT estimate less responsive to changes in the path's RTT. As a result, any mechanisms that rely on an accurate RTT estimate, such as time-threshold loss detection (Section 6.1.2 of QUIC- RECOVERY) or Probe Timeout (Section 6.2 of QUIC-RECOVERY), will be less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. 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. </ins> 9.4.

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: 9. <del> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. </del> <ins> This section provides some guidance on a sender's choice of acknowledgment frequency and discusses some additional considerations.  Implementers can select an appropriate strategy to meet the needs of their applications and congestion controllers. </ins> 9.1. <del> A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. </del> <ins> A sender needs to be responsive to notifications of congestion, such as a packet loss or an ECN CE marking.  Also, window-based congestion controllers that strictly adhere to packet conservation, such as the one defined in QUIC-RECOVERY, rely on receipt of acknowledgments to send additional data into the network, and will suffer degraded performance if acknowledgments are delayed excessively. To enable a sender to respond to potential network congestion, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </ins> 9.2. <del> Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. </del> <ins> Receiving an acknowledgement can allow a sender to release new packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </ins> 9.3. <del> Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </del> <ins> Acknowledgements are fundamental to reliability in QUIC. Consequently, delaying or reducing the frequency of acknowledgments can cause loss detection at the sender to be delayed. A QUIC sender detects loss using packet thresholds on receiving an acknowledgement (Section 6.1.1 of QUIC-RECOVERY); delaying the acknowledgement therefore delays this method of detecting losses. Reducing acknowledgement frequency reduces the number of RTT samples that a sender receives (Section 5 of QUIC-RECOVERY), making a sender's RTT estimate less responsive to changes in the path's RTT. As a result, any mechanisms that rely on an accurate RTT estimate, such as time-threshold loss detection (Section 6.1.2 of QUIC- RECOVERY) or Probe Timeout (Section 6.2 of QUIC-RECOVERY), will be less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. 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. </ins> 9.4.

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: 9. <del> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. </del> <ins> This section provides some guidance on a sender's choice of acknowledgment frequency and discusses some additional considerations.  Implementers can select an appropriate strategy to meet the needs of their applications and congestion controllers. </ins> 9.1. <del> A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. </del> <ins> A sender needs to be responsive to notifications of congestion, such as a packet loss or an ECN CE marking.  Also, window-based congestion controllers that strictly adhere to packet conservation, such as the one defined in QUIC-RECOVERY, rely on receipt of acknowledgments to send additional data into the network, and will suffer degraded performance if acknowledgments are delayed excessively. To enable a sender to respond to potential network congestion, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </ins> 9.2. <del> Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. </del> <ins> Receiving an acknowledgement can allow a sender to release new packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </ins> 9.3. <del> Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </del> <ins> Acknowledgements are fundamental to reliability in QUIC. Consequently, delaying or reducing the frequency of acknowledgments can cause loss detection at the sender to be delayed. A QUIC sender detects loss using packet thresholds on receiving an acknowledgement (Section 6.1.1 of QUIC-RECOVERY); delaying the acknowledgement therefore delays this method of detecting losses. Reducing acknowledgement frequency reduces the number of RTT samples that a sender receives (Section 5 of QUIC-RECOVERY), making a sender's RTT estimate less responsive to changes in the path's RTT. As a result, any mechanisms that rely on an accurate RTT estimate, such as time-threshold loss detection (Section 6.1.2 of QUIC- RECOVERY) or Probe Timeout (Section 6.2 of QUIC-RECOVERY), will be less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. 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. </ins> 9.4.

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: 9. <del> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. </del> <ins> This section provides some guidance on a sender's choice of acknowledgment frequency and discusses some additional considerations.  Implementers can select an appropriate strategy to meet the needs of their applications and congestion controllers. </ins> 9.1. <del> A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. </del> <ins> A sender needs to be responsive to notifications of congestion, such as a packet loss or an ECN CE marking.  Also, window-based congestion controllers that strictly adhere to packet conservation, such as the one defined in QUIC-RECOVERY, rely on receipt of acknowledgments to send additional data into the network, and will suffer degraded performance if acknowledgments are delayed excessively. To enable a sender to respond to potential network congestion, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </ins> 9.2. <del> Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. </del> <ins> Receiving an acknowledgement can allow a sender to release new packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </ins> 9.3. <del> Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </del> <ins> Acknowledgements are fundamental to reliability in QUIC. Consequently, delaying or reducing the frequency of acknowledgments can cause loss detection at the sender to be delayed. A QUIC sender detects loss using packet thresholds on receiving an acknowledgement (Section 6.1.1 of QUIC-RECOVERY); delaying the acknowledgement therefore delays this method of detecting losses. Reducing acknowledgement frequency reduces the number of RTT samples that a sender receives (Section 5 of QUIC-RECOVERY), making a sender's RTT estimate less responsive to changes in the path's RTT. As a result, any mechanisms that rely on an accurate RTT estimate, such as time-threshold loss detection (Section 6.1.2 of QUIC- RECOVERY) or Probe Timeout (Section 6.2 of QUIC-RECOVERY), will be less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. 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. </ins> 9.4.

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: 9. <del> Thanks to Mark Nottingham, Glenn Deen, Dave Oran, Aaron Falk, Kyle Rose, Leslie Daigle, Lucas Pardue, Matt Stock, Alexandre Gouaillard, and Mike English for their very helpful reviews and comments. </del> <ins> Thanks to Alexandre Gouaillard, Aaron Falk, Dave Oran, Glenn Deen, Kyle Rose, Leslie Daigle, Lucas Pardue, Mark Nottingham, Matt Stock, Mike English, Roni Even, and Will Law for very helpful suggestions, reviews and comments. (If we missed your name, please let us know!) </ins> 10.  References

We've been getting help from people, but the ACKs section hasn't changed much since -03 was submitted in November 2020.
I found like two names that we had missed, and added them to the ACKs section. I think we can merge this any time.


Question: An ICE agent that supports mDNS candidates MUST support the situation where the hostname resolution results in more than one IP address. In this case, the ICE agent MUST take exactly one of the resolved IP <del> addresses and ignore the others.  The ICE agent SHOULD, if available, use the first IPv6 address resolved, otherwise the first IPv4 address. </del> <ins> addresses and ignore the others.  The ICE agent SHOULD use the first IPv6 address resolved, if one exists, or the first IPv4 address, if not. </ins> 4.

Also wrap long lines for #processing section.
Comments addressed, PTAL.
Will wait for NAME approval before merging.
LGTM, updated PR for line wrapping.
The changes to ICE candidate gathering are targeted to web browsers; the changes to ICE candidate processing affect all WebRTC endpoints.
If we add this indication, do we also need to clarify the use case for lite ICE agents?
What did you have in mind?
{{#gathering}} starts with "For any host candidate gathered by an ICE agent as part of {{RFC8445}} section 5.1.1," it seems the place we need to revise to resolve this issue. I was thinking of allowing ICE lite implementation to skip the mDNS wrapping, since lite agents only use host candidates (8445, section 2.5). The lite implementation is however not required restricted to ICE agents that always have public IPs from my reading of that section, but rather an alternative to simplify the implementation when possible. So I am still not sure if it makes sense to say lite ICE can be exempted from wrapping; or instead indicating mDNS wrapping can be skipped if host candidates are equivalent to srflx candidates, and automatically the intended use of lite ICE satisfies this condition.
Right, the public IPs exception probably covers this. also indicates that this is really for web browsers, which are not allowed to implement ICE Lite.
Started writing this up today, but realized it's not totally clear how this should work. The idea would be to use STUN to figure out if an IP is public or not, but... Should we wait to hand out the mDNS candidate until we determine if the IP is private (i.e., STUN finishes)? Should we not hand out the mDNS candidate if we get a srflx candidate that shows the IP is not private? If we hand out the mDNS candidate and then get a srflx candidate that matches the local IP, should we make that a host candidate? Once we learn an IP is not public, should we cache that for future ICE gathering sessions (i.e., not give out mDNS candidates?) The easiest thing would probably be to recommend handing out the mDNS and srflx candidates as usual, but allow implementations to skip mDNS for IPs it has learned are public. (Except for RFC1918 addresses, which would always be treated as private.)
Partially addressed in , will probably include some additional clarifying text once it lands
LGTM


Question: length, the output length in bits. <del> fig-edhoc-kdf lists derivations made with EDHOC_KDF during message processing, where </del> <ins> fig-edhoc-kdf lists derivations made with EDHOC_KDF, where </ins> hash_length - length of output size of the EDHOC hash algorithm of the selected cipher suite

I strongly think that all 10 EDHOC-KDF should be in the same table The text about maclengthx need to use the defined term hash_length
I made one commit for review.


Question: with a value greater than 2^60, this would allow a maximum stream ID that cannot be expressed as a variable-length integer; see integer- encoding.  If either is received, the connection MUST be closed <del> immediately with a connection error of type STREAM_LIMIT_ERROR; see </del> <ins> immediately with a connection error of type FRAME_ENCODING_ERROR; see </ins> immediate-close. Endpoints MUST NOT exceed the limit set by their peer.  An endpoint

This is an error that can be detected in frame parsing without additional context.
Over on URL we had a discussion about whether a MAXSTREAMS frame with value exceeding 2^60 generates a FRAMEENCODING or a STREAMLIMIT error. Draft 29 Section 19.11 says: corresponding type that can be opened over the lifetime of the connection. This value cannot exceed 2^60, as it is not possible to encode stream IDs larger than 2^62-1. Receipt of a frame that permits opening of a stream larger than this limit MUST be treated as a FRAMEENCODINGERROR. but as NAME points out, Section 4.5 says with a value greater than 2^60, this would allow a maximum stream ID that cannot be expressed as a variable-length integer; see Section 16. If either is received, the connection MUST be closed immediately with a connection error of type STREAMLIMITERROR Meanwhile, for the STREAMSBLOCKED frame in Section 19.15 we have: I suspect both Vidhi and I are correct, bogus MAXSTREAMS can be treated as either STREAMLIMIT or FRAME_ENCODING. If so, its probably a minor editorial fix to state either/or in both the sections.
NAME suggested that it should only be a FRAMEENCODINGERROR, as it's invalid to send a MAX_STREAMS larger than 2^60 under any circumstance, regardless of connection state, and I agree that's the clearest application of our principles.
I agree that requiring the use of FRAMEENOCDINGERROR is fine. Even though we occasionally allow an endpoint to use multiple error codes when there is more than one way of checking the status (i.e. FLOWCONTROLERROR vs. FRAMEENCODINGERROR for STREAM frames), the check required in this particular case is purely unrelated to the connection state. Hence my +1.
I would be happy with a single error too. I'm not fussy about the actual code used as long as the spec is clear and consistent. That means that we'd need to reduce STREAMS_BLOCKED to one error code too, and potentially any other situation that allows either.
I'm going to drop . I agree with the comments suggesting that FRAMEENCODINGERROR is the right answer. Note that you might still receive a different error, as we permit endpoints that detect multiple errors to send any that it detects, and this case clearly justifies use of STREAMLIMITERROR.


Question: 6.4. <ins> Naturally, an address that is already exposed to the Internet does not need to be protected by mDNS, as it can be trivially observed by the web server or remote endpoint.  However, determining this ahead of time is not straightforward; while the fact that an IPv4 address is private can sometimes be inferred by its value, e.g., whether it is an RFC1918 address, the reverse is not necessarily true.  IPv6 addresses present their own complications, e.g., private IPv6 addresses as a result of NAT64 RFC6146. Instead, the determination of whether an address is public can be reliably made as part of the ICE gathering process, namely, if the query to the STUN RFC5389 server returns the same value as the local address.  This can be done for both IPv4 and IPv6 local addresses, provided that the application has configured both IPv4 and IPv6 STUN servers.  If this situation occurs, i.e., STUN returns the same IP address value for an address that has already been communicated as an mDNS candidate during the current ICE gathering phase, the ICE agent MUST NOT eliminate the candidate as redundant and MUST send the IP address as a server-reflexive candidate.  This allows the ICE agent to send mDNS candidates immediately (i.e., without waiting for STUN), even if the associated addresses may not be private. Once an address has been identified as public, the ICE agent MAY cache this information and omit mDNS protection for that address in future ICE gathering phases. 6.5. As noted in IPHandling, private IPv4 addresses are especially problematic because of their unbounded lifetime.  However, the RFC4941 IPv6 addresses recommended for WebRTC have inherent privacy protections, namely a short lifetime and the lack of any stateful information.  Accordingly, implementations MAY choose to not conceal RFC4941 addresses with mDNS names as a tradeoff for improved peer-to- peer connectivity. 6.6. </ins> As noted in IPHandling, privacy may be breached if a web application running in two browsing contexts can determine whether it is running on the same device.  While the approach in this document prevents the

I think this is good to go, will plan to land at EOD.
Does it obfuscate, conceal, or obscure local IP addresses? My vote is for conceal.
Conceal/concealment sgtm.
As noted in , we don't need to use the same term in every case, but the terms should have the same meaning. conceal and hide are fairly synonymous, but conceal and obfuscate have slightly different meanings.
This section is largely normative, so it might make more sense to put some parts from it immediately after Principle, namely the various adjustments to the technique that need to be considered (TURN, IPv6, stats) Things where we merely provide discussion (e.g., session monitoring) rather than normative guidance could remain in the privacy section.
Due to their different sensitivity and lifetime.
If we add this indication, do we also need to clarify the use case for lite ICE agents?
What did you have in mind?
{{#gathering}} starts with "For any host candidate gathered by an ICE agent as part of {{RFC8445}} section 5.1.1," it seems the place we need to revise to resolve this issue. I was thinking of allowing ICE lite implementation to skip the mDNS wrapping, since lite agents only use host candidates (8445, section 2.5). The lite implementation is however not required restricted to ICE agents that always have public IPs from my reading of that section, but rather an alternative to simplify the implementation when possible. So I am still not sure if it makes sense to say lite ICE can be exempted from wrapping; or instead indicating mDNS wrapping can be skipped if host candidates are equivalent to srflx candidates, and automatically the intended use of lite ICE satisfies this condition.
Right, the public IPs exception probably covers this. also indicates that this is really for web browsers, which are not allowed to implement ICE Lite.
Started writing this up today, but realized it's not totally clear how this should work. The idea would be to use STUN to figure out if an IP is public or not, but... Should we wait to hand out the mDNS candidate until we determine if the IP is private (i.e., STUN finishes)? Should we not hand out the mDNS candidate if we get a srflx candidate that shows the IP is not private?


Question: 6.4. <ins> Naturally, an address that is already exposed to the Internet does not need to be protected by mDNS, as it can be trivially observed by the web server or remote endpoint.  However, determining this ahead of time is not straightforward; while the fact that an IPv4 address is private can sometimes be inferred by its value, e.g., whether it is an RFC1918 address, the reverse is not necessarily true.  IPv6 addresses present their own complications, e.g., private IPv6 addresses as a result of NAT64 RFC6146. Instead, the determination of whether an address is public can be reliably made as part of the ICE gathering process, namely, if the query to the STUN RFC5389 server returns the same value as the local address.  This can be done for both IPv4 and IPv6 local addresses, provided that the application has configured both IPv4 and IPv6 STUN servers.  If this situation occurs, i.e., STUN returns the same IP address value for an address that has already been communicated as an mDNS candidate during the current ICE gathering phase, the ICE agent MUST NOT eliminate the candidate as redundant and MUST send the IP address as a server-reflexive candidate.  This allows the ICE agent to send mDNS candidates immediately (i.e., without waiting for STUN), even if the associated addresses may not be private. Once an address has been identified as public, the ICE agent MAY cache this information and omit mDNS protection for that address in future ICE gathering phases. 6.5. As noted in IPHandling, private IPv4 addresses are especially problematic because of their unbounded lifetime.  However, the RFC4941 IPv6 addresses recommended for WebRTC have inherent privacy protections, namely a short lifetime and the lack of any stateful information.  Accordingly, implementations MAY choose to not conceal RFC4941 addresses with mDNS names as a tradeoff for improved peer-to- peer connectivity. 6.6. </ins> As noted in IPHandling, privacy may be breached if a web application running in two browsing contexts can determine whether it is running on the same device.  While the approach in this document prevents the

If we hand out the mDNS candidate and then get a srflx candidate that matches the local IP, should we make that a host candidate? Once we learn an IP is not public, should we cache that for future ICE gathering sessions (i.e., not give out mDNS candidates?) The easiest thing would probably be to recommend handing out the mDNS and srflx candidates as usual, but allow implementations to skip mDNS for IPs it has learned are public. (Except for RFC1918 addresses, which would always be treated as private.)
Partially addressed in , will probably include some additional clarifying text once it lands
The rest LGTM


Question: system can race different security protocols, e.g., if the application explicitly specifies that it considers them equivalent. <ins> Whether information from previous racing attempts, or other information cached by the Transport Services implementation about past communications, is used during establishment is under application control.  This allows applications to make tradeoffs between efficiency (through racing) and privacy (via information that might leak from the cache toward an on-path observer).  Some applications have native concepts (e.g. "incognito mode") that align with this functionality. </ins> Applications need to ensure that they use security APIs appropriately.  In cases where applications use an interface to provide sensitive keying material, e.g., access to private keys or

In (Arch) section 3.3, you are talking about racing before you've described what it is. At the point where you note that racing should only happen over stacks with identical security properties, note when doing so might introduce privacy issues and what can be done about them.
Describe what you mean by caching and why you might want to isolate sessions earlier.


Question: from a packet number of 0.  Thus, 0-RTT packets could need to use a longer packet number encoding. <del> A client SHOULD instead generate a fresh cryptographic handshake message and start packet numbers from 0.  This ensures that new 0-RTT packets will not use the same keys, avoiding any risk of key and nonce reuse; this also prevents 0-RTT packets from previous handshake attempts from being accepted as part of the connection. </del> A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.  This means that 0-RTT packets cannot contain any response to frames from 1-RTT packets.  For instance, a

As of , the client MUST use the same handshake message.
NAME That's quite complicated, and I'm not sure if we've chosen the right design here. I'd like to keep this PR editorial though. I opened to discuss this.
In URL, NAME points out that after a Retry, all 0-RTT packets sent in the first flight are still valid, although they will probably have been dropped by the server (unless there's significant reordering). That means that a client SHOULD retransmit all 0-RTT packets in the second flight. We now have two different scenarios: In the case of a HelloRetryRequest, the client is prohibited from sending 0-RTT, and has to cancel retransmissions for all outstanding 0-RTT packets. In the case of Retry, the 0-RTT packets from the first flight are declared lost (without any effect on the cwnd though) and retransmitted. Considering that Retry adds a roundtrip anyway (and thereby limits the usefulness of 0-RTT), and that we only expect it to be used by a server that's under attack (which makes it likely to refuse 0-RTT later in the handshake), does it really make sense to send 0-RTT in that case?
NAME I am not sure if I agree with the observation. The transport draft states that a server MAY send Retry packets in response to Initial and 0-RTT packets. A server can either discard or buffer 0-RTT packets that it receives (). Notice that the server is allowed to "buffer" 0-RTT packets. I am not sure if I like this ambiguity (because I think most if not all of us will be dropping 0-RTT packets that carry the original DCID when sending a Retry), but IMO the draft is clear.
NAME thanks for pointing that out. My point is that we should change the draft (i.e. this is a design issue, not an editorial issue).


Question: from a packet number of 0.  Thus, 0-RTT packets could need to use a longer packet number encoding. <del> A client SHOULD instead generate a fresh cryptographic handshake message and start packet numbers from 0.  This ensures that new 0-RTT packets will not use the same keys, avoiding any risk of key and nonce reuse; this also prevents 0-RTT packets from previous handshake attempts from being accepted as part of the connection. </del> A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.  This means that 0-RTT packets cannot contain any response to frames from 1-RTT packets.  For instance, a

The reason a server (or a LB) performs a Retry is that it either has reasons to suspect that the client isn't reachable at the 2-tuple it sent the packet from, or that it is under load, and either uses the Retry to redirect traffic to a different backend server, or just to buy itself some time Under both circumstances, a server wouldn't want to allocate additional state for buffering 0-RTT packets. I'm therefore suggesting to change the draft such that: A server that performs a Retry MUST discard 0-RTT packets. A client MUST NOT use 0-RTT after a Retry was performed. Does that make sense to you?
Yeah, I can envision a server that considers buffering some number of packets to be cheaper than doing a TLS handshake. For such servers, delaying the TLS handshake until client proves it's existence but buffering the 0-RTT packets in the meantime would make sense. That said, I'd be fine with this, assuming that the discarded 0-RTT packets are the ones that carry the original DCID. I would prefer not having this requirement. Once the client is known to exist, a server needs to communicate with the client. Use of 0-RTT helps reduce the server load, because when used, average lifetime of connections becomes 1-RTT less. That leads us to having less concurrent connections.
When our implementation does Retry, it's because we've hit a memory pressure limit and we want to protect ourselves from attack. If a client supplies us with a valid token, we will accept 0-RTT still, but we won't buffer it from the previous Initial (without a token). So, if the client gets a Retry and still wants to do 0-RTT, they need to retransmit it, with the new CID, in a new packet (with a new packet number). I don't see why that design should be prevented.
Ok, I see that there's value in doing 0-RTT after a Retry, and furthermore, there seem to be good reasons (prevention of tampering by middle boxes) to disallow 0-RTT after a HelloRetryRequest in TLS 1.3, as NAME pointed out OOB. Since we can assume that most (all?)


Question: from a packet number of 0.  Thus, 0-RTT packets could need to use a longer packet number encoding. <del> A client SHOULD instead generate a fresh cryptographic handshake message and start packet numbers from 0.  This ensures that new 0-RTT packets will not use the same keys, avoiding any risk of key and nonce reuse; this also prevents 0-RTT packets from previous handshake attempts from being accepted as part of the connection. </del> A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.  This means that 0-RTT packets cannot contain any response to frames from 1-RTT packets.  For instance, a

server implementation will drop 0-RTT packets when sending a Retry, the only reasonable thing to do for a client is to treat all 0-RTT packets as lost and retransmit them. Considering that, it would make sense to require servers to drop all Retry packets from the first flight, as NAME suggests.
NAME Thank you for suggesting a path forward. I think my weak preference goes to something slightly different. I think we are in agreement that most if not all the servers would not buffer the 0-RTT packets carrying the original DCIDs when they send Retrys. It makes sense to acknowledge the fact in the specification and suggest clients to retransmit 0-RTT data it has already sent. What I am not sure is if there is a reason to forbid servers from buffering such 0-RTT packets. From client's point of view, sending 0-RTT data once per connection is an optimization. Retransmitting 0-RTT data when the server sends a Retry is further optimization. If we think that way, servers that buffer 0-RTT packets when sending a Retry has increased chance of utilizing 0-RTT data. Compared to that, there is no reason to mandate servers to drop 0-RTT packets. To summarize, I think all we need to clarify is that servers responding with Retries are likely to discard 0-RTT packets that carry the original DCIDs and therefore that retransmitting 0-RTT data makes sense. But nothing more.
What if client takes action on Retry, and the old 0-RTT state lingers - wouldn't that make servers more vulnerable to DDoS attacks from packet sniffers?
This also bears on . If the DCID doesn't change, then the server won't be able to differentiate the first flight of 0-RTT packets, which you're proposing to drop, from the second flight of 0-RTT packets which it accepts. The current text says that the server MAY buffer and process them later; you're saying that servers probably won't. I think that's fine, but some might -- hence, I favor NAME suggestion to retain the permission to buffer but the caution to the client that the packets were quite possibly lost/dropped.


Question: from a packet number of 0.  Thus, 0-RTT packets could need to use a longer packet number encoding. <del> A client SHOULD instead generate a fresh cryptographic handshake message and start packet numbers from 0.  This ensures that new 0-RTT packets will not use the same keys, avoiding any risk of key and nonce reuse; this also prevents 0-RTT packets from previous handshake attempts from being accepted as part of the connection. </del> A client MUST NOT send 0-RTT packets once it starts processing 1-RTT packets from the server.  This means that 0-RTT packets cannot contain any response to frames from 1-RTT packets.  For instance, a

In terms of actual spec change, I think that means this text in : ...becomes a SHOULD instead of a MAY.
It seems like you have sorted this out. I have no problem with using "SHOULD" over "MAY" here. Note that the reason we have this distinction is logical separation of the mechanism of Retry and 0-RTT acceptance. Retry strictly precedes the connection attempt. No point in blocking 0-RTT if you have to Retry. HelloRetryRequest is different in that certain characteristics it might cause to reset affect whether the 0-RTT works. Retry is required to use the same ClientHello, so there is no need to have the two interact; you can treat a Retry almost as a loss event for the first Initial and everything works fine.
So, the effect of not changing the handshake message is that all previously-sent 0-RTT data is still valid, but has potentially/probably been lost rather than queued. Clients obviously MUST NOT reuse the packet number for different data, but in their not-resetting, they also can't change the data that they've already sent in those packets. They'll need to retransmit it, because otherwise there's a potential DoS attack by delaying/replaying a 0-RTT packet by one RTT against a server that does Retries.This PR looks good to me as an editorial improvement. Regarding NAME point, the transport draft explicitly states that a server sending a Retry can buffer 0-RTT packets that carried the original DCID, and process them after receiving a response to the Retry. To put it differently, I think we are clear on the semantics and that there are ways to implement this without having security concerns. That said, I understand that NAME has opened a design issue () to discuss if that is the design we want to have.LGTM


Question: 21.6. <del> An adversarial sender might intentionally send fragments of stream data in an attempt to cause disproportionate receive buffer memory commitment and/or creation of a large and inefficient data structure. </del> <ins> An adversarial sender might intentionally not send portions of the stream data, causing the receiver to commit resources for the unsent data.  This could cause a disproportionate receive buffer memory commitment and/or the creation of a large and inefficient data structure at the receiver. </ins> An adversarial receiver might intentionally not acknowledge packets containing stream data in an attempt to force the sender to store the

Proposal to clarify "stream fragmentation". Suggested by Issue .
I don’t understand what section 21.6 is about… the title seems to suggests it is about IP Fragmentation and Reassembly Attacks, but elsewhere the spec already prohibits IP Fragmentation in section 14? And I have seen no encouragement to do any form of network-layer fragmentation - so I don’t understand a security consideration in this topic. Is this therefiore some other thing? It may about something different where a sender originates data with “holes” of missing packet to try and exercise the server? or soemthing? What is this?
Hi NAME 21.6 is titled "Stream Fragmentation and Reassembly Attacks". It refers to streams, not IP packets. The attack involves sending stream frames with holes such as and some receivers might allocate the entire stream receive buffer between 0 and 10000001. I found the section pretty clear, but we should make it clear to everyone - could you perhaps suggest text that would make it clearer?
OK. I see. I can try a PR, if I can find words that avoid "fragment": Is this close enough to start: /An adversarial sender might intentionally omit to send portions of the stream data causing the receiver to commit resources for the omitted data, this could cause a disproportionate receive buffer memory commitment and/or creation of a large and inefficient data structure.
Do we really need to avoid the term "fragment"? It's not the only overloaded networking term in the spec. Perhaps adding a "Note that stream fragmentation is unrelated to IP fragmentation" could suffice?
I don't think this clarification is necessary. The context makes it clear what fragmentation this is, and talking about IP fragmentation only leads to confuse the reader. (I like the first part of your PR though, as I've noted on my review of it.)


Question: The entries in the following table are registered by this document. <del> Additionally, each code of the format "0x1f * N + 0x21" for integer values of N (that is, "0x21", "0x40", ..., through </del> <ins> Additionally, each code of the format "0x1f * N + 0x21" for non- negative integer values of N (that is, "0x21", "0x40", ..., through </ins> "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. 12.  References

Clarify reserved values for stream types, settings identifiers, frame types, and error codes. 0x1f N + 0x21 for the value of N = -1 is 0x02. Literal interpretation of the current text includes this as a reserved value. The parenthetical examples given in Section 11.2 make it clear that this was not the intention, rendering this PR editorial. The main motivation of this PR is not that the current text is inconsistent, but that parenthetical examples from 11.2 are necessary to correctly interpret the definitions in sections 6.2.3, 7.2.4.1, 7.2.8, and 8.1. Alternative wordings could be: "0x1f N + 0x21 for N = 0, 1, 2, ..." "0x1f N + 0x02 for positive integer values of N" "0x1f N + 0x02 for N = 1, 2, 3, ..." "0x21, 0x21 + 0x1f, 0x21 + 2 * 0x1f, ..." "a value of at least 0x21 with a remainder of 0x02 modulo 0x1f" "a value of at least 0x21 that is congruent to 0x21 modulo 0x1f" none of which is better than what this PR proposes.


Question: present, but an "AS" value is specified, generate a "TIAS" value using this formula: <del> TIAS = AS * 0.95 - 50 * 40 * 8 </del> <ins> TIAS = AS * 1000 * 0.95 - 50 * 40 * 8 </ins> The 50 is based on 50 packets per second, the 40 is based on an <del> estimate of total header size, and the 0.95 is to allocate 5% to RTCP.  If more accurate control of bandwidth is needed, "TIAS" should be used instead of "AS". </del> <ins> estimate of total header size, the 1000 is to change the unit from kbps to bps and the 0.95 is to allocate 5% to RTCP.  If more accurate control of bandwidth is needed, "TIAS" should be used instead of "AS". </ins> For any "RR" or "RS" bandwidth values, handle as specified in RFC3556, Section 2.

b=TIAS is specified in bits per second, b=AS in kbps. Hence the formula needs to multiply by 1000 to change units. Thanks NAME for catching this in code review.
Even though I noticed it in the code review I had not noticed it as an issue in the spec. Good catch!
nice catch - lgtm with minor comment
LGTM
LGTM to me as well. I updated the text in


Question: vouched for via Endorsements because no Evidence is generated about them are referred to as roots of trust. <del> The manufacturer of the Attester arranges for its Attesting Environment to be provisioned with key material.  The key material is typically in the form of an asymmetric key pair (e.g., an RSA or ECDSA private key and a manufacturer-signed IDevID certificate) secured in the Attester. The Verifier is provided with an appropriate trust anchor, or provided with a database of public keys (rather than certificates), or even carefully secured lists of symmetric keys.  The nature of how the Verifier manages to validate the signatures produced by the Attester is critical to the secure operation of an Attestation system, but is not the subject of standardization within this architecture. </del> <ins> The manufacturer having arranged for an Attesting Environment to be provisioned with key material with which to sign Evidence, the Verifier is then provided with some way of verifying the signature on the Evidence.  This may be in the form of an appropriate trust anchor, or the Verifier may be provided with a database of public keys (rather than certificates) or even carefully secured lists of symmetric keys. The nature of how the Verifier manages to validate the signatures produced by the Attester is critical to the secure operation of an Attestation system, but is not the subject of standardization within this architecture. </ins> A conveyance protocol that provides authentication and integrity protection can be used to convey unprotected Evidence, assuming the

` 1) Is this a normative statement? 2) I think the next paragraph says that maybe it’s not an asymmetric key, and anyways, keys are out of scope for RATS Arch
In a layered device architecture the previous layer "provisions" the next layer. Hence, it isn't possible for the 'manufacturer' entity to do that. I don't know why a section on "Verifier" is going into so much detail about the Attester.


Question: Captive Portal Signaling Protocol: Also known as Signaling Protocol. The protocol for communicating Captive Portal Signals. <ins> Captive Portal Session: Also referred to simply as the "session", a Captive Portal Session is the association for a particular User Equipment that starts when it interacts with the Captive Portal and gains open access to the network, and ends when the User Equipment moves back into the original captive state.  The Captive Network maintains the state of each active Session, and can limit Sessions based on a length of time or a number of bytes used.  The Session is associated with a particular User Equipment using the User Equipment's identifier (see ue_identity). </ins> 2. 2.1.

The idea of a session is important, both because it is used in the API document, and because it helps to tie everything together. Define it in the terminology.
This is a first stab at defining the session. I suspect we may need to iterate on it once or twice. Let me know if you think it deserves its own section on top of the terminology.
Thanks for doing this! Here’s a suggested alternate way to explain this. Feel free to modify as desired. Captive Portal Session: Also referred to simply as the “session”, a Captive Portal Session is the association for a particular User Equipment that starts when it interacts with the Captive Portal and gains open access to the network, and ends when the User Equipment moves back into the original captive state. The Captive Network maintains the state of each active Session, and can limit Sessions based on a length of time or a number of bytes used. The Session is associated with a particular User Equipment using the User Equipment's identifier (see ).
Your phrasing is better. It manages to work in the session limits while keeping it about the same lenght. I've taken it almost verbatim. NAME Do you have any input on this topic?
From Ben's review of the API document, we should define "session" formally in the architecture. The architecture doc mentions it in passing once already. The API doc uses the term session much more.


Question: MAX_STREAMS frames; see frame-max-streams.  Separate limits apply to unidirectional and bidirectional streams. <del> If a max_streams transport parameter or MAX_STREAMS frame is received with a value greater than 2^60, this would allow a maximum stream ID that cannot be expressed as a variable-length integer; see integer- encoding.  If either is received, the connection MUST be closed immediately with a connection error of type FRAME_ENCODING_ERROR; see immediate-close. </del> <ins> If a max_streams transport parameter or a MAX_STREAMS frame is received with a value greater than 2^60, this would allow a maximum stream ID that cannot be expressed as a variable-length integer; see integer-encoding.  If either is received, the connection MUST be closed immediately with a connection error of type TRANSPORT_PARAMETER_ERROR if the offending value was received in a transport parameter or of type FRAME_ENCODING_ERROR if it was received in a frame; see immediate-close. </ins> Endpoints MUST NOT exceed the limit set by their peer.  An endpoint that receives a frame with a stream ID exceeding the limit it has

I noticed this in the Transport Draft (ID-30): Is this intentional? Should an invalid transport parameter result in a frame encoding error?
I believe this aligns with our principles that a framing error which can be detected with no connection context is a FRAMEENCODINGERROR. Is there another error you'd suggest?
My concern is that transport parameter values have nothing to do with framing and using FRAMEENCODINGERROR is therefore misleading.
We only ever applied this principle to frames though, so I'm not sure we can use it as a precedent here. The name is indeed confusing, as it's FRAMEENCODINGERROR and not FRAMINGERROR or ENCODINGERROR.
I always rationalized this as "the encoded content of the CRYPTO frame is erroneous".
Well, if we've been through this before, I won't insist -- it's just something that jumped out at me.
That's even more confusing. The CRYPTO frame itself is totally fine. I'd be in favor of changing it to a TRANSPORTPARAMETERERROR.


Question: In some authentication systems, it is possible for a previously-valid credential to become invalid over time.  For example, in a system based on X.509 certificates, credentials can expire or be revoked. <del> Fortunately, the MLS update mechansisms allow a client to replace an old credential with a new one.  This is best done before the old credential becomes invalid. </del> <ins> The MLS update mechanisms allow a client to replace an old credential with a new one.  This is best done before the old credential becomes invalid. </ins> *RECOMMENDATION:* Proactively rotate credentials, especially if a credential is about to become invalid.

NAME noted in URL that an important function of the AS is to ensure that clients come to consistent evaluations of credentials. We should make that recommendation in this document, including the fact that consistency is needed when validity can change over time.


Question: nonce. For example, assuming the IV value is "6b26114b9cba2b63a9e8dd4f", the <del> connection ID sequence number is "3", and the packet number is </del> <ins> Connection ID Sequence Number is "3", and the packet number is </ins> "aead", the nonce will be set to "6b2611489cba2b63a9e873e2". 5.3.

From PR from NAME
Let's do another editorial pass and evtl. some re-org first and then address this issue. I think we all already agreed that we only need one of the two. So we only need to decide with name we keep.
I prefer to use the name "Path ID", as it is more intuitive in the context of multipath.
The conflict was solved. LGTM.Sounds good.


Question: The COSE_encrypt structure for the recipient is organized as follows: The 'protected', 'iv', 'aad', 'ciphertext' and 'recipients' fields <del> MUST be null. </del> <ins> MUST be nil. </ins> At a minimum, the 'unprotected' field SHOULD contain the 'alg' parameter as well as a parameter identifying the shared secret.

The document is updated to use the CDDL grammer from the latest version (-05) Fixed a couple of small errors where my thinking and my text did not match.


Question: An opaque blob that the client may use with a future Initial packet. <ins> An endpoint might receive multiple NEW_TOKEN frames that contain the same token value.  Endpoints are responsible for discarding duplicate values, which might be used to link connection attempts; see validate-future. </ins> 19.8. STREAM frames implicitly create a stream and carry stream data.  The

Is that not implied by the text here?
Kind of, but this text talks about the sender's perspective. Furthermore, checking for duplicates is inherently racy if you're using tokens for new connections while the old connection is still alive.
You know, I think that I put some proposed fixes for this in c016639e39c with rather than this branch. Moved it over here. NAME you approved , so I hope that moving that commit over here works for you.
Sec 13.2 of QUIC Transport explains what to do for the loss of a packet for every stream type except NEW_TOKEN. IMO it's nice but not critical to repair this loss, but I care less about how we resolve it than that we write it up.
Somewhat related question: Does this section fit better in the recovery draft?
I don't think so. This talks about the repair semantics of these frames, not the process of detecting loss. Recovery doesn't care about the distinction between PING and STREAM when it comes to repair.
LGTM, but do we need some text saying that when receiving a NEW_TOKEN frame, you MUST make sure that it's not a duplicate? Otherwise, a client might just save the token twice, and effectively reuse the token.


Question: If the client exceeds that limit, it MAY not be served. <del> The field is a List Structured Field of positive length.  The first member is named "expiring-limit" and its syntax is "service-limit", while the syntax of the other optional members is "quota-policy" </del> <ins> The field is a non-negative Integer.  Its value is named "expiring- limit". </ins> The "expiring-limit" value MUST be set to the "service-limit" that is <del> closer to reach its limit. The "quota-policy" is defined in quota-policy, and its values are informative. A "time-window" associated to "expiring-limit" can be communicated via an optional "quota-policy" value, like shown in the following example If the "expiring-limit" is not associated to a "time-window", the "time-window" MUST either be: </del> <ins> closer to reach its limit, and the associated "time-window" MUST either be: </ins> inferred by the value of "RateLimit-Reset" at the moment of the reset, or communicated out-of-band (e.g. in the documentation). <ins> The "RateLimit-Policy" field (see ratelimit-policy-field), might contain information on the associated "time-window". This field MUST NOT occur multiple times and can be sent in a trailer section. 5.2. The "RateLimit-Policy" response field indicates the "quota" associated to the client and its value is informative. The field is a non-empty List of quota policies (see quota-policy). A "time-window" associated to "expiring-limit" can be communicated via "RateLimit-Policy", like shown in the following example. </ins> Policies using multiple quota limits MAY be returned using multiple "quota-policy" items, like shown in the following two examples: This field MUST NOT occur multiple times and can be sent in a trailer section. <del> 5.2. </del> <ins> 5.3. </ins> The "RateLimit-Remaining" response field indicates the remaining "quota-units" defined in service-limit associated to the client. <del> The field is an Integer Structured Field and its value is </del> <ins> The field is a non-negative Integer expressed in "quota-units". </ins> This field MUST NOT occur multiple times and can be sent in a trailer section.

moves quota-policies from RateLimit-Limit -> RateLimit-Policyrequires WG discussion -
Given this hint from Mark URL I think it's fine to merge this PR (separate Policy from Limit) since there seems to be agreement to use different fields at least in this case.
Perhaps best to continue discussion in that issue before merging this? While the change will happen in a similar vein, we might want to wait to flesh out further details.
This seems quite arbitrary for a MUST; what is "too far in the future" and "too high"?
Agree, this is an tricky point. I think an implementation: MUST define internal threeshold of allowed values; MUST validate ratelimit fields according to those thresholds. I think we could borrow some text from Signature. See
OK, but RFC2119 language is for interoperability, and this doesn't provide any; different implementations (or deployments) are going to have different values, and that may cause issues. It'd be better to defines precise limits if you think this is important enough to merit a MUST. Personally, I'd remove the 2119 language and just give guidelines about what implementations should consider when they're looking for abuse.
Ok, great!
Addressed in
The draft today suggests putting quota policies, a list, into the header. But that's a sort of breaking change, because that header's equivalent is strictly a number (not a list) in most existing implementations. Could be kept as a plain number (like and ), and instead a new header like or some such can contain supplementary information? That way, the story for upgrading to this draft is simpler. Sorry if this is asked and answered.
iirc we considered this but we initially had some requests of conflating as much as possible in fewer fields. Probably it's a more interoperable choice. I am open in re-considering the idea, provided we get in touch with the current implementers including 3scale, kong and envoy cc: 3scale: NAME , kong: NAME , envoyproxy: NAME
There's no inherent problem in using a specific header for policies, and no issue in moving to use them from the 3scale side. The only downside is we're adding yet another header for rate limiting, currently 4 of them, which might raise a few eyebrows.