jiebi/TextFlow huggingface dataset:
Original text:
5.3. <del> TBD. </del>  5.4.

Reviewer comments:
URL now we know how many holes it takes to fill the Albert Hall. This section has existed for a long time as "TBD". No longer. It also takes the opportunity to explain a little bit about what 0-RTT is for.
Retry is there, but at one level higher up (confirms that endpoints are willing to communicate ({{validate-handshake}})).
So we have little diagrams for send and receive stream states. Any chance this section could include a state diagram and transitions for the overall connection state?
There's a lot of text in the transport draft that assumes you know what 0-RTT / early data are. The term "early data" occurs only once, and doesn't even appear until describing the 0-RTT packet type. The introductory sections should probably contain some high-level description of Early Data, then point off to TLS for more detailed considerations. Purely editorial -- nothing new needs to be specified, but an uninitiated reader will need some context. This could possibly be part of .
I didn't see any other TBDs in the draft -transport doc or an existing issue, so opening this for tracking purposes.
Whoops!
I noticed you didn't write anything about Retry. Was that intentional?

Revised text:
5.3.  <ins> A QUIC connection is a stateful interaction between a client and server, the primary purpose of which is to support the exchange of data by an application protocol.  Streams (streams) are the primary means by which an application protocol exchanges information. Each connection starts with a handshake phase, during which client and server establish a shared secret using the cryptographic handshake protocol QUIC-TLS and negotiate the application protocol. The handshake (handshake) confirms that both endpoints are willing to communicate (validate-handshake) and establishes parameters for the connection (transport-parameters). An application protocol can also operate in a limited fashion during the handshake phase.  0-RTT allows application messages to be sent by a client before receiving any messages from the server.  However, 0-RTT lacks certain key security guarantees.  In particular, there is no protection against replay attacks in 0-RTT; see QUIC-TLS. Separately, a server can also send application data to a client before it receives the final cryptographic handshake messages that allow it to confirm the identity and liveness of the client.  These capabilities allow an application protocol to offer the option to trade some security guarantees for reduced latency. The use of connection IDs (connection-id) allows connections to migrate to a new network path, both as a direct choice of an endpoint and when forced by a change in a middlebox.  migration describes mitigations for the security and privacy issues associated with migration. For connections that are no longer needed or desired, there are several ways for a client and server to terminate a connection (termination). </ins> 5.4.
Original text:
the frame.  These frames are explained in more detail in frame- formats.  An endpoint MUST treat the receipt of a frame of unknown type as a connection error of type FRAME_ENCODING_ERROR.

Reviewer comments:
It's still slightly odd where we have this setup between TLS and transport, but it seems like replicating the information might be enough.
Would it make sense to add PN space columns to the table of frames with section references, with an X where a frame is applicable? Transport section 12.4 URL
Looks good to me, and thank you for adding this column. Seeing frames like PATH_CHALLENGE/RESPONSE in 0RTT packets is strange, but clearly allowed by the spec. I don't see a reason to changing this, but it's why I think this column is useful.

Revised text:
the frame.  These frames are explained in more detail in frame- formats. <ins> The "Packets" column in frame-types does not form part of the IANA registry (see iana-frames).  This column summarizes the types of packets that each frame type can appear in, indicated as up to four characters indicating: Initial (packet-initial) Handshake (packet-handshake) 0-RTT (packet-0rtt) 1-RTT (short-header) A CONNECTION_CLOSE frame of type 0x1c can appear in Initial, Handshake, and 1-RTT packets, whereas a CONNECTION_CLOSE of type 0x1d can only appear in a 1-RTT packet. Section 4 of QUIC-TLS provides more detail about these restrictions. Note that all frames can appear in 1-RTT packets. </ins> An endpoint MUST treat the receipt of a frame of unknown type as a connection error of type FRAME_ENCODING_ERROR.
Original text:
QUIC requires that the cryptographic handshake provide authenticated protocol negotiation.  TLS uses Application Layer Protocol <del> Negotiation (ALPN) RFC7301 to select an application protocol.  Unless </del>  another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose.  When using ALPN, endpoints 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- <del> errors).  While RFC7301 only specifies that servers use this alert, QUIC clients MUST also use it to terminate a connection when ALPN </del>  negotiation fails. <del> An application-layer protocol MAY restrict the QUIC versions that it can operate over.  Servers MUST select an application protocol compatible with the QUIC version that the client has selected.  If the server cannot select a compatible combination of application protocol and QUIC version, it MUST abort the connection.  A client MUST abort a connection if the server picks an application protocol incompatible with the protocol version being used. </del>  8.2.

Reviewer comments:
The old text used the non-specific "abort" here, but we can point to the right error code.
What does "abort" mean? Perhaps change this to "drop QUIC connection state"? Originally posted by NAME in URL
LGTM modulo the preference below.

Revised text:
QUIC requires that the cryptographic handshake provide authenticated protocol negotiation.  TLS uses Application Layer Protocol  <ins> Negotiation (ALPN) ALPN to select an application protocol.  Unless </ins> another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose.  When using ALPN, endpoints 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-  <ins> errors).  While ALPN only specifies that servers use this alert, QUIC clients MUST also use it to terminate a connection when ALPN </ins> negotiation fails.  <ins> An application protocol MAY restrict the QUIC versions that it can operate over.  Servers MUST select an application protocol compatible with the QUIC version that the client has selected.  The server MUST treat the inability to select a compatible application protocol as a connection error of type 0x178 (no_application_protocol).  Similarly, a client MUST treat the selection of an incompatible application protocol by a server as a connection error of type 0x178. </ins> 8.2.
Original text:
An endpoint MAY send data to an unvalidated peer address, but it MUST protect against potential attacks as described in address-spoofing and on-path-spoofing.  An endpoint MAY skip validation of a peer <del> address if that address has been seen recently. </del>  An endpoint only changes the address that it sends packets to in response to the highest-numbered non-probing packet.  This ensures

Reviewer comments:
This is really just an observation, because there is no real way we can insist on people doing this sort of thing, but being aware of the performance implication of spoofed migrations might motivate solutions.
I think the sections that describe connection migration attacks should mention that, when the endpoint detects a spurious migration, it should revert back to using the same CC state and ECN state as before. Otherwise, an attacker could degrade the performance of a connection.
Perhaps the tag should be recovery, not transport.
I can see it going either way. NAME what do you think?
I think the text is going to be in transport, so that's probably the right tag
As long as this doesn't lead to confusion (for example: we recently tightened up the MUST around resetting state) for folks when reading this, I think it's really valuable to actually state this in the draft rather than hint at it throughout -- looks good!

Revised text:
An endpoint MAY send data to an unvalidated peer address, but it MUST protect against potential attacks as described in address-spoofing and on-path-spoofing.  An endpoint MAY skip validation of a peer  <ins> address if that address has been seen recently.  In particular, if an endpoint returns to a previously-validated path after detecting some form of spurious migration, skipping address validation and restoring loss detection and congestion state can reduce the performance impact of the attack. </ins> An endpoint only changes the address that it sends packets to in response to the highest-numbered non-probing packet.  This ensures
Original text:
data for a terminated connection is to use the stateless reset process (stateless-reset). <del> An endpoint that receives an invalid CONNECTION_CLOSE frame MUST NOT signal the existence of the error to its peer. </del> 11.2. If an application-level error affects a single stream, but otherwise

Reviewer comments:
If we get one, rely on the back-off that we require endpoints to implement when they enter the closing state. No need for any additional special processing rules (as mentioned in ).
Section 11.1 says: "An endpoint that receives an invalid CONNECTIONCLOSE frame MUST NOT signal the existence of the error to its peer." Editorially, it is not clear to me whether I am to suppress the error code in the CONNECTIONCLOSE frame or the error I generate when I receive an invalid frame. Moreover, I am not sure what constitutes an invalid CONNECTION_CLOSE frame. The words don't occur elsewhere. Section 19.19 doesn't define any fatal errors for this type. I can imagine a Reason Length that overruns the packet, or perhaps an undefined error code? A bogus frame type? We should probably define those in 19.19. Perhaps this sentence is an artifact from before we were throwing away Initial keys agressively?
If you suppress the error, does it matter which error you do not send?
I'm not sure what the intent of the sentence is. Do I send PROTOCOL_VIOLATION but not the error code in the frame? Do I send nothing?
As I read it, you should not send anything if you see CONNECTION_CLOSE. As to the motivation, I'm not quite sure, but if the peer closes but does it badly, chances are that anything you send just results in stateless resets. Maybe there can also be some malicious intend, especially in early handshake, but I don't think that is the reason.
I think this is addressing the injected packet case -- if you ignore an injected CONNECTION_CLOSE, you shouldn't send the real peer anything about it, or you've just allowed an attacker to inject authenticated traffic in the connection.
This is more about the looping case: sending CONNECTIONCLOSE in response to CONNECTIONCLOSE. But it is badly worded.
From the current text in 10.3 After sending a CONNECTIONCLOSE frame, endpoints immediately enter the closing state. During the closing period, an endpoint that sends a CONNECTIONCLOSE frame SHOULD respond to any packet that it receives with another packet containing a CONNECTION_CLOSE frame. To minimize the state that an endpoint maintains for a closing connection, endpoints MAY send the exact same packet. This will be a loop since the same invalid packet will be sent again by the sender ....
I'm going to request that this be re-assessed. When looking into Roni's comment, I realize that we aren't really clear enough about this invalid case and some (small amount of) discussion might be necessary to confirm that this change is OK.

Revised text:
data for a terminated connection is to use the stateless reset process (stateless-reset).  11.2. If an application-level error affects a single stream, but otherwise
Original text:
6.1. <del> If a path has been verified to support ECN, QUIC treats a Congestion Experienced codepoint in the IP header as a signal of congestion. This document specifies an endpoint's response when its peer receives packets with the Congestion Experienced codepoint.  As discussed in RFC8311, endpoints are permitted to experiment with other response functions. </del>  6.2.

Reviewer comments:
And note that 8311 is an update.
(Broken out of .) >A receiver maintains a cumulative sum of It would have helped me, had this explained what was intended by “control violations” - I think it means to detect when the sender sends more than permitted by the flow control limit. I think the control part comes in a later sentence? (Is this measured against the largest advertised offset, or the current offset? … given what is written about reducing the advertised value?)
one suggestion, but I'm approving

Revised text:
6.1.  <ins> If a path has been verified to support ECN RFC3168 RFC8311, QUIC treats a Congestion Experienced(CE) codepoint in the IP header as a signal of congestion.  This document specifies an endpoint's response when its peer receives packets with the Congestion Experienced codepoint. </ins> 6.2.
Original text:
2. Like HPACK, QPACK uses two tables for associating header fields to <del> indices.  The static table (see _table-static) is predefined and contains common header fields (some of them with an empty value). The dynamic table (see _table-dynamic) is built up over the course of the connection and can be used by the encoder to index header fields in the encoded header lists. </del>  QPACK defines unidirectional streams for sending instructions from encoder to decoder and vice versa. QPACK defines two settings which are included in the HTTP/3 SETTINGS frame. <del> The default value is zero.  See _table-dynamic for usage.  This is the equivalent of the SETTINGS_HEADER_TABLE_SIZE from HTTP/2. </del>  The default value is zero.  See blocked-streams.

Reviewer comments:
xml2rfc v3 format prohibits the use of these, which will cause problems. This makes the anchors longer, so feel free to go with something else.
Had to merge it, but feel free to fix anchors.

Revised text:
2. Like HPACK, QPACK uses two tables for associating header fields to  <ins> indices.  The static table (see header-table-static) is predefined and contains common header fields (some of them with an empty value). The dynamic table (see header-table-dynamic) is built up over the course of the connection and can be used by the encoder to index header fields in the encoded header lists. </ins> QPACK defines unidirectional streams for sending instructions from encoder to decoder and vice versa. QPACK defines two settings which are included in the HTTP/3 SETTINGS frame.  <ins> The default value is zero.  See header-table-dynamic for usage. This is the equivalent of the SETTINGS_HEADER_TABLE_SIZE from HTTP/2. </ins> The default value is zero.  See blocked-streams.
Original text:
client believes that the Path Maximum Transmission Unit (PMTU) supports the size that it chooses.  A server MAY send a CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in response to an Initial packet it receives from a client if the UDP datagram is smaller than 1200 bytes.  It MUST NOT

Reviewer comments:
This won't necessarily prevent fragmentation from happening, but it's the best we can do. I didn't REQUIRE dropping of fragments, because some systems do that for you, but a SHOULD seems appropriate.
Gorry notes correctly that fragmentation can play poorly with using IW10. If a sender uses a large maxdatagramsize, and if the network fragments, then IW10 can result in substantially larger amplification than 10x. A simple fix here is to say that if the endpoint uses maxdatagramsize larger than 1280 bytes (this is what the transport spec limits it to in the absence of DPLPMTUD), then the endpoint MUST set DF on outgoing packets. This is a problem with RFC 6928 as well, but we should be clear about it for QUIC.
Shouldn't endpoint always set DF for all QUIC packets? TCP does so.
I tend to agree with Praveen here. I think this is something that's under-specified in transport? I believe it should be in section 14: URL
Yeah, this is probably an issue in transport. DF seems like the obvious answer.
That was my first answer, but I thought that might be too intrusive. If we all agree that is a fine response, I'm happy with that. I can write up a PR.
From memory, I think there was once a discussion on DF bit not being accessible in some language interfaces. As such, the formulation should perhaps be that the DF bit SHOULD be set whenever possible. Having a MUST whenever possible could be problematic because possible could involve a lot of complexity.
-- URL
NAME yes, that is exactly the text I am referring to. I'm questioning if that requirement is practically enforceable.

Revised text:
client believes that the Path Maximum Transmission Unit (PMTU) supports the size that it chooses. <ins> UDP datagrams MUST NOT be fragmented at the IP layer.  In IPv4 IPv4, the DF bit MUST be set to prevent fragmentation on the path. </ins> A server MAY send a CONNECTION_CLOSE frame with error code PROTOCOL_VIOLATION in response to an Initial packet it receives from a client if the UDP datagram is smaller than 1200 bytes.  It MUST NOT
Original text:
allow values to be linked by an on-path observer to the connection on which it was issued, unless the values are encrypted.  For example, it cannot include the previous connection ID or addressing <del> information.  Information that allows the server to distinguish between tokens from Retry and NEW_TOKEN MAY be accessible to entities other than the server. </del>  It is unlikely that the client port number is the same on two different connections; validating the port is therefore unlikely to connection error of type FRAME_ENCODING_ERROR. An endpoint might receive multiple NEW_TOKEN frames that contain the <del> same token value.  Endpoints are responsible for discarding duplicate values, which might be used to link connection attempts; see validate-future. </del>  Clients MUST NOT send NEW_TOKEN frames.  Servers MUST treat receipt of a NEW_TOKEN frame as a connection error of type

Reviewer comments:
This is already implied by the existing text, but it isn't said directly. That is, we say that the values can't be linkable, which is a stronger requirement. Saying that you can't send the same value on two connections is much clearer.
This text does not forbid the server from sending the same token on multiple connections. Consequently the client has a hard, or impossible, task of excluding duplicates. At least if you only read that section. Later the text says: >The token MUST NOT include information that would allow it to be linked by an on-path observer to the connection on which it was issued. This suggests that the token MUST indeed be unique, but in a roundabout manner. It would be helpful to make the initial paragraph clearer by stating the that the duplicate token can only happen on the same connection and that the server MUST ensure different connections use different tokens.
A nit, but looks good, thanks for working patiently!

Revised text:
allow values to be linked by an on-path observer to the connection on which it was issued, unless the values are encrypted.  For example, it cannot include the previous connection ID or addressing  <ins> information.  A server MUST ensure that every NEW_TOKEN frame it sends is unique across all clients, with the exception of those sent to repair losses of previously sent NEW_TOKEN frames.  Information that allows the server to distinguish between tokens from Retry and NEW_TOKEN MAY be accessible to entities other than the server. </ins> It is unlikely that the client port number is the same on two different connections; validating the port is therefore unlikely to connection error of type FRAME_ENCODING_ERROR. An endpoint might receive multiple NEW_TOKEN frames that contain the  <ins> same token value if packets containing the frame are incorrectly determined to be lost.  Endpoints are responsible for discarding duplicate values, which might be used to link connection attempts; see validate-future. </ins> Clients MUST NOT send NEW_TOKEN frames.  Servers MUST treat receipt of a NEW_TOKEN frame as a connection error of type
Original text:
disabled for a connection.  Implementations MUST allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis.  Even when the spin bit is not disabled by <del> the administrator, implementations MUST disable the spin bit for a given connection with a certain likelihood.  The random selection process SHOULD be designed such that on average the spin bit is disabled for at least one eighth of network paths.  The selection process performed at the beginning of the connection SHOULD be applied for all paths used by the connection. </del>  When the spin bit is disabled, endpoints MAY set the spin bit to any value, and MUST ignore any incoming value.  It is RECOMMENDED that

Reviewer comments:
This builds on to address the linkability issues that it added. It recommends 1/16 of network paths are disabled randomly as suggested by NAME It also allows the determination to be made per connection ID rather than per-path (which is more granular, but I expect it will have a nearly identical effect). The net effect is that 1/8 paths will not spin as originally intended.
The draft says: Given that each endpoint needs to decide for itself whether it is enabling spin bit, it is not exactly clear whether each endpoint SHOULD disable spin bit on at least 1/8 (=12.5%) of connections, or it can assume that the other endpoint is also making a random decision to disable and disable only on 1-sqrt(7/8) (=6.5%) of connections.
as the author of this passage, I intended the latter (assume the other side is disabling as well, so 1-sqrt(7/8)), but the "at least" is in there since just disabling 1/8 is probably what people will do, and the result (about 1/4) is "at least 1/8".
NAME could you review ?
One suggestionLooks good technically. It may be slightly confusing, though, that the last sentence only talks about paths, while a sentence before talks about "paths or connection IDs". In any case, the behavior ensures a sufficient amount of traffic without the spin bit to prevent ossification of the bit.

Revised text:
disabled for a connection.  Implementations MUST allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis.  Even when the spin bit is not disabled by  <ins> the administrator, endpoints MUST disable their use of the spin bit for a random selection of at least one in every 16 network paths, or for one in every 16 connection IDs.  As each endpoint disables the spin bit independently, this ensures that the spin bit signal is disabled on approximately one in eight network paths. </ins> When the spin bit is disabled, endpoints MAY set the spin bit to any value, and MUST ignore any incoming value.  It is RECOMMENDED that