jiebi/CodeConvo huggingface dataset:
Change:
The issue suggests that any packet from the server validates the server's address, because it echoes the client's CID. I'm not sure that's correct, because the client might have chosen a zero-length SCID in its initial packet, and the server doesn't echo the ODCID in Initial packets. This PR generalizes the existing rules for servers -- receiving a sufficiently-complex DCID or a valid Handshake packet is actual proof of address ownership.
The address validation section dives right into what a server needs to do to validate the client, but it doesn't really address the client needs. This is pretty simple: any valid packet from the server validates the server address via the client-chosen destination connection ID. We just need to write that down here (it might be elsewhere, I would need to check).

Discussion:
Connection establishment implicitly provides address validation for both endpoints.  In particular, receipt of a packet protected with <del> Handshake keys confirms that the client received the Initial packet from the server.  Once the server has successfully processed a Handshake packet from the client, it can consider the client address to have been validated. </del> <ins> Handshake keys confirms that the peer successfully processed an Initial packet.  Once an endpoint has successfully processed a Handshake packet from the peer, it can consider the peer address to have been validated. </ins> <del> Additionally, a server MAY consider the client address validated if the client uses a connection ID chosen by the server and the </del> <ins> Additionally, an endpoint MAY consider the peer address validated if the peer uses a connection ID chosen by the endpoint and the </ins> connection ID contains at least 64 bits of entropy. <ins> For the client, the value of the Destination Connection ID field in its first Initial packet allows it to validate the server address as a part of successfully processing any packet.  Initial packets from the server are protected with keys that are derived from this value (see Section 5.2 of QUIC-TLS).  Alternatively, the value is echoed by the server in Version Negotiation packets (version-negotiation) or included in the Integrity Tag in Retry packets (Section 5.8 of QUIC- TLS). </ins> Prior to validating the client address, servers MUST NOT send more than three times as many bytes as the number of bytes they have received.  This limits the magnitude of any amplification attack that
Change:
This is a bit of a niche code, as it is only narrowly useful for signaling loss of paths. But people wanted it and it doesn't code that much. Note the target of this pull request. For .
I'm going to leave this for a bit, but if people like the idea, I plan to merge it into .
Thank you for the PR. This error code will be useful, as the only other way of closing the connection would be to use NO_ERROR. Then, it would be impossible to know why the connection was abruptly closed.Yes, there's value in having a way to fail URL suggestion, but lgtm

Discussion:
path is unusable.  This does not necessarily imply a failure of the connection - endpoints can continue sending packets over other paths as appropriate.  If no paths are available, an endpoint can wait for <del> a new path to become available or close the connection. </del> <ins> a new path to become available or close the connection.  An endpoint that has no valid network path to its peer MAY signal this using the NO_VIABLE_PATH connection error, noting that this is only possible if the network path exists but does not support the required MTU datagram-size. </ins> A path validation might be abandoned for other reasons besides failure.  Primarily, this happens if a connection migration to a new

An endpoint has reached the confidentiality or integrity limit for the AEAD algorithm used by the given connection. <ins> An endpoint has determined that the network path is incapable of supporting QUIC.  An endpoint is unlikely to receive CONNECTION_CLOSE carrying this code except when the path does not support a large enough MTU. </ins> The cryptographic handshake failed.  A range of 256 values is reserved for carrying error codes specific to the cryptographic handshake that is used.  Codes for errors occurring when TLS is
Change:
For all packets. For all network paths.
You are right it's not really incorrect , I just found it confusing giving potentially the impression that using multiple paths without CID is "easily" possible. How about this phrasing to be even more clear: "A zero-length Destination Connection ID field is used in all packets sent toward such an endpoint and this cannot be changed even if the network path changes."
Yes, good to call out this implicit exception.

Discussion:
migration, as the peer will be unable to respond if the pool is exhausted. <ins> An endpoint that selects a zero-length connection ID during the handshake cannot issue a new connection ID.  A zero-length Destination Connection ID field is used in all packets sent toward such an endpoint over any network path. </ins> 5.1.2. An endpoint can change the connection ID it uses for a peer to
Change:
This isn't critical, but it's clearer and easier to parse. All to the good.
Derrell Piper writes:
The one nit here regards this sentence: This seems right to me. You might rewrite this as: But I don't think that is appreciably better. I think we can close this with no action unless we get some enthusiasm for rewording.
I think the issue is that "epoch starts is" looks like either an extra word or subject/verb agreement error. It's not actually; if you diagram the sentence out, "after the epoch starts" is in a dependent clause and "any packet ... is acknowledged" is correct agreement. That said, the rewording is easier to read because it doesn't look wrong and you don't have to try different possible parsings in your head before you find the one which works. We've tried to avoid trial decryption; let's avoid it in grammar, too.
Thanks, this seems like an improvement to me.

Discussion:
4.3. <del> QUIC starts a loss epoch when a packet is lost and ends one when any packet sent after the epoch starts is acknowledged.  TCP waits for the gap in the sequence number space to be filled, and so if a segment is lost multiple times in a row, the loss epoch may not end for several round trips.  Because both should reduce their congestion windows only once per epoch, QUIC will do it once for every round trip that experiences loss, while TCP may only do it once across multiple round trips. </del> <ins> QUIC starts a loss epoch when a packet is lost.  The loss epoch ends when any packet sent after the start of the epoch is acknowledged. TCP waits for the gap in the sequence number space to be filled, and so if a segment is lost multiple times in a row, the loss epoch may not end for several round trips.  Because both should reduce their congestion windows only once per epoch, QUIC will do it once for every round trip that experiences loss, while TCP may only do it once across multiple round trips. </ins> 4.4.
Change:
NAME I think you missed the change proposed to the reference. It should point to somewhere that imposes minimum datagram size (e.g., {{validate-handshake}}, not {{version-negotiation}}).
Urgh. Thanks for catching that, NAME sent.
([IPv4]), the DF bit MUST be set if possible, to prevent fragmentation on the path. However, the size of the datagram is not authenticated. Therefore, an endpoint MUST NOT close a connection when it receives a datagram that does not meet size constraints, though the endpoint MAY discard such datagrams. I really think this section needs re-writing for clarity.
I find this text perfectly clear, so I will need help in identifying in what ways the text lacks clarity.
Other than kazuho's nit which I regard as minor, this is good.

Discussion:
(IPv4), the DF bit MUST be set if possible, to prevent fragmentation on the path. <del> Datagrams are required to be of a minimum size under some conditions. However, the size of the datagram is not authenticated.  Therefore, an endpoint MUST NOT close a connection when it receives a datagram that does not meet size constraints, though the endpoint MAY discard such datagrams. </del> <ins> QUIC sometimes requires datagrams to be no smaller than a certain size; see version-negotiation as an example.  However, the size of a datagram is not authenticated.  That is, if an endpoint receives a datagram of a certain size, it cannot know that the sender sent the datagram at the same size.  Therefore, an endpoint MUST NOT close a connection when it receives a datagram that does not meet size constraints; the endpoint MAY however discard such datagrams. </ins> 14.1.
Change:
Since only servers can send NEW_TOKEN, using "client" is clearer. "Servers MUST treat" is used only here, so it is changed into "A server MUST treat".
Please see the for full context. This issue is tracking the following IANA question: >IANA Question --> Section 22.1.2 says, "Applications to register codepoints in QUIC registries MAY include a codepoint as part of the registration. IANA MUST allocate the selected codepoint unless that codepoint is already assigned or the codepoint is the first unallocated codepoint in the registry."
I think it is a good question that has two aspects. If a registrant is requesting additional consecutive values beyond an earlier registration is that okay? But other registrants they need to draw a new random value to not block the next value? Or any future allocation should have to select a new random value? Also, is it IANA or the designated expert that is making the determination if this request is allowed or not?
I think what this is intended to convey is: Permanent registrations for the first unallocated codepoint are intended for use in Standards-track documents The "negotiation" involved in a provisional registration is essentially to confirm that the requestor is doing so for use in a document which is likely to become a Standards-track RFC. It's the "likely to" that becomes squishy. Do we actually need this?
So in I have a comment that indicates a potential solution or direction for how to work with this using either of two process that will be clearer. Either provisional for test and development value and then assign a final value when approving the specification, or early allocation per RFC 7120. I also like to point out that there is very large hole in this algorithm. If a registry has assigned 0-N then asking for N+1 is rejected, but asking for N+2 is the approved without question per these rules unless you are in a registry with the special rules for 0-63 values.
Could we make some progress here?
I think fixes this too. NAME ?
This was fixed by
Thanks, NAME !

Discussion:
bytes. An opaque blob that the client can use with a future Initial <del> packet.  The token MUST NOT be empty.  An endpoint MUST treat receipt of a NEW_TOKEN frame with an empty Token field as a connection error of type FRAME_ENCODING_ERROR. </del> <ins> packet.  The token MUST NOT be empty.  A client MUST treat receipt of a NEW_TOKEN frame with </ins> <del> An endpoint might receive multiple NEW_TOKEN frames that contain the </del> <ins> A client might receive multiple NEW_TOKEN frames that contain the </ins> same token value if packets containing the frame are incorrectly <del> determined to be lost.  Endpoints are responsible for discarding </del> <ins> determined to be lost.  Clients are responsible for discarding </ins> duplicate values, which might be used to link connection attempts; see validate-future. <del> Clients MUST NOT send NEW_TOKEN frames.  Servers MUST treat receipt </del> <ins> Clients MUST NOT send NEW_TOKEN frames.  A server MUST treat receipt </ins> of a NEW_TOKEN frame as a connection error of type PROTOCOL_VIOLATION.
Change:
NAME You have a comment here pending. I'm planning to merge this PR in ~15 hours from now, so please say something now if you still would prefer a change.
Section 22.1.4: "For instance, the registries for 62-bit codepoints in this document have stricter policies for codepoints in the range from 0 to 63." Looking then at 22.2 it states: The "QUIC Transport Parameters" registry governs a 62-bit space. This registry follows the registration policy from Section 22.1. Permanent registrations in this registry are assigned using the Specification Required policy ([RFC8126]). No mention of the special registration rule for values in the 0-63 range. Section 22.3 and 22.4 do have these special rules. So should 22.1.4 be changed to state "may"/"sometime" have this rule. Or should a special rule be added to 22.2 and the version registry?

Discussion:
The creation of a registry MAY identify a range of codepoints where registrations are governed by a different registration policy.  For <del> instance, the registries for 62-bit codepoints in this document have stricter policies for codepoints in the range from 0 to 63. </del> <ins> instance, the frame type registry in iana-frames has a stricter policy for codepoints in the range from 0 to 63. </ins> Any stricter requirements for permanent registrations do not prevent provisional registrations for affected codepoints.  For instance, a <del> provisional registration for a frame type (iana-frames) of 61 could be requested. </del> <ins> provisional registration for a frame type of 61 could be requested. </ins> All registrations made by Standards Track publications MUST be permanent.
Change:
Sec 12.4 says: There is no specification of error handling in the case of zero frame. I would like to know what kind of error MUST be sent. Also, the packet formats contains the following field: Should we change this to the following?

Discussion:
The payload of a packet that contains frames MUST contain at least one frame, and MAY contain multiple frames and multiple frame types. <del> Frames always fit within a single QUIC packet and cannot span multiple packets. </del> <ins> An endpoint MUST treat receipt of a packet containing no frames as a connection error of type PROTOCOL_VIOLATION.  Frames always fit within a single QUIC packet and cannot span multiple packets. </ins> Each frame begins with a Frame Type, indicating its type, followed by additional type-dependent fields:
Change:
Please see the for full context. This issue is tracking the following IANA question:
Responded to e-mail as well, but for GitHub tracking purposes, I believe HTTP/3 should be its own registry page, separate from QUIC and analogous to HTTP/2.
NAME I think that is a good proposal.
Can we put that in the draft then?

Discussion:
New registries created in this document operate under the QUIC registration policy documented in Section 22.1 of QUIC-TRANSPORT. These registries all include the common set of fields listed in <del> Section 22.1.1 of QUIC-TRANSPORT. </del> <ins> Section 22.1.1 of QUIC-TRANSPORT.  These registries [SHALL be/are] collected under a "Hypertext Transfer Protocol version 3 (HTTP/3) Parameters" heading. </ins> The initial allocations in these registries created in this document are all assigned permanent status and list a change controller of the
Change:
Minimum packet size varies between the packet types (and other things like the length of CID being used). Therefore, the sentence is merely providing an example, and should be stated as such. .
Currently section 10.3 of the transport doc says: However, Version Negotiation packets are not guaranteed to be larger than 21 bytes. For example, a VN packet with an 0-byte destination connection ID, 8 byte source connection ID and single version would be 19 bytes. If a client receives such a packet, must it be dropped? This text suggests it must. But it's not clear to mean (or the slack channel) that this interpretation is expected. Of course, a server could work around this issue by appending a sufficient number of GREASE'd versions to make the packet large enough. But I'm not sure if that is mandatory?
The second sentence merely points out that QUIC packets that use AEAD can never be smaller than 21 bytes. VN packets do not use AEAD, hence that 21 byte limit does not apply. Of course, endpoints can do their own maths to figure out the minimal size of VN packets that they might receive. Just my two cents. We might want to clarify the italic part ("that use AEAD") in the specification.
I agree with NAME that the spec isn't technically wrong, but I find it unclear. It wouldn't surprise me if someone were to read this and add to their packet ingestion code. I think all we need here is an editorial clarification such as
Note: 21 is the correct number, as requires endpoints to expand the payload size to at least 4 + len(AEAD tag), so that we can always have full-sized entropy for header protection.
Thanks Kazuho, this is great. What I like about this is that it also implies the possibility of a higher minimum. For instance, the limit on long headers is higher (28 for Initial, 27 for 0-RTT and handshake if I'm right, but you can also add the minimum connection ID length for receiving to that).

Discussion:
stateless reset size. Endpoints MUST discard packets that are too small to be valid QUIC <del> packets.  With the set of AEAD functions defined in QUIC-TLS, packets that are smaller than 21 bytes are never valid. </del> <ins> packets.  To give an example, with the set of AEAD functions defined in QUIC-TLS, short header packets that are smaller than 21 bytes are never valid. </ins> Endpoints MUST send stateless reset packets formatted as a packet with a short header.  However, endpoints MUST treat any packet ending
Change:
I looked into the commits but I cannot identify the commit which removed this line.
Gah! Thanks NAME for catching this!!

Discussion:
An opaque blob that the client can use with a future Initial packet.  The token MUST NOT be empty.  A client MUST treat receipt <del> of a NEW_TOKEN frame with </del> <ins> of a NEW_TOKEN frame with an empty Token field as a connection error of type FRAME_ENCODING_ERROR. </ins> A client might receive multiple NEW_TOKEN frames that contain the same token value if packets containing the frame are incorrectly
Change:
Magnus Nystrom : not be able (based on no current known attack against static Huffman encodings) to mount the previously described "probing" attack? If so, adding a sentence at the end of the section along the lines of "Thus, the previously mentioned probing attack is not known to be applicable for any fields where static Huffman encoding is used."
This section is not related to the probing attack. I think some of the confusion here is lost formatting when importing from RFC 7541. The TOC should be:

Discussion:
at a time, reducing an exponential-time attack into a linear-time attack. <del> 7.2. </del> <ins> 7.1.1. </ins> QPACK mitigates but does not completely prevent attacks modeled on CRIME (CRIME) by forcing a guess to match an entire field line,

connection by different web origins (RFC6454) are made by mutually distrustful entities. <del> 7.3. </del> <ins> 7.1.2. </ins> Users of HTTP that require confidentiality for header or trailer fields can use values with entropy sufficient to make guessing

field name might occur for shorter values more quickly or with higher probability than for longer values. <del> 7.4. </del> <ins> 7.1.3. </ins> Implementations can also choose to protect sensitive fields by not compressing them and instead encoding their value as literals.

Note that these criteria for deciding to use a never-indexed literal representation will evolve over time as new attacks are discovered. <del> 7.5. </del> <ins> 7.2. </ins> There is no currently known attack against a static Huffman encoding. A study has shown that using a static Huffman encoding table created

attacker could not take advantage of this information leakage to recover any meaningful amount of information (see PETAL). <del> 7.6. </del> <ins> 7.3. </ins> An attacker can try to cause an endpoint to exhaust its memory. QPACK is designed to limit both the peak and stable amounts of memory

new streams, reading only from the encoder stream, or closing the connection. <del> 7.7. </del> <ins> 7.4. </ins> An implementation of QPACK needs to ensure that large values for integers, long encoding for integers, or long string literals do not
Change:
Removes the word ack-eliciting in the descriptive text to persistent congestion. It also contains minor text changes in the following of that section.
I'm taking the suggested changes and this PR. Thanks, NAME !
On the mailing list Timo Völker asked some questions about persistent congestion and why it was only applicable to in-flight packets. During the explanation, I realized that it should probably be ack-eliciting packets, not in-flight. UPDATE: It already is ack-eliciting in all but one spot. I wrote PR to fix that one spot.
To have the context, I quote your explanation. I think ack-eliciting makes more sense here than in-flight. At least, I understand that for the persistent congestion detection the first and the last packet need to be ack-eliciting. But why does this have to be true for packets sent between these two ack-eliciting packets? Here is an example for the edge case. The loss of three out of 50 packets let the sender consider this a persistent congestion. In general, I don't see a real issue here. But, I would like to understand why it is helpful to ignore the fact that non-ack-eliciting packets, sent between two lost ack-eliciting packets, have been acknowledged.
This absolutely should not be in flight packets. This may not cause a major issue as it stands but it is not technically correct.
The text is largely correct(ack-eliciting, not in-flight) already, based on my reading. Unfortunately, the very first description is incorrect, which is potentially confusing, so see
Looking good, one further suggestion.

Discussion:
7.6. <del> When a sender establishes loss of all ack-eliciting packets sent over a long enough duration, the network is considered to be experiencing persistent congestion. </del> <ins> When a sender establishes loss of all packets sent over a long enough duration, the network is considered to be experiencing persistent congestion. </ins> 7.6.1.

7.6.2. <del> A sender establishes persistent congestion on receiving an </del> <ins> A sender establishes persistent congestion after the receipt of an </ins> acknowledgement if at least two ack-eliciting packets are declared lost, and: <del> all packets, across all packet number spaces, sent between these two send times are declared lost; </del> <ins> all packets, across all packet number spaces, sent between the send times of two ack-eliciting packets are declared lost; </ins> the duration between the send times of these two packets exceeds the persistent congestion duration (pc-duration); and a prior RTT sample existed when both packets were sent. <ins> These two packets MUST be ack-eliciting, since a receiver is required to acknowledge only ack-eliciting packets within its maximum ack delay; see Section 13.2 of QUIC-TRANSPORT. </ins> The persistent congestion period SHOULD NOT start until there is at least one RTT sample.  Before the first RTT sample, a sender arms its PTO timer based on the initial RTT (pto-handshake), which could be
Change:
NAME rightly noted lack of clarity (), which this PR attempts to fix. There's a new MUST here, but I think it was again implicit. EDIT: Removed this MUST since NAME notes correctly that this is a definition, not an action.

Discussion:
7.6.2. A sender establishes persistent congestion after the receipt of an <del> acknowledgement if at least two ack-eliciting packets are declared </del> <ins> acknowledgement if two packets that are ack-eliciting are declared </ins> lost, and: all packets, across all packet number spaces, sent between the <del> send times of two ack-eliciting packets are declared lost; </del> <ins> send times of these two packets are declared lost; </ins> the duration between the send times of these two packets exceeds the persistent congestion duration (pc-duration); and <del> a prior RTT sample existed when both packets were sent. </del> <ins> a prior RTT sample existed when these two packets were sent. </ins> These two packets MUST be ack-eliciting, since a receiver is required to acknowledge only ack-eliciting packets within its maximum ack