jiebi/CodeConvo huggingface dataset:
Code change:
Some definitional work for terms that were poorly used. Note that "host" in the remaining uses is strictly interpreted in the RFC 1122 sense, so I left those alone. I considered sorting the terms section differently, and might still alphabetize that, but this isn't problematic just yet.
The word "host" is undefined. If it is equal to "endpoint", it should be replaced. Otherwise, "host" should" be defined in Sec 1.2. The word "address" sometime means "IP address" and "a pair of IP address and port" in other cases. Sec 1.2 should define "address" as "a pair of IP address and port". And "IP" should be added in front of "address" which means "IP address".
fixed this.
Thank you!

Related discussion:
text: associated with an existing connection, or - for servers - potentially create a new connection. <del> Hosts try to associate a packet with an existing connection.  If the packet has a non-zero-length Destination Connection ID corresponding to an existing connection, QUIC processes that packet accordingly. Note that more than one connection ID can be associated with a connection; see connection-id. </del> <ins> Endpoints try to associate a packet with an existing connection.  If the packet has a non-zero-length Destination Connection ID corresponding to an existing connection, QUIC processes that packet accordingly.  Note that more than one connection ID can be associated with a connection; see connection-id. </ins> If the Destination Connection ID is zero length and the packet <del> matches the local address and port of a connection where the host </del> <ins> matches the local address and port of a connection where the endpoint </ins> used zero-length connection IDs, QUIC processes the packet as part of that connection.
Code change:
The Retry packet can be discarded.
The Retry packet currently allows sending an empty token. The Retry token is defined as an opaque blob where "indicates that x is variable-length", which also includes zero-length values. On the wire, an Initial packet with a zero-length token is identical to an Initial without a token. However, there's a difference on the client side, since a client will perform at most a single Retry.
Tagging this editorial. This was clearly intended to be considered non-zero length.

Related discussion:
text: Clients MUST discard Retry packets that contain an Original Destination Connection ID field that does not match the Destination Connection ID from its Initial packet.  This prevents an off-path <del> attacker from injecting a Retry packet. </del> <ins> attacker from injecting a Retry packet.  A client MUST discard a Retry packet with a zero-length Retry Token field. </ins> The client responds to a Retry packet with an Initial packet that includes the provided Retry Token to continue connection
Code change:
Fixes issue
Sect. 7 in transport refers to packer number spaces without any reference to what that might mean. These are only introduced later in sect. 12.3. Also the text talks about crypto sequence numbers and the text is not very clear about these being different from packet numbers if you haven't been through TLS text.
This is still an issue. I think adding references to where packet number spaces are mentioned (List of Common Terms and Section 7) would be sufficient.
Sounds great, would you be willing to write a PR NAME
Fixed in .

Related discussion:
text: acknowledgment (see sending-acknowledgements). A packet that does not increase the largest received packet number <del> for its packet number space by exactly one.  A packet can arrive out of order if it is delayed or if earlier packets are lost or delayed. </del> <ins> for its packet number space (packet-numbers) by exactly one.  A packet can arrive out of order if it is delayed or if earlier packets are lost or delayed. </ins> An entity that can participate in a QUIC connection by generating, receiving, and processing QUIC packets.  There are only two types
Code change:
Fixes issue
Sect. 7 in transport refers to packer number spaces without any reference to what that might mean. These are only introduced later in sect. 12.3. Also the text talks about crypto sequence numbers and the text is not very clear about these being different from packet numbers if you haven't been through TLS text.
This is still an issue. I think adding references to where packet number spaces are mentioned (List of Common Terms and Section 7) would be sufficient.
Sounds great, would you be willing to write a PR NAME
Fixed in .

Related discussion:
text: An endpoint can verify support for Explicit Congestion Notification (ECN) in the first packets it sends, as described in ecn-validation. <del> The CRYPTO frame can be sent in different packet number spaces.  The sequence numbers used by CRYPTO frames to ensure ordered delivery of cryptographic handshake data start from zero in each packet number space. </del> <ins> The CRYPTO frame can be sent in different packet number spaces (packet-numbers).  The sequence numbers used by CRYPTO frames to ensure ordered delivery of cryptographic handshake data start from zero in each packet number space. </ins> Endpoints MUST explicitly negotiate an application protocol.  This avoids situations where there is a disagreement about the protocol
Code change:
Fixes issue
Thanks for this. It's a lot clearer this way.
restricts frame type varint encoding: The relevant sentence is: This means that the restriction may not apply to frames defined by QUIC extensions (such as the frame in the Delayed Acks_ extension). Must each extension spell out its own frame type encoding rules? It would be easier to change the transport draft to extend the minimal encoding restriction to not-as-yet-specified frames as well.
I read the first sentence as applying to all QUIC frame types, core or extensions. The examples confuse the matter by explicitly mentioning the core frames. Section 19.21 contains some guidance for extension frames, adding a pointer back to the encoding rules from would be a good editorial change.
The sentence I highlighted talks about frames in this document and then these frames, effectively overriding what the first sentence may imply.
yes I think we agree :)
I think we all agree that it can be made more explicit. The first sentence says that the rule for all frame types is that they be minimally encoded. Applying that principle to all frame types defined in this document means that they get one-byte encodings. We should clarify that it's an application of the rule, not a limitation of it.
Why did we have this rule in the first place? It just seems to complicate things in unexpected ways.
NAME See . IIRC the rationale for using minimal varint encoding is that stacks that support only the standardized frames can live with a simpler dispatch scheme that takes one byte as an input (regardless of the dispatch method being a table or a switch clause or whatever). While I do not have a strong opinion regarding that requirement, I'd prefer not revisiting the discussion.
PR has been merged -- closing bug.

Related discussion:
text: The Frame Type field uses a variable length integer encoding (see integer-encoding) with one exception.  To ensure simple and efficient implementations of frame parsing, a frame type MUST use the shortest <del> possible encoding.  Though a two-, four- or eight-byte encoding of the frame types defined in this document is possible, the Frame Type field for these frames is encoded on a single byte.  For instance, though 0x4001 is a legitimate two-byte encoding for a variable-length integer with a value of 1, PING frames are always encoded as a single byte with the value 0x01.  An endpoint MAY treat the receipt of a frame type that uses a longer encoding than necessary as a connection error of type PROTOCOL_VIOLATION. </del> <ins> possible encoding.  For frame types defined in this document, this means a single-byte encoding, even though it is possible to encode these values as a two-, four- or eight-byte variable length integer. For instance, though 0x4001 is a legitimate two-byte encoding for a variable-length integer with a value of 1, PING frames are always encoded as a single byte with the value 0x01.  This rule applies to all current and future QUIC frame types.  An endpoint MAY treat the receipt of a frame type that uses a longer encoding than necessary as a connection error of type PROTOCOL_VIOLATION. </ins> 13.
Code change:
These are all MUST in recovery and the editors discussed this and agreed that these should be MUST too.

Related discussion:
text: server, can cause a situation in which the server cannot send when the client has no data to send and the anti-amplification limit is reached.  In order to avoid this causing a handshake deadlock, <del> clients SHOULD send a packet upon a probe timeout, as described in </del> <ins> clients MUST send a packet upon a probe timeout, as described in </ins> QUIC-RECOVERY.  If the client has no data to retransmit and does not <del> have Handshake keys, it SHOULD send an Initial packet in a UDP datagram of at least 1200 bytes.  If the client has Handshake keys, it SHOULD send a Handshake packet. </del> <ins> have Handshake keys, it MUST send an Initial packet in a UDP datagram of at least 1200 bytes.  If the client has Handshake keys, it SHOULD send a Handshake packet. </ins> A server might wish to validate the client address before starting the cryptographic handshake.  QUIC uses a token in the Initial packet
Code change:
Clarifies why a client might send a Handshake packet, as well as improving the surrounding anti-deadlock text. Changes 2 SHOULDs to MUSTs to line up with recovery.
We don't provide examples of the weird cases where you need to send Handshake packets to prevent amplification deadlock. The strangest one is where the client has all Initial data (and therefore has Handshake keys), but never receives a Handshake packet from the server. In this case, the client needs to send a Handshake packet that won't contain ACK or CRYPTO frames. We should explain this in a note. See .
I think the logic in the recovery draft misses some of these cases entirely. The rule in draft 23 is: but in your example case there is not necessarily any unacknowledged data to transmit in a probe, and a is forbidden at Handshake level, leaving no reasonable options to compose an ACK-eliciting packet.
a few suggestions

Related discussion:
text: the server is not overly constrained by the amplification restriction. <del> Packet loss, in particular loss of a Handshake packet from the server, can cause a situation in which the server cannot send when the client has no data to send and the anti-amplification limit is reached.  In order to avoid this causing a handshake deadlock, clients MUST send a packet upon a probe timeout, as described in QUIC-RECOVERY.  If the client has no data to retransmit and does not have Handshake keys, it MUST send an Initial packet in a UDP datagram of at least 1200 bytes.  If the client has Handshake keys, it SHOULD send a Handshake packet. </del> <ins> Loss of an Initial or Handshake packet from the server can cause a deadlock if the client does not send additional Initial or Handshake packets.  A deadlock could occur when the server reaches its anti- amplification limit and the client has received acknowledgements for all the data it has sent.  In this case, when the client has no reason to send additional packets, the server will be unable to send more data because it has not validated the client's address.  To prevent this deadlock, clients MUST send a packet on a probe timeout (PTO, see Section 5.3 of QUIC-RECOVERY).  Specifically, the client MUST send an Initial packet in a UDP datagram of at least 1200 bytes if it does not have Handshake keys, and otherwise send a Handshake packet. </ins> A server might wish to validate the client address before starting the cryptographic handshake.  QUIC uses a token in the Initial packet
Code change:
Currently, the "Ignoring Loss of Undecryptable Packets" section indicates that some loss can be ignored, but now that we have multiple packet number spaces, I think we can constrain the set of ignorable losses to those below the smallest acknowledged packet in a packet number space. Ignoring the loss of a subsequently sent packet was not the intent.
I might have to put in a lint for HTAB...

Related discussion:
text: 6.6. During the handshake, some packet protection keys might not be <del> available when a packet arrives.  In particular, Handshake and 0-RTT packets cannot be processed until the Initial packets arrive, and 1-RTT packets cannot be processed until the handshake completes. Endpoints MAY ignore the loss of Handshake, 0-RTT, and 1-RTT packets that might arrive before the peer has packet protection keys to process those packets. </del> <ins> available when a packet arrives and the receiver can choose to drop the packet.  In particular, Handshake and 0-RTT packets cannot be processed until the Initial packets arrive and 1-RTT packets cannot be processed until the handshake completes.  Endpoints MAY ignore the loss of Handshake, 0-RTT, and 1-RTT packets that might have arrived before the peer had packet protection keys to process those packets. Endpoints MUST NOT ignore the loss of packets that were sent after the earliest acknowledged packet in a given packet number space. </ins> 6.7.
Code change:
It might pay to reconcile: {{vars-of-interest}}) to be larger than the congestion window, unless the packet is sent on a PTO timer expiration; see {{pto}}. And now exceeds the recently reduced congestion window. Now, you might implement the latter using PTO machinery, but that text doesn't really suggest that in any way.
Where does this second sentence come from? I'm pretty sure I haven't implemented anything like this in quic-go. Should I?
That sentence is the the definition of the . We haven't implemented that either, and I was wondering if it truly helps.
For TCP this second case if important because as long as you don't retransmit the lost packet you will not get any ACK that acknowledges new data. I guess we don't need that for QUIC.
The second sentence was added later in , and the MUST wasn't updated, so I'll fix that. Chromium currently implements PRR(RFC6937), which is a more complex variant of this which is designed to keep the ACK clock going. I thought we discussed adding an informative reference to PRR when we added this text, and I'm not sure why we didn't.
seems to be the wrong issue you are pointed to...
Good catch, it's
I've suggested some symbolic references.

Related discussion:
text: layer.  By providing reliability at the stream level and congestion control across the entire connection, it has the capability to improve the performance of HTTP compared to a TCP mapping.  QUIC also <del> incorporates TLS 1.3 at the transport layer, offering comparable security to running TLS over TCP, with the improved connection setup latency of TCP Fast Open RFC7413. </del> <ins> incorporates TLS 1.3 TLS13 at the transport layer, offering comparable security 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
Code change:
Having non-overlapping conditions makes sense; adjusted wording.
The recovery draft : This is consistent with the pseudocode, in particular . When the server receives the client's final handshake flight, it discards handshake keys and hence cannot acknowledge it. When the client receives the resulting , the handshake is confirmed, but no Handshake or 1-RTT acknowledgements have necessarily been received. This results in a PTO being set even though the client's address has certainly been verified and there are no ack-eliciting packets in flight. As written, the pseudocode would in fact set a PTO for the Initial space at a garbage time. I think this could be corrected by appending "and has not discarded handshake keys" or "and has not confirmed the handshake" to the language, and adding the analogous clause to the conditions checked in the final statement of .
I thought that was implied, but implications are bad, so I agree it's best to explicitly state it. I'm happy to review a PR if you have time to write one, or I'll fix this fairly soon ideally.
When a reverse proxy forwards a HTTP response to the client, sometimes it sees the upstream server terminate the response early. For example, a HTTP/1.1 connection being closed prior to transmitting number of bytes specified by the field. Or a chunked response being closed abruptly. The only way of delegating such a condition to the client in HTTP/2 was to send a RSTSTREAM frame with . However, use of the error code is awkward in this case, considering the fact that the error did not happen within the communication between the endpoints using the particular HTTP/2 connection. I think it makes sense to have an error code that better designates the case. One way to address the issue in H3 would be to change to , and let the server use the error code (as an argument of the RESET_STREAM frame) to indicate that the response has been "cancelled". Originally proposed in URL
What if you do not want to admit to being a proxy? (who does?)
HTTPMESSAGECANCELLED would simply mean that the transfer of the response is cancelled, regardless of the server being an origin or a reverse proxy.
I can get behind this. As long as we're not looking for a byte-by-byte reproduction of the bytes the intermediary received (as was once requested and rejected, I think at the Seattle interim), then it makes sense to signal that the message was killed.
This is basically an expansion of the CANCELLED/REJECTED codes to allow a server to do either. WFM.
NAME Yes. And thank you for the PR.

Related discussion:
text: unblock the server until it is certain that the server has finished its address validation (see Section 8 of QUIC-TRANSPORT).  That is, the client MUST set the probe timer if the client has not received an <del> acknowledgement for one of its Handshake or 1-RTT packets. </del> <ins> acknowledgement for one of its Handshake or 1-RTT packets, and has not received a HANDSHAKE_DONE frame. </ins> Prior to handshake completion, when few to none RTT samples have been generated, it is possible that the probe timer expiration is due to
Code change:
Now that we require a minimum packet size, this is no longer true.
Is this no longer true for the algorithms defined in the spec, or no longer true for any packet protection algorithms for any AEAD? It might be worth moving the note to the end of 5.4.1 instead.

Related discussion:
text: approach 2^(-L/2), that is, the birthday bound.  For the algorithms described in this document, that probability is one in 2^64. <del> In some cases, inputs shorter than the full size required by the packet protection algorithm might be used. </del> To prevent an attacker from modifying packet headers, the header is transitively authenticated using packet protection; the entire packet header is part of the authenticated additional data.  Protected
Code change:
The endpoint sends frames, which carry -- not send -- identifier values.
The way it's intended to parse, "An endpoint ... MUST NOT increase the value they send," is probably incorrect in number or gender. But yes, changing the verb to reflect that the subject is the frames instead of the endpoint is also an option.
OK. I have no preference how this sentence is fixed -- as long as it's fixed.
This looks good. While we are at this paragraph, why say "client?" GOAWAY can be sent by either side now.
It can, but a server isn't going to retry push streams on a new connection; it's going to decide de novo whether to push there. Arguably, nothing breaks if the client increases the Push ID on the server after the fact.
BTW, thanks for catching this. I appreciate how many of these ambiguities you're winkling out.
NAME NAME OK, lgtm, then.
Maybe, given the ambiguity, the right answer is to get rid of "they" in the first place?

Related discussion:
text: A client that is unable to retry requests loses all requests that are in flight when the server closes the connection.  An endpoint MAY <del> send multiple GOAWAY frames indicating different identifiers, but MUST NOT increase the identifier value they send, since clients might already have retried unprocessed requests on another connection. Receiving a GOAWAY containing a larger identifier than previously received MUST be treated as a connection error of type H3_ID_ERROR. </del> <ins> send multiple GOAWAY frames indicating different identifiers, but the identifier in each frame MUST NOT be greater than the identifier in any previous frame, since clients might already have retried unprocessed requests on another connection.  Receiving a GOAWAY containing a larger identifier than previously received MUST be treated as a connection error of type H3_ID_ERROR. </ins> An endpoint that is attempting to gracefully shut down a connection can send a GOAWAY frame with a value set to the maximum possible
Code change:
The text in 2.1 is more complete, so we don't need this.
When I read 3.0 I was a bit confused, because when the discussion of streams takes place in section 2.1, the requirement on stream ID ordering is already mentioned, but the reminder of what the types are is fresh in the mind. Perhaps this should be revised.

Related discussion:
text: opening of either the send or receive side causes the stream to open in both directions. <del> An endpoint MUST open streams of the same type in increasing order of stream ID. </del> These states are largely informative.  This document uses stream states to describe rules for when and how different types of frames can be sent and the reactions that are expected when
Code change:
In early versions of path validation, there was a requirement that PATH_CHALLENGE be sent on the same path. This is, for various reasons, either unnecessary or harmful, so we no longer have that requirement. But there was some residual text that assumed that property. This removes a paragraph citing symmetry directly, and rewords text that assumes return reachability - a property that QUIC no longer provides mechanisms for.
In , we removed the requirement that PATHRESPONSE be sent/received on the same path that PATHCHALLENGE was sent. However, there is still text in the document that relies on this assumption. In 8.5, it explains that receipt of the PATHRESPONSE on another interface doesn't cause validation to fail, because "It is possible that a valid PATHRESPONSE might be received in the future." But receipt of the PATHRESPONSE, over any interface is valid, and causes the validation to succeed. In 9.2, it suggests using path validation to demonstrate return reachability, but since PATHRESPONSE need not be sent on the same path, path validation doesn't demonstrate that.
Note that sending the response on the old path can lead to failures in "break before make" scenarios. Shall we mention that?

Related discussion:
text: a PATH_CHALLENGE frame is not adequate validation, since the acknowledgment can be spoofed by a malicious peer. <del> Note that receipt on a different local address does not result in path validation failure, as it might be a result of a forwarded packet (see off-path-forward) or misrouting.  It is possible that a valid PATH_RESPONSE might be received in the future. </del> 8.6. Path validation only fails when the endpoint attempting to validate