jiebi/CodeConvo huggingface dataset:
Change:
I tried to just make a note here saying "if you don't send many packets, you won't send many packets", but then decided that 3PTO is probably more sensible. As it is, 3 RTT is the value that the PTO is initialized to (validation almost always happens on a new path). And the loss of a single packet just doesn't cut it. Even 3 packets (the first packet, plus two on PTO, assuming two are sent on PTO) is not that strong, but at least it isn't insanely tight.
URL and URL describe ECN validation and they say : dropped by a faulty network element, an endpoint could set the ECT(0) codepoint for only the first ten outgoing packets on a path, or for a period of three RTTs, whichever occurs first. Initial PTO timeout is also 3RTT. If client does not get ACK for its first flight Initial, after 3RTT later, it resends Initial without ECT set because client is now in "UNKNOWN" state. If the first client Initial is really lost, ECN validation fails. It seems to me that it would be better to lengthen timeout or ensure enough packets are sent not limited by the timeout?
It seems like this particular problem was introduced by reducing the initial RTT from 500ms to 333ms (in ).
We use 3*PTO everywhere else, so suggesting it here makes sense to me.

Discussion:
If an endpoint has cause to expect that IP packets with an ECT codepoint might be dropped by a faulty network element, the endpoint could set an ECT codepoint for only the first ten outgoing packets on <del> a path, or for a period of three RTTs.  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the marking causes in loss. </del> <ins> a path, or for a period of three PTOs (see Section 6.2 of QUIC- RECOVERY).  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the marking causes in loss. </ins> An endpoint thus attempts to use ECN and validates this for each new connection, when switching to a server's preferred address, and on
Change:
I can't stop re-reading this text. There isn't much of it, but that makes it easier to spot little annoyances like this.

Discussion:
7. <del> It is possible that middleboxes could use traits of a specific </del> <ins> It is possible that middleboxes could observe traits of a specific </ins> version of QUIC and assume that when other versions of QUIC exhibit similar traits the same underlying semantic is being expressed. There are potentially many such traits; see bad-assumptions.  Some
Change:
This saves bytes (that's the most important reason). This uses something positive rather than something negative to define the instruction. Yes, it means that there are two "Literal"s in the name of an instruction. But now it says what is inside rather than what isn't.
NAME I can't solve all the problems :) I think that in HPACK "literal" was reserved for the value more than the name. Maybe this only highlights that...
I understand. This commit at least solves some of them, thank you for the improvement!
Beauty is in the eye of the beholder. What am I to do with all the "wonr" variable names?
Without Name Reference might be better replaced as "With Literal Name" (Damn my enter key...)
Also consider changing on line 1640, but GitHub won't let me comment that far from a change.I think this is an improvement. It has always bothered me that "literal field line" is used in sitations when only part of the field line is literal, and this change does not address that. An alternative would be: insert with literal name => insert literal field line (or literal entry) literal field line with name reference => field line with name reference and literal value literal field line with literal name => literal field lineSeems like a sensible change.

Discussion:
4.5.6. <del> The literal field line without name reference representation encodes a field name and a field value as string literals. </del> <ins> The literal field line with literal name representation encodes a field name and a field value as string literals. </ins> This representation begins with the '001' three-bit pattern.  The fourth bit is the 'N' bit as described in literal-name-reference.
Change:
The spec says: First of all, I have no idea what a "corruption of state" is supposed to be. More importantly, the second sentence seems to suggest that if an error only affects a single stream, it might not be required to send a connection-level error. I'm thinking of a stream-level flow control violation.
The challenge here is that the transport doesn't define how streams can be used by application layer protocols, but seems to want to strongly encourage how an application uses error codes. An example of "corruption of state" is something like a QPACK error that renders the HTTP/3 connection unusable because the QPACK state cannot be assured. In contrast, an application might treat receiving a header with an uppercase field name as a stream error that otherwise would not affect the rest of the H3 connection.
Anything remain to be done here?
It seems like NAME is interpreting this sentence as only applying to application protocol errors. If that's the intention, we should make that clear:
It's not exclusive to the application. Another example of corrupt state at the transport layer is CRYPTOBUFFEREXCEEDED -- you had to drop some bytes, so now your TLS handshake state is corrupted. As to the second piece, I think you're reading that backward. A stream error MAY always be promoted to a connection error if the implementation decides it's severe enough; it doesn't say anything about deciding to downplay errors if they're localized. If an error is defined to be a connection error, it's a connection error. If it's defined to be a stream error, however, you're always allowed to decide it's the last straw and walk away.
QUIC transport does not have stream-level errors, though applications can. As such, the last sentence references a circumstance that does not exist in the transport draft. So the best solution seems to be to remove the last sentence.
NAME : to your two points: "corruption of state that affects an entire connection" is clear that if the connection state is affected then it should result in a connection error agree that the second sentence seems unnecessary entirely, since stream-level errors are always treated as connection errors within the transport.

Discussion:
Errors that result in the connection being unusable, such as an obvious violation of protocol semantics or corruption of state that affects an entire connection, MUST be signaled using a <del> CONNECTION_CLOSE frame (frame-connection-close).  An endpoint MAY close the connection in this manner even if the error only affects a single stream. </del> <ins> CONNECTION_CLOSE frame (frame-connection-close). </ins> Application-specific protocol errors are signaled using the CONNECTION_CLOSE frame with a frame type of 0x1d.  Errors that are
Change:
Section 13.4.2: If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the marking causes in loss. s/in/the?

Discussion:
a path, or for a period of three PTOs (see Section 6.2 of QUIC- RECOVERY).  If all packets marked with non-zero ECN codepoints are subsequently lost, it can disable marking on the assumption that the <del> marking causes in loss. </del> <ins> marking caused the loss. </ins> An endpoint thus attempts to use ECN and validates this for each new connection, when switching to a server's preferred address, and on
Change:
So there are a couple of section references in the doc that points the wrong section in other documents. Section 6.2.1: "A sender SHOULD restart its PTO timer every time an ack-eliciting packet is sent or acknowledged, when the handshake is confirmed (Section 4.1.2 of [QUIC-TLS]), or when Initial or Handshake keys are discarded (Section 9 of [QUIC-TLS])", should that last ref be to section 4.9 in QUIC-TLS?"Section 6.4: "see Section 4.8 of [QUIC-TLS])" This is now Section 4.9.Section B.2: maxdatagramsize: The sender's current maximum payload size. Does not include UDP or IP overhead. The max datagram size is used for congestion window computations. An endpoint sets the value of this variable based on its PMTU (see Section 14.1 of [QUIC-TRANSPORT]), with a minimum value of 1200 bytes." Should that Section 14.1 reference be to 14.2.
Thank you for catching these, NAME

Discussion:
A sender SHOULD restart its PTO timer every time an ack-eliciting packet is sent or acknowledged, when the handshake is confirmed (Section 4.1.2 of QUIC-TLS), or when Initial or Handshake keys are <del> discarded (Section 9 of QUIC-TLS).  This ensures the PTO is always </del> <ins> discarded (Section 4.9 of QUIC-TLS).  This ensures the PTO is always </ins> set based on the latest estimate of the round-trip time and for the correct packet across packet number spaces.

6.4. <del> When packet protection keys are discarded (see Section 4.8 of QUIC- </del> <ins> When packet protection keys are discarded (see Section 4.9 of QUIC- </ins> TLS), all packets that were sent with those keys can no longer be acknowledged because their acknowledgements cannot be processed anymore.  The sender MUST discard all recovery state associated with
Change:
Could we also maybe add a pointer to the requirement that a DCID in an Initial must be eight bytes to Section 17.2? Because at the moment, it's buried in Section 7.2, where I didn't find it.
I've taken this change manually, after reverting the change to the invariants doc. After looking at this more closely, the invariants doc does not include specifics of how to generate a Version Negotiation packet and this takes an awkward step in that direction. Rather than start to import the rules into invariants piecemeal like this, I think that it is cleaner to leave the rules for generating a Version Negotiation packet as version-specific, which is already clearly the case.
Addendum: I missed the bit about this being a blanket "version-specific rules for packets". I've changed this to "version-specific rules for connection IDs", to reflect the context better. And to avoid tripping up on the packet size rules in version 1.
Since future QUIC versions might have different CID length requirements for Initial packets (or however that packet type will be called in that version), we already require servers to be able to send Version Negotiation packets with CIDs longer than 20 bytes (which is the maximum length that v1 allows). We need to clarify that this also applies to the minimum CID length, which is 8 byte for the DCID in v1. A future version of QUIC might relax this limit, so a server also needs to generate a VN packet if it receives a packet with an unknown version and a shorter DCID, otherwise it won't be possible to roll out such a QUIC version. This is coming out of a Slack discussion with NAME and NAME as well as recent tests on the interop runner. It turns out that 2 server implementations on the interop runner didn't get this right, and at least one server implementation that's not on the interop runner, but is running QUIC in production.
I think the CID specific aspect is fine. It is unclear what other aspects that are specified by the protocol and are not invariant here.

Discussion:
attacker. Future versions of QUIC may have different requirements for the <del> lengths of connection IDs larger than version 1.  In particular, connection IDs might not be required to have a minimum lengths, and might be longer than 20 bytes.  A server therefore MUST respond with a Version Negotiation packets for all lengths of connection IDs allowed by the layout defined here. </del> <ins> lengths of connection IDs.  In particular, connection IDs might have a smaller minimum length or a greater maximum length.  Version- specific rules for QUIC packets therefore MUST NOT influence a server decision about whether to send a Version Negotiation packet. </ins> The remainder of the Version Negotiation packet is a list of 32-bit versions that the server supports.
Change:
This could have been more explicit, so now it is. Doubly so.
Section 5.4.1, Figure 6: mask = headerprotection(hpkey, sample) I think it is a bit unclear that the headerprotection function is what is producing the stream cipher cipher text that will be masked and xored with the header bits. Especially as the instantiations of these functions for AESGCM (Section 5.4.3) and ChaCha20 (Section 5.4.4) is not defined as instantiation of that function, only as providing the same variable output. I think this could be clarified in both places so that the linkage between the general application and the stream cipher producing function is clear.
Looks good and resolve my issue.
indubitably

Discussion:
Removing header protection only differs in the order in which the packet number length (pn_length) is determined. <ins> Specific header protection functions are defined based on the selected cipher suite; see hp-aes and hp-chacha. </ins> fig-sample shows an example long header packet (Initial) and a short header packet. fig-sample shows the fields in each header that are covered by header protection and the portion of the protected packet

AES is defined in AES. This algorithm samples 16 bytes from the packet ciphertext.  This <del> value is used as the input to AES-ECB.  In pseudocode: </del> <ins> value is used as the input to AES-ECB.  In pseudocode, the header protection function is defined as: </ins> 5.4.4.

a sequence of 32-bit little-endian integers. The encryption mask is produced by invoking ChaCha20 to protect 5 <del> zero bytes.  In pseudocode: </del> <ins> zero bytes.  In pseudocode, the header protection function is defined as: </ins> 5.5.
Change:
If you receive a handshake ACK, then the server has validated the client's address, so it's really only Initial ACKs.
I think this is good.
There is an inconsistency in URL w.r.t. resetting PTO backoff factor. Section 6.2.1: This suggests that for a client to be certain that the server has finished validating the client's address, the handshake should have been confirmed. However, the pseudo code uses PeerCompletedAddressValidation to determine whether to reset pto-count and PeerCompletedAddressValidation also checks for Handshake ACK received. That is not what the text in 6.2.1 says, as, according to URL, the handshake is confirmed when HANDSHAKEDONE is received or when a 1-RTT ack is received. That is a subtle difference. As kazu noted in the discussion on Slack, Sec 8.1 of QUIC says: "Once the server has successfully processed a Handshake packet from the client, it can consider the client address to have been validated.", so, the client can consider that the server validated the client address when either ACK in Handshake or HANDSHAKEDONE in 1-RTT is received. (See Figure 5 of TLS.) Hence, the pseudocode seems to be correct and that means the text in 6.2.1 should be corrected.
Thanks for filing this, I think the new text is simpler anyway.

Discussion:
server from repeated client probes, the PTO backoff is not reset at a client that is not yet certain that the server has finished validating the client's address.  That is, a client does not reset <del> the PTO backoff factor on receiving acknowledgements until the handshake is confirmed; see Section 4.1.2 of QUIC-TLS. </del> <ins> the PTO backoff factor on receiving acknowledgements in Initial packets. </ins> This exponential reduction in the sender's rate is important because consecutive PTOs might be caused by loss of packets or
Change:
Text was already given the thumbs-up on the issue, so merging without waiting for review.
Section 3.2.2 states: "Prior to making requests for an origin whose scheme is not "https", the client MUST ensure the server is willing to serve that scheme. If the client intends to make requests for an origin whose scheme is "http", this means that it MUST obtain a valid http-opportunistic response for the origin as described in [RFC8164] prior to making any such requests. Other schemes might define other mechanisms." The first issue is that this text make normative use of RFC8164 to handle "http" scheme. RFC8164 is an experimental RFC. Thus we have a downref issue. I think it would be inappropriate to elevate RFC8164 status by allowing a downref here. I think one option would be to move the specification of the usage of RFC 8164 for the "http" URI scheme in HTTP/3 into its own experimental RFC. Another potential option is to simply inform about the ongoing experiment without specifying that it can be done with HTTP/3. Secondly, I am uncertain about the scope of the first sentence in that paragraph. Is there any other URI schemes other than "http" that this is applicable for? If it is which type of URI schemes is it applicable for? For clearly it is not applicable to the "rtsp" scheme that isn't using HTTP at all.
Second point first: HTTP doesn't restrict the scheme of URIs a client can request; URI schemes define what protocols can be used to access them, which might or might not include HTTP. For example, RFC7540 says: ":scheme" is not restricted to "http" and "https" schemed URIs. A proxy or gateway can translate requests for non-HTTP schemes, enabling the use of HTTP to interact with non-HTTP services. To the first point, I feel like not mentioning that RFC8164 can be done with HTTP/3 means it's irrelevant to include in this document, and the requirement to verify the peer can serve a scheme is necessary. Perhaps something like:
The proposed text looks good. I think that resolves it and you can move RFC8164 to be a informational ref. So I think this resolves my issue.
Based on this resolution, labeling this as "editorial"

Discussion:
Prior to making requests for an origin whose scheme is not "https", the client MUST ensure the server is willing to serve that scheme. <del> If the client intends to make requests for an origin whose scheme is "http", this means that it MUST obtain a valid "http-opportunistic" response for the origin as described in RFC8164 prior to making any such requests.  Other schemes might define other mechanisms. </del> <ins> For origins whose scheme is "http", an experimental method to accomplish this is described in RFC8164.  Other mechanisms might be defined for various schemes in the future. </ins> 3.3.
Change:
In Section 7.2.3: URL A server SHOULD send a CANCELPUSH frame even if it has opened the corresponding stream. Is the intention that this sentence should have this meaning? "A server that has opened a stream for a PUSH and is unable to fulfill this promise SHOULD send a CANCEL_PUSH frame with the corresponding Push ID." I think as currently formulated it is missing the criteria as well when this may occur. Secondly the alternative is also not clear. I assume this is a SHOULD as the stream can be reset with an error code? Does that need to be added and which error will be used? Especially as the next paragraph only discusses that the client SHOULD abort reading. Can't the server terminate the stream from its side? If only the later is allowed, I think that should be made explicit but appears unnecessary.
To the second question, stating clearly that the server can abort the Push stream with H3REQUESTCANCELLED seems like a good improvement.
Looking at the larger paragraph, the point is that there are two possible states when a server decides not to fulfill a push: a. No stream has been created; CANCELPUSH is sufficient. b. A stream has been created. The server could simply reset the stream; this is valid, but risks the client processing the RESET before learning the Push ID, so it won't know which Push ID is no longer being fulfilled. Better if the server both resets the stream and sends a CANCELPUSH. You're right that this could be reworded to emphasize that you always send CANCEL_PUSH if you're not fulfilling a promise, and also close the stream if you've opened one.
This seems like the right framing. But everything seems to correspond.

Discussion:
has already ended, the server MAY still abruptly terminate the stream or MAY take no action. <del> When a server sends CANCEL_PUSH, it is indicating that it will not be fulfilling a promise.  The client cannot expect the corresponding promise to be fulfilled, unless it has already received and processed the promised response.  A server SHOULD send a CANCEL_PUSH frame even if it has opened the corresponding stream. </del> <ins> A server sends CANCEL_PUSH to indicate that it will not be fulfilling a promise which was previously sent.  The client cannot expect the corresponding promise to be fulfilled, unless it has already received and processed the promised response.  Regardless of whether a push stream has been opened, a server SHOULD send a CANCEL_PUSH frame when it determines that promise will not be fulfilled.  If a stream has already been opened, the server can abort sending on the stream with an error code of H3_REQUEST_CANCELLED. </ins> Sending a CANCEL_PUSH frame has no direct effect on the state of existing push streams.  A client SHOULD NOT send a CANCEL_PUSH frame
Change:
NAME does this address your concerns?
Section 7.2.8: URL These frames have no semantics, and can be sent on any open stream when application-layer padding is desired. So I am uncertain if it is acceptable to shoehorn in a reserved frame after a frame that is supposed to be the last and then result in a close of the frame? Based on what is written I would lean to the interpretation that it is allowed, as the frame sender has decided to not close the stream yet, and thus it is open. If this is correct interpretation than it is up to the editor if they like to clarify more. Else something needs to be done.
The best example here is sending a reserved frame after a Request stream is opened by the client. Perhaps it is useful to call that out in section 4.1. is a bit loose. You can't send frames on qpack streams for instance, or as the first bytes on a push stream. Maybe we can rephrase it as, "Can be sent on any stream where frames are permitted to be sent"
There are no frames that close the stream, because stream closure is handled by the transport. SETTINGS is special in that it is required to be first, and is covered by : It would hypothetically apply to a future frame type which is required to come at the end of the stream as well, but we have no such frames at this time. ( does impose specific ordering on DATA and HEADERS frames relative to each other, but says nothing about other frame types.) NAME point is well-taken, and I'll take that text.
NAME does the PR address your issue?
Yes, I think this PR clarifies things a bit and are sufficient to resolve my issue.
Labeling this as "editorial" based on

Discussion:
connection error of type H3_FRAME_UNEXPECTED (errors).  In particular, a DATA frame before any HEADERS frame, or a HEADERS or DATA frame after the trailing HEADERS frame is considered invalid. <ins> Other frame types, especially unknown frame types, might be permitted subject to their own rules; see extensions. </ins> A server MAY send one or more PUSH_PROMISE frames (frame-push- promise) before, after, or interleaved with the frames of a response

Frame types of the format "0x1f * N + 0x21" for non-negative integer values of N are reserved to exercise the requirement that unknown types be ignored (extensions).  These frames have no semantics, and <del> can be sent on any open stream when application-layer padding is desired.  They MAY also be sent on open streams in connections where no data is currently being transferred.  Endpoints MUST NOT consider these frames to have any meaning upon receipt. </del> <ins> MAY be sent on any stream where frames are allowed to be sent.  This enables their use for application-layer padding.  Endpoints MUST NOT consider these frames to have any meaning upon receipt. </ins> The payload and length of the frames are selected in any manner the implementation chooses.