jiebi/CodeConvo huggingface dataset:
Also updates the transport parameter codepoint to 0xff03de1a from 0xff02de1a.
While reading the latest ack-frequency draft, I am confused with the wording that was added in URL If I have ack-eliciting threshold = 1, to me it means that I can receive 1 ack-eliciting packet before sending an ACK, i.e. I have to send ACK after receiving 1 packet. But looking at the example of 0, this interpretation looks wrong. NAME suggested, maybe the "before" needs to be "without" and an additional sentence added: "An immediate acknowledgement is sent when more than this number of packets have been received." I agree with his suggestion.
Thanks for the issues, this is a bit unclear. PTAL at
The definition that I use internally is "the number of packets you can receive without sending an immediate acknowledgment". This is different than saying "please acknowledge every N packets". The main benefit of this definition is that there are no invalid values for the number. I recommend making this adjustment in the frame definition: it will be more efficient (by a tiny amount), but it also removes the need to validate the value.
This seems like a good change, it's just a matter of writing the text.
My understanding is that if I am a receiver that wants to proactively cause a sender to stop sending, I should use the explicit way of sending a path abandon frame. The idle timeout handles the case when a receiver is unaware of a path change that leads to communication failure. If that is the purpose, as long as the receiver can receive packets in the sender-to-receiver direction and acknowledge on another path, it looks to me that we should still allow the sender to use that path. But I feel if we do that, we are diverging from the bidirectional nature of a path described in the draft, which worths more discussion.
I agree with NAME that if you want to close a path, you should use the abandon frame. This sentence covers the case where a path was idle for a while and therefore should be closed silently as it might not work anymore anyway. However, if you have received packet on the path or have an indication that packets you've sent on the path were received by the other end, the path is clearly not idle and working. I also agree with NAME that that means you only know for sure that the path is still working in one direction and that might need further discussion.
This was discussed in issue and PR .
Regarding the maxidletimeout, RFC9000 says "To avoid excessively small idle timeout periods, endpoints MUST increase the idle timeout period to be at least three times the current Probe Timeout (PTO)." As in multi-path QUIC, the PTO is per-path, when maxidletimeout is used to close a connection, it makes sense to set maxidletimeout = 3max(PTO1, PTO2). But when it comes to close a path, I am not sure if the timeout for path1 should also depend on the PTO of path 2?
I think there are two idle timeouts: the "connection idle timeout" and the "path idle timeout". For the "connection idle timeout", I agree that it should be at least 3PTO_max. Triggering this timeout closes the connection. For the "path idle timeout", this might be a way to have a stronger guarantee to stop using paths (closing them) after some inactivity than the text proposed in .
Still, if we define such a mechanism, we need to know whether all paths should have the same path timeout value or not (in the latter case, a transport parameter might not be the best way).
I would avoid having a different timer for a path than for a connection. That would make the protocol more complex without a lot of benefits. If a host wants to use a shorter timeout per path than the connection timeout, it can simply define it and use a PATH_ABANDON frame to indicate that the path is abandoned. However, we need to be clearer in 3.2.3 to indicate that a path can be considered valid if either packets are received on that path or packets sent on that path are acknowledged (possibly on another path)
Presented at IETF-113 but no time for discussion.
I have submitted PR to resolve this issue according to the above discussions.
PR was merged but forgot to close issue...
In 3.2.3, we have the following paragraph: When more than one path is available, servers shall monitor the arrival of non-probing packets on the available paths. Servers SHOULD stop sending traffic on paths through where no non-probing packet was received in the last 3 path RTTs, but MAY ignore that rule if it would disqualify all available paths. To avoid idle timeout of a path, endpoints can send ack-eliciting packets such as packets containing PING frames Section 19.2 of [QUIC-TRANSPORT] on that path to keep it alive. Sending periodic PING frames also helps prevent middlebox timeout, as discussed in Section 10.1.2 of [QUIC-TRANSPORT]. This paragraph implicitly indicates that we consider a path to be active if we send and receive packets on this path. This definition works well for MPTCP where each data packet triggers an ACK on the same path. In MPQUIC, a server could have two paths that it uses to send data. However, the client might decide to always send the ACKs on only one path (e.g. the lowest delay one). In this case, the two paths are clearly active, but the server could consider the higher delay path to be inactive since it does not receive packets over this path. It could send PING frames to trigger data packets, but then it would need to send one PING every 3 RTT, which seams excessive.
I would suggest to rewrite the text as follows (I removed Server, because I think the recommendation should be generic): When more than one path is available, hosts shall monitor both the arrival of non-probing packets and the acknowledgements for the packets sent over each path. Hosts SHOULD stop sending traffic on paths whether either: (a) no non-probing packet was received in the last 3 path RTT or (b) no non-probing packet sent over this path was acknowledged during the last 3 path RTT, but MAY ignore that rule if it would disqualify all available paths. To avoid idle timeout of a path, endpoints can send ack-eliciting packets such as packets containing PING frames Section 19.2 of [QUIC-TRANSPORT] on that path to keep it alive. Sending periodic PING frames also helps prevent middlebox timeout, as discussed in Section 10.1.2 of [QUIC-TRANSPORT].
The word "either" means that STOP sending becomes true If either (a) is true or (b) is true. If I understand correctly, the actual meaning is to use the word "both" here, instead. So stop sending if both (a) no non-probing packets received and (b) no packets was acknowledged.
Yes, I think this is a good clarification and yes "either" might be confusing here.
I commented on the PR. I don't like the idea that receivers would have to stop acknowledging packets in order to signal preference to not use a path. We need to think that a little more.
So we have a choice: either say that nodes should regularly send non-probing packets over the path that they want to keep using, or if we don't want that, accept the idea that acks on other paths show continuity, and require "abandon path" to terminate a path that is otherwise working, acknowledges packets, etc..
Yes, I think the second option is what we are aiming for with the new text. Stopping ack'ing packets to stop someone sending on a path is wrong and is something you should never do. If you receive a packet successfully you should ack it (also because that would otherwise confuse congestion control). But we have the abandon frame exactly for that case. However, it also seems wrong to me to require sending acks on the same path taen the data is received.
So if you decide to always only send ack on one path and all payload data flows into one direction only over multiple paths, the current text would require you to send potentially unnecessary ping packets over each non-ack'ing paths or you would end up closing those paths which also is wrong as everything seems to work fine. So the question is really is, do we want to require pings in this scenario (payload traffic over multiple paths but acks only on one path) in order to ensure that all paths are usable bidirectionally? I think that's unnecessary overhead and believe Olivier's proposed addition is the correct thing to do.
I can look at what I implemented in picoquic: If there is no traffic in either direction for the idle period, the path is automatically abandoned. If traffic is sent and acked, or traffic is received, the path is not considered idle. This is pretty much what Olivier proposed. If there is a "timer loss", and if there is an alternate, the path is put in a low priority list. The node will send ping and try get an ack. If no ack is received after N trials, the path is abandoned. If "abandon path" frame is received, the path is abandoned.
I marked this issue as editorial as we have an editorial PR for it. However, I open a new issue for the per path idle timeout discussion (). Do we need another issue to clarify path closure or sending of keep-alive traffic? However this might be covered in other parts of the draft already...?
The modified text looks good.Looks good to meThe text looks good to me.
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
URL CoAP over WebSockets The following now seems unrelated: Another possible configuration is to set up a CoAP forward proxy at the WebSocket endpoint. Depending on what transports are available Figure 12: CoAP Client (UDP client) accesses sleepy CoAP Server (WebSocket client) via a CoAP proxy (UDP server/WebSocket server) s/sleepy// (There is no mention of sleepiness here.) CoAP over WebSockets is intentionally very similar to CoAP over UDP. Therefore, instead of presenting CoAP over WebSockets as a new protocol, this document specifies it as a series of deltas from [RFC7252]. Probably best to delete that paragraph -- it is true not only for WS, but also for TCP. So why only here? 3.1. Opening Handshake Hmm, the title is confusing. WS also uses the same opening handshake as 2.3. The parts that relate to both TCP/TLS and WS/S need to be factored out. 3.2. Message Format The message format shown in Figure 14 is the same as the CoAP over TCP message format (see Section 2.4) with one restriction. The Length (Len) field MUST be set to zero because the WebSockets frame already contains the length. s/restriction/change/. The CoAP over TCP message format eliminates the Version field defined in CoAP over UDP. If CoAP version negotiation is required in the future, CoAP over WebSockets can address the requirement by the definition of a new subprotocol identifier that is negotiated during the opening handshake. This paragraph is a bit weird. Maybe: As with CoAP over TCP, the message format for CoAP over Websockets eliminates the Version field defined in CoAP over UDP. If CoAP Empty messages (Code 0.00) MUST be ignored by the recipient (see also Section 4.4). Why are we saying this here and not in Section 2? Factor out. 3.3. Message Transmission Similar as with CoAP over TCP, Retransmission and deduplication of messages is provided by the WebSocket protocol. CoAP over WebSockets therefore does not make a distinction between Confirmable or Non-Confirmable messages, and does not provide Acknowledgement or Reset messages. 3.4.
Connection Health There is no way to retransmit a request without creating a new one. Re-registering interest in a resource is permitted, but entirely unnecessary. (See the discussion we already had.) [Brian] - The reference is
Closing the Connection Does this mean, only the client must cancel the requests? Or should the server do this also? Then a clarfication may be useful.
The original - URL - was specific to Observe: ~ All updates to Observe are now captured in a single place - Appendix A. This specific case is in URL At this point, I think that Closing the Connection could simply be deleted because there are no specific changes required.
Let's say a client has sent one or more requests to a server but hasn't received any response yet, and/or is observing a resource at a server. If the client or the server closes the connection or if the connection goes down unexpectedly, then the client will never receive the responses or any further notifications. The client has to reconnect and send new requests. Neither the client nor the server needs to send anything to cancel active requests before closing the connection; when a connection closes, all active requests are canceled automatically. The client should signal that to the code waiting for the responses, e.g., by throwing an exception. The server should abort processing the requests or at least discard the responses once the requests have been processed. The server also should remove the client from the lists of observers (at latest when it tries to send the next notification and it notices that the connection is down).
URL General - It's not clear "how" mandatory the use of the CSM is. Clause 2.3 on TCP/TLS indicates that the CSM message must be sent at the start of the connection. Clause 3.1 on Websockets makes no mention of CSM messages. Clause 4.3 indicates that the CSM MUST be sent at the start of the connection also and makes no distinction between TCP/TLS and Websockets. Clause 2.3 also indicates that the connection must be aborted if the CSM is missing or invalid as the first message on the connection. Given the discussion about address changes does more information need to be provided what start of connection means?
In the , the intent of this statement is unclear: There is no way to retransmit a request without creating a new one.
Re-registering interest in a resource is permitted, but entirely unnecessary.
Response from Klaus Hartke: In general, CoAP clients are not allowed to use a token while it is still in use. RFC 7641 defines an exception: a client is allowed to confirm its interest in receiving notifications for a resource by sending a request identical to the original registration request, including the token that is already in use. The above paragraph just says that this is also the case for CoAP over TCP/TLS/WebSockets, but points out that sending a Ping (which checks the health of the connection and hence of all active observations) is better than confirming the interest for all active observations individually. Response from Carsten: Yes, the text is much easier to understand in that context — in the old draft, it was clear that this talks about reregistering interest. So in the new text, we probably need to prefix a sentence like For use with UDP, RFC 7641 discusses ways to re-register interest in a resource to deal with the case that the server providing this resource might have lost the information about this interest. In CoAP over TCP, the framework of the current connection provides fate-sharing between the health of the connection and the health of the expression of interest.
After further review, I think that this note belongs in Appendix A with the other updates/guidance for Observe on reliable transports. Connection Health should limit its discussion to WebSocket specific changes - in this case, the use of the CoAP Ping Signaling message instead of WebSocket Ping/Pong.
Addresses
In the architecture document, I noticed that we sometimes say "Transport Services system" and sometimes "Transport System". Are these the same? Are "Transport Services implementation" and "Transport System implementation" the same, too?
I prefer "Transport Services system" and "Transport Services implementation"
I find it long and clumsy :( Side note: we'll have to rename it everywhere in the API draft too if we go with this.
was this fixed by ?
Yes it was. We already used Transport Services most places so it's not all that different.
Looks good, thanks!
This does not handle the removal of DH uses instead of KEM which will be done as part of Issue / PR ...
I would be happier if this PR were moving the draft to use draft-barnes-cfrg-hpke, which is one of the changes I had in mind for -04. Do you think that's premature?
This text is wrong:
This could also be addressed by using draft-barnes-cfrg-hpke.
This has been fixed by
Enable, e.g., P-256 with both AES-GCM and ChaChaPoly Re-use code points from TLS
We should discuss that today
This defines a limit on the number of packets that can fail authentication before you have to use new keys. There is a big hole here in that AES-CCM (that is, the AEAD based on CBC-MAC) is currently permitted, but we have no analysis to support either the confidentiality limits in TLS 1.3 or the integrity limits in this document. It is probably OK, but that is not the standard we apply here. So this might have to remain open until we get some sort of resolution on that issue. My initial opinion is to cut CCM from the draft until/unless an analysis is produced.
In the interest of transparency, I have added one more commit here. When I did the same for DTLS, ekr observed that if you have updated, you might safely stop trying to accept packets with the old keys rather than killing the connection. That results in loss for any packets that genuinely did want to use the exhausted keys, but that is probably less disruptive than having the connection drop. Of course, you can't always update, so closure is still likely necessary in some cases.
For what it's worth, Martin, Felix, and I put together a document which might help users do this themselves: URL
NAME Could you use that to come up with 2^16 limits and put them in the doc? I’m really wary of letting implementors roll their own
Sure! Can you please file an issue with that request? Noting anything else you'd like spelled out in detail would be helpful, too.
tl;dr We need to recommend limits on the number of failed decryptions. At one of the side discussions concentrated on the quality of the analysis of the and the applicability of that analysis to QUIC. Felix Günther, along with Marc Fischlin, Christian Janson, and Kenny Paterson have done a little analysis, based on and the we used to set limits in TLS. There are two relevant limits in this analysis: The confidentiality bound, which is usually expressed in terms of advantage an attacker gains in being able to break confidentiality of records/packets as they get more data from valid packets.
For instance, in AES-GCM, the analysis shows that after seeing 2^24.5 packets (almost 24 million) the attacker has a 2^-60 better chance than pure chance of winning the IND-CPA game. The forgery bound, which is again expressed as an probably of an attacker successfully creating a forged record/packet. Thanks to the analysis done previously, we know that AES-GCM and ChaCha20+Poly1305 have a forgery chance of 2^-57 after 2^60 and 2^36 forgery attempts respectively. The current text just points to TLS 1.3, which recommends the use of key updates to protect confidentiality. But TLS has a forgery tolerance of 0: a single failed forgery attempt causes the connection to break. QUIC (and DTLS) allow for multiple forgeries to be ignored, so we need to factor that in. As discussed in if we want to maintain security, we need to consider both confidentiality and integrity. For that we need two independent limits: The number of packets that are successfully encrypted and decrypted. The number of packets that are unsuccessfully decrypted. We have the former already. The latter is what this issue tracks. Once the limit is at risk of being exceeded, updating keys will force the attacker to start over. Based on Felix's recommendation I am going to suggest that we limit forgery attempts to 2^36. I have confirmed this with a close reading of the paper and concur. There is a significant difference here between AES-GCM and ChaCha20+Poly1305 but we believe that setting a single limit is the best approach. I will create a pull request to document this approach shortly. We could split the recommendation and allow a larger limit for AES-GCM, but I don't believe that 2^36 (~68 billion) is a significant barrier. For reference, if you were able to saturate a 10Gbps link with 50 byte IP packets that contained plausible QUIC packets, and the recipient didn't treat this as DoS traffic, it would take 5 minutes. If we assume that are more likely representative of potential packet rates, then the limit goes up to 10s of hours.