jiebi/CodeConvo huggingface dataset:
Change:
URL a TLS stack. The canonical example being the Handshake keys, which are needed by a client to acknowledge partial server Handshake flights. TLS won't use those keys itself until it has the entire set of Handshake messages from the server. In doing this, I decided that it makes sense to reorder the sequence diagram to show what incoming packets trigger different events.
In order for the client to be able to acknowledge packets sent with Handshake encryption level, it needs to have access to the Handshake write key right after processing the ServerHello. URL states that the Handshake write key is exported after receiving the server's Finished message, which would make loss recovery of Handshake packets impossible. I found this fact non-obvious, and I think it should be documented in some way that we're deviating from the schedule in which a normal TLS 1.3 implementation would make new keys available.
I had the same realization a while ago, but failed to capture that in the spec. It's a fairly important point that - if ignored - would lead to bad outcomes, because a good part of the time you can get away with not exporting it early. You mostly just get transient errors... until the server can't fit its certificate into 3 packets, then you get a hard fail.

Discussion:
4.1.4. As keys for new encryption levels become available, TLS provides QUIC <del> with those keys.  Separately, as TLS starts using keys at a given encryption level, TLS indicates to QUIC that it is now reading or writing with keys at that encryption level.  These events are not asynchronous; they always occur immediately after TLS is provided with new handshake bytes, or after TLS produces handshake bytes. </del> <ins> with those keys.  Separately, as keys at a given encryption level become available to TLS, TLS indicates to QUIC that reading or writing keys at that encryption level are available.  These events are not asynchronous; they always occur immediately after TLS is provided with new handshake bytes, or after TLS produces handshake bytes. </ins> TLS provides QUIC with three items as a new encryption level becomes available:

process those acknowledgments in order to detect lost Handshake packets. <ins> QUIC also needs access to keys that might not ordinarily be available to a TLS implementation.  For instance, a client might need to acknowledge Handshake packets before it is ready to send CRYPTO frames at that encryption level.  TLS therefore needs to provide keys to QUIC before it might produce them for its own use. </ins> 4.1.5. exchange-summary summarizes the exchange between QUIC and TLS for both client and server.  Each arrow is tagged with the encryption level used for that transmission. <ins> exchange-summary shows the multiple packets that form a single "flight" of messages being processed individually, to show what incoming messages trigger different actions.  New handshake messages are requested after all incoming packets have been processed.  This process might vary depending on how QUIC implementations and the packets they receive are structured. </ins> 4.2. This document describes how TLS 1.3 TLS13 is used with QUIC.
Change:
by saying that, since error codes are extensible, you can't treat the receipt of an error code you don't understand or don't think you should have gotten as an error itself. (Though it can still be an error that the stream closed, regardless of the error code.) (Which leads to the question, should we be greasing the error code space?)
Yes! I would create a grease stream and it could be closed (stop sending and/or reset) by peers.
That seems to have very narrow applicability. Would you only be permitted to send a greasing error code in that case? Or to put the question differently, what would happen if you decided to randomly turn a subset of the semantic-ful error codes you generate into greasing codes?
Per the language of this PR, I think that would be fine. Possibly with the exception of the errors that are supposed to inform behavior, like REJECTED and perhaps EARLYRESPONSE.
The HTTP/3 spec is a little light on detail about processing an error code that should have never been sent. At NAME suggestion, this issue is scoped to discussion of HTTP/3 stream errors: Example a) a client receives a STOPSENDING with HTTPREQUESTCANCELLED Example b) a server receives a RESETSTREAM with HTTPLIMITEXCEEDED
I'm mostly inclined to treat this with the same fatalism as an invalid code in an APPLICATIONCLOSE code that makes no sense. The stream is gone, regardless of the error code. If it was a critical stream, then CLOSEDCRITICALSTREAM; otherwise, perhaps a MAY GENERALPROTOCOL_ERROR?
I agree with NAME The error code doesn't matter. What matters is how you handle it. Error codes with no specific handling are fine; error codes with special handling can be ignored. The question of what to do with critical streams is separable. Don't make things worse by coupling the two concepts.
Oh, totally separable. But then you'd then have two competing permissions-to-blow up -- because the critical stream close (regardless of error code) and because a stream closed with an invalid error code (regardless of which stream). And I don't think it matters which reason you have to blow up or what the resulting error is.

Discussion:
described in more detail in QUIC-TRANSPORT.  An endpoint MAY choose to treat a stream error as a connection error. <ins> Because new error codes can be defined without negotiation (see extensions), receipt of an unknown error code or use of an error code in an unexpected context MUST NOT be treated as an error.  However, closing a stream can constitute an error regardless of the error code (see request-response). </ins> This section describes HTTP/3-specific error codes which can be used to express the cause of a connection or stream error.
Change:
with some text in the TBD Security Considerations section.
If I understand correctly, the decoder stream buffer which endpoint has to keep grows indefinitely if encoder-side app does not return back flow control credit. The number of Header Acknowledgement instruction is bounded by the number of max blocked streams which decoder can specify. On the other hand, the number of Stream Cancellation is not bounded. So if encoder-side app keeps resetting stream without sending MAXSTREAMDATA, decoder-side has to keep all closed stream in decoder stream. I'm not sure this has been discussed already.
The solution to this seems implementation-dependent, but implementations should place a bound on the amount of data waiting to be sent on the decoder stream.
Hypothetically, this limit would create a way to force the peer to kill the connection by starving the decoder stream of flow control credit and then cancelling lots of streams. However, the consumer of (and therefore the entity which could fail to read) the decoder stream is the encoder, and the encoder can trivially cause the connection to close by emitting an invalid instruction anyway. That seems fine.
NAME writes: This is incorrect: an for each header that references the dynamic table.

Discussion:
TBD. <ins> While the negotiated limit on the dynamic table size accounts for much of the memory that can be consumed by a QPACK implementation, data which cannot be immediately sent due to flow control is not affected by this limit.  Implementations should limit the size of unsent data, especially on the decoder stream where flexibility to choose what to send is limited.  Possible responses to an excess of unsent data might include limiting the ability of the peer to open new streams, reading only from the encoder stream, or closing the connection. </ins> 8. 8.1.
Change:
This paper studies several "nonce hiding" transformations, of which the QUIC header protection algorithm is one. This change replaces the old analysis text with something a bit more crisp.
I'm really happy to see good research on this that confirms our intuitions about one of the most important QUIC-specific constructions. Thanks for doing this Chris. Are you planning to make a similar contribution to DTLS 1.3?
My pleasure. :-) Yep!

Discussion:
9.3. <del> Header protection relies on the packet protection AEAD being a pseudorandom function (PRF), which is not a property that AEAD algorithms guarantee.  Therefore, no strong assurances about the general security of this mechanism can be shown in the general case. The AEAD algorithms described in this document are assumed to be PRFs. The header protection algorithms defined in this document take the form: This construction is secure against chosen plaintext attacks (IND- CPA) IMC. </del> <ins> NAN analyzes authenticated encryption algorithms which provide nonce privacy, referred to as "Hide Nonce" (HN) transforms.  The general header protection construction in this document is one of those algorithms (HN1).  Header protection uses the output of the packet protection AEAD to derive "sample", and then encrypts the header field using a pseudorandom function (PRF) as follows: The header protection variants in this document use a pseudorandom permutation (PRP) in place of a generic PRF.  However, since all PRPs are also PRFs IMC, these variants do not deviate from the HN1 construction. As "hp_key" is distinct from the packet protection key, it follows that header protection achieves AE2 security as defined in NAN and therefore guarantees privacy of "field", the protected packet header. Future header protection variants based on this construction MUST use a PRF to ensure equivalent security guarantees. </ins> Use of the same key and ciphertext sample more than once risks compromising header protection.  Protecting two different headers
Change:
At the top of page 66 of the , we read: The second sentence seems to imply that a field could be omitted. Does this sentence sound odd to anyone else?
While it is perhaps technically redundant, I think it is actually quite helpful. The first sentence says, "complete" but that might be open to interpretation. The second sentence makes it clear what that means. I like it. YMMV :)
My issue is not with the redundancy of the second senteance, but rather with its meaning. The specification that "no fields be omitted" implies that fields could be omitted -- but they can't be: There are no optional fields in packet headers.
Maybe change the second sentence to something like:
NAME writes: The third sentence clarifies the first sentence well, too. I would just drop the second sentence altogether.
I can't remember now, but we did have an intermediate design where redundant fields were absent. This sentence may have crept in around then. I agree with NAME : it does seem redundant now.

Discussion:
packet in the datagram. Every QUIC packet that is coalesced into a single UDP datagram is <del> separate and complete.  Though the values of some fields in the packet header might be redundant, no fields are omitted.  The receiver of coalesced QUIC packets MUST individually process each QUIC packet and separately acknowledge them, as if they were received as the payload of different UDP datagrams.  For example, if decryption fails (because the keys are not available or any other reason), the receiver MAY either discard or buffer the packet for later processing and MUST attempt to process the remaining packets. </del> <ins> separate and complete.  The receiver of coalesced QUIC packets MUST individually process each QUIC packet and separately acknowledge them, as if they were received as the payload of different UDP datagrams.  For example, if decryption fails (because the keys are not available or any other reason), the receiver MAY either discard or buffer the packet for later processing and MUST attempt to process the remaining packets. </ins> Retry packets (packet-retry), Version Negotiation packets (packet- version), and packets with a short header (short-header) do not
Change:
This is a point NAME makes in , but it probably pays to make it more clearly. This was possible in earlier iterations of the draft, so it's worth stamping out residual mentions.
Section 4.5 of quic-tls: Early data within the TLS connection MUST NOT be used. As it is for other TLS application data, a server MUST treat receiving early data on the TLS connection as a connection error of type PROTOCOL_VIOLATION. As there is no way to express TLS application data (no record headers!) I believe there is no way for the proposed error condition to occur. I propose we strike the paragraph, though we might mention that this condition is impossible for clarity.

Discussion:
A QUIC server starts the process by providing TLS with the client's handshake bytes. <del> At any given time, the TLS stack at an endpoint will have a current sending encryption level and receiving encryption level.  Each encryption level is associated with a different flow of bytes, which is reliably transmitted to the peer in CRYPTO frames.  When TLS provides handshake bytes to be sent, they are appended to the current flow and any packet that includes the CRYPTO frame is protected using keys from the corresponding encryption level. </del> <ins> At any time, the TLS stack at an endpoint will have a current sending encryption level and receiving encryption level.  Each encryption level is associated with a different flow of bytes, which is reliably transmitted to the peer in CRYPTO frames.  When TLS provides handshake bytes to be sent, they are appended to the current flow and any packet that includes the CRYPTO frame is protected using keys from the corresponding encryption level. </ins> QUIC takes the unprotected content of TLS handshake records as the content of CRYPTO frames.  TLS record protection is not used by QUIC. QUIC assembles CRYPTO frames into QUIC packets, which are protected using QUIC packet protection. <ins> QUIC is only capable of conveying TLS handshake records in CRYPTO frames.  TLS alerts are turned into QUIC CONNECTION_CLOSE error codes; see tls-errors.  TLS application data and other message types cannot be carried by QUIC at any encryption level and is an error if they are received from the TLS stack. </ins> When an endpoint receives a QUIC packet containing a CRYPTO frame from the network, it proceeds as follows:

Section 4.2.10 of TLS13).  It then sends the application data in 0-RTT packets. <del> Early data within the TLS connection MUST NOT be used.  As it is for other TLS application data, a server MUST treat receiving early data on the TLS connection as a connection error of type PROTOCOL_VIOLATION. </del> 4.6. A server accepts 0-RTT by sending an early_data extension in the
Change:
Add short explanation and reference to explain why QUIC-TLS bans the use of post-handshake client authentication.
draft-tls section 4.4 (Peer Authentication) states: This sounds like there are security implications, but what they are is unclear. As a reader of the document, this makes me doubt my understanding of the protocol. If we don't have a good justification for banning this, we shouldn't be banning it. (This is me reopening since that was closed for being a question.)
Is the text unclear, or are you asking to re-enable post-handshake authentication?
At least I am curious about the reasoning behind this, not that I am against it.
NAME The best way to understand the rationale is to try to work through how a particular protocol might use this feature. Read , look at the design and discussion and see the sorts of problems it tries to address. In that case, some of the problems are with server-authentication, which you can safely ignore, but the general class of problems related to concurrency and how that relates to the status of authentication produce a fairly complex design. Now I might concede that it is possible to build a protocol that uses this TLS feature well, but I would still hold that are a far superior design.
NAME Thanks for the explantion and pointers. On exported authenticators I guess there is some overlap with OAuth2, Fido, and temporary web service tokens once you get past the handshake.
NAME if we have a good reason (which it sounds like we do), then this issue tracks adding that reason to the draft.
Now that NAME has clearly written this up, perhaps we can resolve this issue by adding a reference to URL in draft-ietf-quic-tls. If that sounds good to the editors I can write a PR.
I'd prefer more direct text. You get references to HTTP/2 doc and that in turn references TLS 1.2 with compression rules etc. that needs to be filtered out.
NAME : that sounds like a good way forward.
I'm going to say that this is editorial-enough to just merge. MUST NOT implies PROTOCOL_VIOLATION, so the new normative language is fine as editorial. I'll give others a chance to disagree though.

Discussion:
to authenticate when requested.  The requirements for client authentication vary based on application protocol and deployment. <del> A server MUST NOT use post-handshake client authentication (see Section 4.6.2 of TLS13). </del> <ins> A server MUST NOT use post-handshake client authentication (as defined in Section 4.6.2 of TLS13), because the multiplexing offered by QUIC prevents clients from correlating the certificate request with the application-level event that triggered it (see HTTP2-TLS13). More specifically, servers MUST NOT send post-handshake TLS CertificateRequest messages and clients MUST treat receipt of such messages as a connection error of type PROTOCOL_VIOLATION. </ins> 4.5.
Change:
It can result in an inflated RTT, as well as being a waste of bytes.
Even though a sender is encouraged to assemble frames containing up-to-date information every time it sends a packet, it is not forbidden to retransmit copies of frames from lost packets. A receiver MUST accept packets containing an outdated frame, such as a MAX_DATA frame carrying a smaller maximum data than one found in an older packet. URL If a packet containing an ACK is lost and the payload is retransmitted with a new packet number AND no ACKs are received prior to the retransmitted ACK frame arriving, the peer will calculate and RTT sample that is 2 RTTs + loss recovery delay. As such, I'd suggest we add a warning that retransmitting ACKs can cause RTT inflation and is heavily discouraged. There may be other issues with retransmitting ACKs, but this is the first that comes to mind.

Discussion:
stream.  Once an endpoint sends a RESET_STREAM frame, no further STREAM frames are needed. <del> The most recent set of acknowledgments are sent in ACK frames.  An ACK frame SHOULD contain all unacknowledged acknowledgments, as described in sending-acknowledgements. </del> <ins> ACK frames carry the most recent set of acknowledgements and the Ack Delay from the largest acknowledged packet, as described in sending-acknowledgements.  Delaying the transmission of packets containing ACK frames or sending old ACK frames can cause the peer to generate an inflated RTT sample or unnecessarily disable ECN. </ins> Cancellation of stream transmission, as carried in a RESET_STREAM frame, is sent until acknowledged or until all stream data is
Change:
The recommendation for a 25ms delayed ack time is in transport, not recovery, so remove it from recovery. Should this paragraph be moved to transport?
I think that it's fine to just cut this.
This paragraph didn't seem to relate to anything else in the document: Is it left-over from a previous version?
Thanks for pointing this out. The intent was to explain why 25ms was chosen, given it's smaller than most TCP implementations default delayed ack time. There were more exceptions before, but now there's only the one, which makes the preceding paragraph awkward as well. "The majority of constants were derived from best common practices among widely deployed TCP implementations on the internet. Exceptions follow."
I realized that the 25ms recommendation is in transport, so this is just out of place now.
Ah, I see, I remember I went looking for it in transport, but I think I looked for "delayed ack" and didn't come up with anything fitting. I've got no concrete suggestion how to resolve it but moving the notice to transport in some form would probably make sense.

Discussion:
might be destroyed sooner, as soon as handshake keys are available (see Section 4.9.1 of QUIC-TLS). <del> 5.6. The majority of constants were derived from best common practices among widely deployed TCP implementations on the internet. Exceptions follow. A shorter delayed ack time of 25ms was chosen because longer delayed acks can delay loss recovery and for the small number of connections where less than packet per 25ms is delivered, acking every packet is beneficial to congestion control and loss recovery. </del> 6. QUIC's congestion control is based on TCP NewReno RFC6582.  NewReno
Change:
In section "Time Threshold", is used for the first time. I guess that would reference the same value before called ? If that's the case they should be named the same. Further down in the same paragraph "smoothed SRTT" is used which is even more confusing. SRTT is used a few more times further down.
There was a cleanup a while ago to ensure definitions such as SRTT happened before use, but that might have been lost in recovery to transport migration?
:+1:

Discussion:
If packets sent prior to the largest acknowledged packet cannot yet be declared lost, then a timer SHOULD be set for the remaining time. <del> Using max(SRTT, latest_RTT) protects from the two following cases: </del> <ins> Using max(smoothed_rtt, latest_rtt) protects from the two following cases: </ins> <del> the latest RTT sample is lower than the SRTT, perhaps due to reordering where the acknowledgement encountered a shorter path; </del> <ins> the latest RTT sample is lower than the smoothed RTT, perhaps due to reordering where the acknowledgement encountered a shorter path; </ins> <del> the latest RTT sample is higher than the SRTT, perhaps due to a sustained increase in the actual RTT, but the smoothed SRTT has not yet caught up. </del> <ins> the latest RTT sample is higher than the smoothed RTT, perhaps due to a sustained increase in the actual RTT, but the smoothed RTT has not yet caught up. </ins> The RECOMMENDED time threshold (kTimeThreshold), expressed as a round-trip time multiplier, is 9/8.

This document does not specify a pacer, but it is RECOMMENDED that a sender pace sending of all in-flight packets based on input from the congestion controller.  For example, a pacer might distribute the <del> congestion window over the SRTT when used with a window-based </del> <ins> congestion window over the smoothed RTT when used with a window-based </ins> controller, and a pacer might use the rate estimate of a rate-based controller.
Change:
The Stream Types registry (URL) currently lists two types only (0 - control, 1 - push). While working on a dissector for the base HTTP/3 protocol, I ran across 2 and 3. It turns out these are defined in the QPACK document (URL) with 2 - QPACK Encoder Stream, 3 - QPACK Decoder Stream. Since QPACK has already been referenced multiple times from the -http document, what about mentioning (or registering) the two codepoints in the -http document and reference to the -qpack document for the definition?
We can, and as QPACK is a required component of HTTP/3, you'd probably need to support QPACK for that to work. However, this is an extensible space and your dissector would need to tolerate other types it might not recognize, or that are added by future extensions. So the fact that there are definitions in other documents not mentioned by HTTP/3 is to be expected.

Discussion:
Some stream types are reserved (stream-grease).  Two stream types are defined in this document: control streams (control-streams) and push <del> streams (push-streams).  Other stream types can be defined by extensions to HTTP/3; see extensions for more details. </del> <ins> streams (push-streams).  QPACK defines two additional stream types. Other stream types can be defined by extensions to HTTP/3; see extensions for more details. </ins> The performance of HTTP/3 connections in the early phase of their lifetime is sensitive to the creation and exchange of data on