jiebi/TextFlow huggingface dataset:
Original text:
Packet numbers are limited to this range because they need to be representable in whole in the Largest Acknowledged field of an ACK frame (frame-ack).  When present in a long or short header however, <del> packet numbers are reduced and encoded in 1 to 4 bytes, see packet- </del>  encoding). <del> Version Negotiation (packet-version) and Retry packet-retry packets </del>  do not include a packet number. Packet numbers are divided into 3 spaces in QUIC: <del> Initial space: All Initial packets packet-initial are in this </del>  space. <del> Handshake space: All Handshake packets packet-handshake are in </del>  this space. Application data space: All 0-RTT and 1-RTT encrypted packets <del> packet-protected are in this space. </del>  As described in QUIC-TLS, each packet type uses different protection keys. types. A QUIC endpoint MUST NOT reuse a packet number within the same packet <del> number space in one connection (that is, under the same cryptographic keys).  If the packet number for sending reaches 2^62 - 1, the sender MUST close the connection without sending a CONNECTION_CLOSE frame or any further packets; an endpoint MAY send a Stateless Reset (stateless-reset) in response to further packets that it receives. </del>  A receiver MUST discard a newly unprotected packet unless it is certain that it has not processed another packet with the same packet

Reviewer comments:
The deleted parenthetical is not accurate, and is unnecessary: 0-RTT and 1-RTT with various key phases share a PN space without sharing keys. I prefer the MUST NOT in coalescing, but if there are objections I can revert it.
Thanks Martin.
All good apart from the MUST NOT. I'm with Martin -- everything else looks fine.

Revised text:
Packet numbers are limited to this range because they need to be representable in whole in the Largest Acknowledged field of an ACK frame (frame-ack).  When present in a long or short header however,  <ins> packet numbers are reduced and encoded in 1 to 4 bytes (see packet- </ins> encoding).  <ins> Version Negotiation (packet-version) and Retry (packet-retry) packets </ins> do not include a packet number. Packet numbers are divided into 3 spaces in QUIC:  <ins> Initial space: All Initial packets (packet-initial) are in this </ins> space.  <ins> Handshake space: All Handshake packets (packet-handshake) are in </ins> this space. Application data space: All 0-RTT and 1-RTT encrypted packets  <ins> (packet-protected) are in this space. </ins> As described in QUIC-TLS, each packet type uses different protection keys. types. A QUIC endpoint MUST NOT reuse a packet number within the same packet  <ins> number space in one connection.  If the packet number for sending reaches 2^62 - 1, the sender MUST close the connection without sending a CONNECTION_CLOSE frame or any further packets; an endpoint MAY send a Stateless Reset (stateless-reset) in response to further packets that it receives. </ins> A receiver MUST discard a newly unprotected packet unless it is certain that it has not processed another packet with the same packet
Original text:
Negotiation (ALPN) RFC7301 to select an application protocol.  Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose.  When using ALPN, endpoints <del> MUST abort a connection if an application protocol is not negotiated. </del>  An application-layer protocol MAY restrict the QUIC versions that it can operate over.  Servers MUST select an application protocol

Reviewer comments:
Just so you don't have to read the whole RFC7301.
Yeah I was thinking about that. I wonder if it would make sense for the client to simply send PROTOCOL_VIOLATION instead of a TLS alert.
NAME I added a clarification to allow clients to send noapplicationnegotiated as well. Should I send an email to the mailing list for discussion now that the new process is in effect?
Unfortunately yes. This is a design change so it will need an issue as well. I like it and we should do it, but can you add the error code we would use in CONNECTION_CLOSE to the text?
NAME ok, added error code, created issue () and sent email to the list.
NAME thanks, suggestions accepted.
PR added a requirement for end-points to terminate a connection if ALPN negotiation fails, but doesn't specify an error code for this situation. RFC7301 defines the alert that must be used by TLS servers, so QUIC servers should probably use that as well. As for clients, RFC7301 doesn't specify a behaviour, but it also doesn't forbid use of in clients, and it seems better if QUIC clients use the same error code as the servers. Proposed wording change is in .
My :+1: goes to making the change, though I would like to confirm that it wouldn't be illegal for a client to close the connection with error after it sends ClientFinished. I ask this because depending on the design of the TLS stack, the QUIC stack might not be able to see the result of ALPN before the TLS stack generates a ClientFinished (note that EE.ALPN and ServerFinished might arrive in one packet). It's my understanding that the intent of the issue is to not allow the client to send any application data on ALPN failure. Assuming that's true, sending the alert after ClientFinished should be fine.
Yes, I think that would be fine. I don't think that we would be able to guarantee that the alert goes out before sending ClientFinished either. It's certainly possible, but I can see how it might be tricky.
This was fixed with .
a few nits

Revised text:
Negotiation (ALPN) RFC7301 to select an application protocol.  Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose.  When using ALPN, endpoints  <ins> MUST immediately close a connection (see Section 10.3 in QUIC- TRANSPORT) if an application protocol is not negotiated with a no_application_protocol TLS alert (QUIC error code 0x178, see tls- errors).  While RFC7301 only specifies that servers use this alert, QUIC clients MUST also use it to terminate a connection when ALPN negotiation fails. </ins> An application-layer protocol MAY restrict the QUIC versions that it can operate over.  Servers MUST select an application protocol
Original text:
MAX_STREAMS frames (frame-max-streams).  Separate limits apply to unidirectional and bidirectional streams.  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

Reviewer comments:
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.

Revised text:
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
Original text:
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>  HTTP_MALFORMED_FRAME. When a PRIORITY frame claims to reference a request, the associated

Reviewer comments:
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.

Revised text:
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  <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
Original text:
<del> QPACK: Header Compression for HTTP over QUIC </del>  draft-ietf-quic-qpack-latest Abstract

Reviewer comments:
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.

Revised text:
 <ins> QPACK: Header Compression for HTTP/3 </ins> draft-ietf-quic-qpack-latest Abstract
Original text:
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>  The server's preferred address is used to effect a change in server address at the end of the handshake, as described in

Reviewer comments:
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.

Revised text:
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  <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
Original text:
TRANSPORT is used. The quic_transport_parameters extension is carried in the ClientHello <del> and the EncryptedExtensions messages during the handshake. </del>  While the transport parameters are technically available prior to the completion of the handshake, they cannot be fully trusted until the

Reviewer comments:
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.

Revised text:
TRANSPORT is used. The quic_transport_parameters extension is carried in the ClientHello  <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
Original text:
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>  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>  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>  11.  References

Reviewer comments:
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

Revised text:
Additionally, each code of the format "0x1f * N + 0x21" for integer values of N (that is, "0x21", "0x40", ..., through  <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  <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  <ins> "0x3FFFFFFFFFFFFFFE") MUST NOT be assigned by IANA. </ins> 11.  References
Original text:
6.3. <del> For a server to use a new version in the future, clients must </del>  correctly handle unsupported versions.  To help ensure this, a server <del> SHOULD include a reserved version (see versions) while generating a </del>  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>  7.

Reviewer comments:
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

Revised text:
6.3.  <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  <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.  <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.
Original text:
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>  Once the application has been delivered the signal indicating that the stream was reset, the receiving part of the stream transitions to

Reviewer comments:
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.

Revised text:
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  <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
Original text:
sustained increase in the actual RTT, but the smoothed SRTT has not yet caught up.  Implementations MAY experiment with absolute thresholds, thresholds from previous connections, adaptive thresholds, or including RTT variance.  Smaller thresholds reduce reordering resilience and

Reviewer comments:
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

Revised text:
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