jiebi/CodeConvo huggingface dataset:
Change:
This LGTM, but it will need chair approval eventually.
This is also applies to the transport parameters, doesn’t it?
Good point, I think it does.
I now mention the transport parameters and incorporated a version of Martin's suggested text. PTAL.
2^60 is too large as well, as 2^62 cannot be expressed as a variable-length integer, either.
I believe 2^60 means stream IDs of that type with Stream IDs less than 2^62 can be opened, but those equal and greater cannot. ie: MAX_STREAMS of 1 means a single stream can be opened, and that stream will have an ID less than 1 * 2^2 = 4.
NAME I see. You're right -- thanks.
Currently, stream IDs are as high as 2^62-1. The MAXSTREAMS frame specifies a limit as a varint that has a max value of 2^62-1 that translates to a Stream ID of 4 * maxstreams + initialstreamidfortype. This is larger than the max expressible stream ID, so we should specify what happens in this case. I'm suggesting that we allow all streams to be opened and MUST NOT close the connection in PR
Good idea.
I don't have a strong opinion, but this seems like a bug at the peer. I would be inclined to specify that an endpoint MUST NOT advertise max streams that are too large, and close the connection (with PROTOCOL_VIOLATION) if a value is received that is too large.
I'd also lean towards closing the connection (probably with a TRANSPORTPARAMETERERROR, not a PROTOCOL_VIOLATION though). Interestingly, we have the following definition for packet numbers but no such thing for stream IDs, although this is implied by the way we encode them.
I'm happy to close the connection as well, as long as the behavior is well-defined.
On PR , NAME noted that this logic should apply to the equivalent transport param as well.
Wordsmithing, but content is fine.

Discussion:
MAX_STREAMS frames (frame-max-streams).  Separate limits apply to unidirectional and bidirectional streams. <ins> If a max_streams transport parameter or MAX_STREAMS frame is received with a value greater than 2^60, this would allow a maximum stream ID that cannot be expressed as a variable-length integer (see integer- encoding).  If either is received, the connection MUST be closed immediately with a connection error of type STREAM_LIMIT_ERROR (see immediate-close). </ins> Endpoints MUST NOT exceed the limit set by their peer.  An endpoint that receives a STREAM frame with a stream ID exceeding the limit it has sent MUST treat this as a stream error of type STREAM_LIMIT_ERROR
Change:
in the PRIORITY frame
I agree, this doesn't seem to mesh with the discussion on the issue. If nothing else, it introduces the inconsistency NAME pointed out, but the gist of the issue seems to be that a receiver MAY check that it's zero.
NAME Are you in favor of changing MUST to MAY, should I discard the PR, or have I misunderstood your comment completely?
MUST => MAY
PR kicked up a bit more controversy than expected, so I'm opening an issue. Currently he Empty bits it the PRIORITY frame MUST be zero and MUST be ignored by the receiver. In most other areas, we're killing connections for this kind of violation. Then again, HTTP/3 is a different protocol from QUIC. What do people think?
Closing the connection SGTM.
I can live with must be zero and connection error if not.
Which means drop requirement to ignore them.
I'd keep the requirement to ignore them on receipt -- why require more unnecessary checking?
That works, but then state that their value is completely meaningless and should not be interpreted as anything
NAME you want to add verbiage in addition to this?
Looking back to HTTP/2, it had this to say about in-frame PADDING in DATA frames. Padding octets MUST be set to zero when sending. A receiver is not obligated to verify padding but MAY treat non-zero padding as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. URL
That is probably OK here as well. Though the need is less acute for a 4 bit field. Padding in DATA can be arbitrarily large. Either way, the hope would be that at least a few implementations check and enforce.
I don't see how this agrees with the field requirement that empty bits are ignored Empty: A four-bit field which MUST be zero when sent and MUST be ignored on receipt.

Discussion:
PRIORITY frame sent on a control stream with the Prioritized Element Type set to "11" MUST be treated as a connection error of type HTTP_MALFORMED_FRAME.  A PRIORITY frame with Empty bits not set to <del> zero MUST be treated as a connection error of type </del> <ins> zero MAY be treated as a connection error of type </ins> HTTP_MALFORMED_FRAME. When a PRIORITY frame claims to reference a request, the associated
Change:
It seems appropriate given that the term is used elsewhere in the text. However, I am sorry if there is a specific reason for keeping "HTTP over QUIC" here.
This matches HPACK (Header Compression for HTTP/2), so sure. I guess if we use vanilla QPACK for HTTP/4+ people will figure it out. circleci failed but the error appears unrelated.
Thanks.

Discussion:
<del> QPACK: Header Compression for HTTP over QUIC </del> <ins> QPACK: Header Compression for HTTP/3 </ins> draft-ietf-quic-qpack-latest Abstract
Change:
Some infrastructures are likely to load balance on port as well as address.
"Address" has been taken to mean IP and port in other contexts, but no harm in being extra precise here.

Discussion:
endpoint does not support connection migration (migration).  Peers of an endpoint that sets this transport parameter MUST NOT send any packets, including probing packets (probing), from a local <del> address other than that used to perform the handshake.  This parameter is a zero-length value. </del> <ins> address or port other than that used to perform the handshake. This parameter is a zero-length value. </ins> The server's preferred address is used to effect a change in server address at the end of the handshake, as described in
Change:
All of them have defaults.
If you mean "Is sending TP mandatory", I don't think so. An endpoint that doesn't receive a TP assumes the default value. An endpoint that uses a default value does not need to advertise it.
The issue could have been more precisely worded. The question was about the entire QUIC transport parameters extension. Individual parameters are still clearly optional. We should be very crisp about that. Up until -18, this was mandatory, but we don't need the version parameters any more.
One nice property of making the TLS transport parameters extensions mandatory is that it helps mitigate cross-protocol attacks: QUIC servers can abort the connection if it's missing and TLS over TCP servers can abort if the extension is present.
I think we can call the entire extension as an option. As to NAME point, I'm not sure if it helps in practice. TLS 1.3 stacks that run on top of TCP does not have (and it's doubtful if all of them would have) the capability to detect and raise an error when it sees the QUIC TP extension.
Our defense for cross-protocol attacks is ALPN. Then key separation, and probably other things. While layers of defense is generally a good idea, transport parameters don't need to be another secondary layer.
I agree with NAME and NAME points. This was more of a belt-and-suspenders approach. That said, I still think every single deployment will actually send transport parameters, therefore requiring the extension to be present sounds simpler to implement. But I don't feel too strongly about this.
The question arose when we realized that you can have a perfectly functional stack with the defaults. And it was non- trivial sending any. However, if the client doesn't send any, it prevents the server from sending any. That seems bad.
That argument is more compelling than mine.
Discussed in Prague; no pushback against making them mandatory.
NAME can you make that into a PR?
There already is a PR, it just wasn't tagged properly as closing this issue.

Discussion:
TRANSPORT is used. The quic_transport_parameters extension is carried in the ClientHello <del> and the EncryptedExtensions messages during the handshake. </del> <ins> and the EncryptedExtensions messages during the handshake.  Endpoints MUST send the quic_transport_parameters extension; endpoints that receive ClientHello or EncryptedExtensions messages without the quic_transport_parameters extension MUST terminate the TLS handshake with a fatal missing_extension alert (an error of 0x16d). </ins> While the transport parameters are technically available prior to the completion of the handshake, they cannot be fully trusted until the
Change:
This was fun, it turns out there were actually 3 pair of instances where the were added. I wonder if this was super meta level protest against the endianess-swap from back in the day...
Draft 19 has rendering issue for the reserved frame type in section 10.4

Discussion:
Additionally, each code of the format "0x1f * N + 0x21" for integer values of N (that is, "0x21", "0x40", ..., through <del> "0x&#8237;3FFFFFFFFFFFFFFE&#8236;") MUST NOT be assigned by IANA. </del> <ins> "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. </ins> 10.4.

Additionally, each code of the format "0x1f * N + 0x21" for integer values of N (that is, "0x21", "0x40", ..., through <del> "0x&#8237;3FFFFFFFFFFFFFFE&#8236;") MUST NOT be assigned by IANA. </del> <ins> "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. </ins> 10.5.

Additionally, each code of the format "0x1f * N + 0x21" for integer values of N (that is, "0x21", "0x40", ..., through <del> "0x&#8237;3FFFFFFFFFFFFFFE&#8236;") MUST NOT be assigned by IANA. </del> <ins> "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. </ins> 11.  References
Change:
Section 6.3 says And then Section 15 defines two kinds of "reserved" versions, which makes the paragraph above ambiguous. ... Is the intent in Section 6.3 that a server SHOULD include a version that is reserved for forcing version negotiation (i.e., matches 0x?a?a?a?a), or SHOULD a server include a version reserved for future IETF consensus documents (i.e., matching 0x0000????). Or both?
In my opinion having an implementation that advertises possible future standards versions without actually supporting them seems wrong, what happens if the other side actually supports this version? This seems like it could deadlock or look like a bidding down attack in case the client moves to a lower version to resolve the deadlock. On the other hand, announcing standards versions helps to not ossify around the 0x?a?a?a?a pattern but to me announcing standards versions does not seem like a solution to this.
I think that some of the discussion recently has pushed us away from reserving versions for IETF use. Fixing that would make this a design issue, of course. I get the editorial point though. Doubling up on the use of "reserved" is unfortunate.
looks fine

Discussion:
6.3. <del> For a server to use a new version in the future, clients must </del> <ins> For a server to use a new version in the future, clients need to </ins> correctly handle unsupported versions.  To help ensure this, a server <del> SHOULD include a reserved version (see versions) while generating a </del> <ins> SHOULD include a version that is reserved for forcing version negotiation (0x?a?a?a?a as defined in versions) when generating a </ins> Version Negotiation packet. The design of version negotiation permits a server to avoid maintaining state for packets that it rejects in this fashion. <del> A client MAY send a packet using a reserved version number.  This can be used to solicit a list of supported versions from a server. </del> <ins> A client MAY send a packet using a version that is reserved for forcing version negotiation.  This can be used to solicit a list of supported versions from a server. </ins> 7.
Change:
For NAME
This is talking about the case of being in "Data Recvd" and therefore ignoring RESET_STREAM. Should the last sentence instead read: "In the latter case, the receiving part of the stream remains in "Data Recvd" ?
That sounds right.

Discussion:
is received (that is, from the "Data Recvd" state).  Similarly, it is possible for remaining stream data to arrive after receiving a RESET_STREAM frame (the "Reset Recvd" state).  An implementation is <del> free to manage this situation as it chooses.  Sending RESET_STREAM means that an endpoint cannot guarantee delivery of stream data; however there is no requirement that stream data not be delivered if a RESET_STREAM is received.  An implementation MAY interrupt delivery of stream data, discard any data that was not consumed, and signal the receipt of the RESET_STREAM immediately.  Alternatively, the RESET_STREAM signal might be suppressed or withheld if stream data is completely received and is buffered to be read by the application. In the latter case, the receiving part of the stream transitions from "Reset Recvd" to "Data Recvd". </del> <ins> free to manage this situation as it chooses. Sending RESET_STREAM means that an endpoint cannot guarantee delivery of stream data; however there is no requirement that stream data not be delivered if a RESET_STREAM is received.  An implementation MAY interrupt delivery of stream data, discard any data that was not consumed, and signal the receipt of the RESET_STREAM.  A RESET_STREAM signal might be suppressed or withheld if stream data is completely received and is buffered to be read by the application.  If the RESET_STREAM is suppressed, the receiving part of the stream remains in "Data Recvd". </ins> Once the application has been delivered the signal indicating that the stream was reset, the receiving part of the stream transitions to
Change:
PTO works out fine, but loss_delay becomes weird. We should probably handle that.
In some environments, Kerberos integration (for server and client authentication) might be preferable to authentication via server certificates and SPNEGO.
Outside of this WG charter. A version of QUIC could be defined which does this, hypothetically, but our charter is to use TLS as the handshake for the version of QUIC we define.
One small suggestion, but LG

Discussion:
sustained increase in the actual RTT, but the smoothed SRTT has not yet caught up. <ins> An endpoint might consistently record RTT samples as 0 in extremely low latency networks, leading to a smoothed_rtt of 0.  Consequently, the endpoint could declare all earlier packets as lost immediately upon receiving an acknowledgement for a later packet.  That is, the endpoint would not provide any reordering tolerance.  To avoid declaring packets as lost too early, the time threshold MUST be set to at least kGranularity (defined in ld-consts-of-interest). </ins> Implementations MAY experiment with absolute thresholds, thresholds from previous connections, adaptive thresholds, or including RTT variance.  Smaller thresholds reduce reordering resilience and
Change:
The text here had a MUST prohibiting data+offset from exceeding 2^62-1. But that is redundant with flow control, which can't express a limit greater than this anyway. So just point to FLOWCONTROLERROR.
Sec 19.8 says: The first byte in the stream has an offset of 0. The largest offset delivered on a stream - the sum of the offset and data length - MUST be less than 2^62. It certainly possible to express a STREAM frame that violates this rule. What action should we take?
I don't know if we ever wrote this down, but I think that we might say if you catch a peer violating the spec, then you can send an error of any type you like. But for this case, PROTOCOL_VIOLATION is entirely appropriate (as with many others of this sort).
Not just offset, but offset + content size of stream frame, otherwise there is no fixed limit on stream sizes, which is unfortunate.

Discussion:
frame is the offset of the next byte that would be sent. The first byte in the stream has an offset of 0.  The largest offset <del> delivered on a stream - the sum of the offset and data length - MUST be less than 2^62. </del> <ins> delivered on a stream - the sum of the offset and data length - cannot exceed 2^62-1, as it is not possible to provide flow control credit for that data.  Receipt of a frame that exceeds this limit will be treated as a connection error of type FLOW_CONTROL_ERROR. </ins> 19.9.
Change:
Adds some explanation about why it's better to arm/fire the time threshold alarm before the crypto retransmission timeout. Hopefully clarifies comments from
Thanks for the explanation. It's much clearer. Can i ask for one more clarification? In DetectLostPackets, shouldn't the for-loop have been something like this:
Thanks for catching the pseudocode error in DetectLostPackets. PTAL.
lgtm. thank you!
In both SetLossDetectionTimer() and OnLossDetectionTimeout(), the losstime based timer setup and loss detection happens before the crypto loss recovery logics. That seems at the cross road with the idea that crypto packets having higher priority in loss recovery. In fact in OnLossDetectionTimerou(), if losstime is present and we go into DetectLostPackets(), then we will only decect loss of one packet number space between Initial and Handshake. Plus the losstime used to set the timer is the earliest among all possible values, which means even if only one of Initial and Handshake space has inflight packets, we may still not retransmit all the inflight packets when this timer fires. So this current code really doesn't follow the idea that when crypto is inflight and loss timer fires, all inflight crypto needs to be retransmitted. If we change the code so that crypto is handled first, we can also reduce the states need to be maintained and simplify some of the functions. In current draft there are 3 losstimes, one per packet number space. By always handling crypto first, we will need such loss_time for AppData space only, and no need to have the helper function to GetEarliestLossTime(). (I'm more than happy to cook up a PR if people think this makes sense.)
It's been a few days. I sent PR .
This was introduced as a fix to URL, and fixed in URL I don't think we should revert that fix.
+1 to NAME comment. Timers are necessary when you have no information about what might be lost, but if you do have information, there's no reason not to use that instead.
I sent out an editorial PR to clarify why time based loss detection has higher priority.

Discussion:
least 1200 bytes. The crypto retransmission timer is not set if the time threshold <del> time-threshold loss detection timer is set.  When the crypto retransmission timer is active, the probe timer (pto) is not active. </del> <ins> time-threshold loss detection timer is set.  The time threshold loss detection timer is expected to both expire earlier than the crypto retransmission timeout and be less likely to spuriously retransmit data.  The Initial and Handshake packet number spaces will typically contain a small number of packets, so losses are less likely to be detected using packet-threshold loss detection. When the crypto retransmission timer is active, the probe timer (pto) is not active. </ins> 6.2.1.
Change:
Editorial fix for This seems like the minimal fix for the existing text, though I wonder if it's the correct one.
I think this fix is fine, but it's inadequate. I'll take this in since it's useful.
Can you clarify why it's inadequate on the still open issue?
NAME primarily because it does not correct the pseudocode, but I've also made some textual adjustments in
As discussed with NAME 6.2.2.2 is awkward, because in the first paragraph it says And then the very last paragraph changes that by saying What is super unclear is that the final paragraph apparently means to imply that when there is no new or unACKed data to send, nothing should be send, i.e., it invalidates the SHOULD in the first paragraph. Related to that, the pseudo code still uses , which is also inaccurate, since it's really "at least one (unless you don't have new or unACKed data) but can also send two". Good luck finding a good name for that function :-)
The pseudocode now uses SendOneOrTwoPackets(), but the last paragraph pretty clearly violates the previous MUST, which is very bad. The simplest fix would be to change the MUST to a "SHOULD unless otherwise specified", but I'm increasingly thinking we should stick with the MUST and if you get into a situation you have nothing to send, require sending something ack-eliciting to ensure in-flight packets are removed from flight. Thoughts?

Discussion:
6.3.2. When a PTO timer expires, the sender MUST send one ack-eliciting <del> packet as a probe.  A sender MAY send up to two ack-eliciting packets, to avoid an expensive consecutive PTO expiration due to a single packet loss. </del> <ins> packet as a probe, unless there is nothing to send.  A sender MAY send up to two ack-eliciting packets, to avoid an expensive consecutive PTO expiration due to a single packet loss. </ins> Consecutive PTO periods increase exponentially, and as a result, connection recovery latency increases exponentially as packets
Change:
Move the "Discarding Keys and Packet State" section up a level and out from underneath the Crypto Handshake Timer. This section in no way references the crypto handshake timer, so there's no reason to put it there. It's possible this should be up-leveled out of loss recovery as well? The preceding "Retry and Version Negotiation" has a similar problem, so I'd like suggestions on where to move that too.

Discussion:
value to seed the RTT estimator for a subsequent connection attempt to the server. <del> 6.2.2. When packet protection keys are discarded (see Section 4.9 of QUIC- 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 those packets and MUST remove them from the count of bytes in flight. Endpoints stop sending and receiving Initial packets once they start exchanging Handshake packets (see Section 17.2.2.1 of QUIC- TRANSPORT).  At this point, recovery state for all in-flight Initial packets is discarded. When 0-RTT is rejected, recovery state for all in-flight 0-RTT packets is discarded. If a server accepts 0-RTT, but does not buffer 0-RTT packets that arrive before Initial packets, early 0-RTT packets will be declared lost, but that is expected to be infrequent. It is expected that keys are discarded after packets encrypted with them would be acknowledged or declared lost.  Initial secrets however might be destroyed sooner, as soon as handshake keys are available (see Section 4.10 of QUIC-TLS). </del> 6.3. A Probe Timeout (PTO) triggers a probe packet when ack-eliciting data

6.4. <ins> When packet protection keys are discarded (see Section 4.9 of QUIC- 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 those packets and MUST remove them from the count of bytes in flight. Endpoints stop sending and receiving Initial packets once they start exchanging Handshake packets (see Section 17.2.2.1 of QUIC- TRANSPORT).  At this point, recovery state for all in-flight Initial packets is discarded. When 0-RTT is rejected, recovery state for all in-flight 0-RTT packets is discarded. If a server accepts 0-RTT, but does not buffer 0-RTT packets that arrive before Initial packets, early 0-RTT packets will be declared lost, but that is expected to be infrequent. It is expected that keys are discarded after packets encrypted with them would be acknowledged or declared lost.  Initial secrets however might be destroyed sooner, as soon as handshake keys are available (see Section 4.10 of QUIC-TLS). 6.5. </ins> The majority of constants were derived from best common practices among widely deployed TCP implementations on the internet. Exceptions follow.