jiebi/CodeConvo huggingface dataset:
Change:
Moves some RECOMMENDEDs up and removes others which are already elsewhere in the draft and reference those sections. This was intended to address , which I can still do in this PR if NAME would like, but I still think of Min CWND and Initial CWND as constants per-connection, even if they're not truly constants.

Discussion:
has not yet caught up. The RECOMMENDED time threshold (kTimeThreshold), expressed as a <del> round-trip time multiplier, is 9/8. </del> <ins> round-trip time multiplier, is 9/8.  The RECOMMENDED value of the timer granularity (kGranularity) is 1ms. </ins> Implementations MAY experiment with absolute thresholds, thresholds from previous connections, adaptive thresholds, or including RTT

A connection MAY use the delay between sending a PATH_CHALLENGE and receiving a PATH_RESPONSE to set the initial RTT (see kInitialRtt in <del> ld-consts-of-interest) for a new path, but the delay SHOULD NOT be considered an RTT sample. </del> <ins> pto-handshake) for a new path, but the delay SHOULD NOT be considered an RTT sample. </ins> Until the server has validated the client's address on the path, the amount of data it can send is limited to three times the amount of

can be established by consecutive PTOs, but since the PTO timer is reset when a new ack-eliciting packet is sent, an explicit duration must be used to account for those cases where PTOs do not occur or <del> are substantially delayed.  This duration is computed as follows: </del> <ins> are substantially delayed.  The rationale for this threshold is to enable a sender to use initial PTOs for aggressive probing, as TCP does with Tail Loss Probe (TLP) RACK, before establishing persistent congestion, as TCP does with a Retransmission Timeout (RTO) RFC5681. The RECOMMENDED value for kPersistentCongestionThreshold is 3, which is approximately equivalent to two TLPs before an RTO in TCP. This duration is computed as follows: </ins> For example, assume:
Change:
This was getting a little long. You could get lost in there. The text was fine, it was mostly well structured. All it needed was one small move and some headers.

Discussion:
See the Retry Packet Integrity section of QUIC-TLS. <ins> 17.2.5.1. </ins> The server populates the Destination Connection ID with the connection ID that the client included in the Source Connection ID of the Initial packet.

Initial or 0-RTT packets.  A server MUST NOT send more than one Retry packet in response to a single UDP datagram. <ins> 17.2.5.2. </ins> A client MUST accept and process at most one Retry packet for each connection attempt.  After the client has received and processed an Initial or Retry packet from the server, it MUST discard any

connection ID as part of its token validation logic (see token- integrity). <ins> A Retry packet does not include a packet number and cannot be explicitly acknowledged by a client. 17.2.5.3. </ins> The next Initial packet from the client uses the connection ID and token values from the Retry packet; see negotiating-connection-ids. Aside from this, the Initial packet sent by the client is subject to

absent.  A client MUST treat a failed validation as a connection error of type TRANSPORT_PARAMETER_ERROR. <del> A Retry packet does not include a packet number and cannot be explicitly acknowledged by a client. </del> 17.3. This version of QUIC defines a single packet type which uses the
Change:
The algorithm was updated at somepoint but the example was lagging.
Insert Count will be encoded modulo 6. If a decoder has received 10 inserts, then an encoded value of 3 indicates that the Required Insert Count is 9 for the header block. should be Insert Count will be encoded modulo 6. If a decoder has received 10 inserts, then an encoded value of 4 indicates that the Required Insert Count is 9 for the header block. Background: I implemented ReqInsertCount for decoder. When I test it with: MaxTableCapacity = 100 EncodedInsertCount = 3 TotalNumberOfInserts = 10 My function returns 8, not 9.I guess that EncodedInsertCount = 4 is right since ReqInsertCount for encoder calculates 4 with ReqInsertCount = 9. NAME pointed out that it looks like the algorithm was replaced, and the example text we are looking at is left as is.

Discussion:
For example, if the dynamic table is 100 bytes, then the Required Insert Count will be encoded modulo 6.  If a decoder has received 10 <del> inserts, then an encoded value of 3 indicates that the Required </del> <ins> inserts, then an encoded value of 4 indicates that the Required </ins> Insert Count is 9 for the header block. 4.5.1.2.
Change:
This is based on and is targeted for that. Careful. I did a bit of language tweaking to the 260 limits on the MAX_STREAMS frame to make it a little more useful. The text there was a little old.

Discussion:
MAX_STREAMS frames contain the following fields: A count of the cumulative number of streams of the corresponding <del> type that can be opened over the lifetime of the connection. Stream IDs cannot exceed 2^62-1, as it is not possible to encode stream IDs larger than this value.  Receipt of a frame that permits opening of a stream larger than this limit MUST be treated as a FRAME_ENCODING_ERROR. </del> <ins> type that can be opened over the lifetime of the connection.  This value cannot exceed 2^60, as it is not possible to encode stream IDs larger than 2^62-1.  Receipt of a frame that permits opening of a stream larger than this limit MUST be treated as a FRAME_ENCODING_ERROR. </ins> Loss or reordering can cause a MAX_STREAMS frame to be received which states a lower stream limit than an endpoint has previously received.

STREAMS_BLOCKED frames contain the following fields: <del> A variable-length integer indicating the stream limit at the time the frame was sent.  Stream IDs cannot exceed 2^62-1, as it is not possible to encode stream IDs larger than this value.  Receipt of a frame that encodes a larger stream ID MUST be treated as a STREAM_LIMIT_ERROR or a FRAME_ENCODING_ERROR. </del> <ins> A variable-length integer indicating the maximum number of streams allowed at the time the frame was sent.  This value cannot exceed 2^60, as it is not possible to encode stream IDs larger than 2^62-1.  Receipt of a frame that encodes a larger stream ID MUST be treated as a STREAM_LIMIT_ERROR or a FRAME_ENCODING_ERROR. </ins> 19.15.
Change:
Feel free to suggest better text or other reasons, but this is what I came up with.
QUIC spec uses kMinimumWindow of 2 MSS compared to TCP's 1 MSS. Let's state the deviation and add justifiaiton text.
LGTM, modulo one suggestion

Discussion:
or more packets are sent prior to a dramatic decrease in congestion window; see persistent-congestion. <ins> 3.1.8. TCP uses a minimum congestion window of one packet.  However, loss of that single packet means that the sender needs to waiting for a PTO (pto) to recover, which can be much longer than a round-trip time. Sending a single ack-eliciting packet also increases the chances of incurring additional latency when a receiver delays its acknowledgement. QUIC therefore recommends that the minimum congestion window be two packets.  While this increases network load, it is considered safe, since the sender will still reduce its sending rate exponentially under persistent congestion (pto). </ins> 4. At a high level, an endpoint measures the time from when a packet was
Change:
This just writes down what NAME suggested in .
Two things need to be clarified around SPA: The CID is not path-specific; it's there to ensure that the client has a second CID before the handshake completes. If the client opts not to migrate, the client can use that CID on the The IP addresses in the SPA are only for use in the transition post-handshake; the client should not cache the IP addresses for any other use.
(Just filling in the text here) on the original address from the server, which is the existing connection, not-migrated. +1 to the second point
If the server is telling the client to migrate to a SPA, should this be changed to "the client MUST select one of the two server's preferred addresses ..."? If the text remains a SHOULD, and the client stays on the old server address, what can the server do if it is only willing to continue with the new connection on the SPA? The server could close the initial connection using the old server address but there isn't a transport error code (e.g. MIGRATION_ERROR) that would explicitly tell the client why the connection is being closed.
The "SHOULD" is intentional. A server cannot rely on clients moving.
Then perhaps a cautionary note such as "If the client opts not to migrate to a preferred address, the server may [lower case] decide to close the connection (e.g. SERVER_BUSY)".
If the server isn't willing at all to handle connections on its published IP address, then (naively) it shouldn't accept connections on that IP address and should publish the other one instead. The scenario this targets is that it's somehow better for the client to use a different address, but that other address can't necessarily be known in advance.
Migrating to a unicast address avoids having to perform connection-based routing through a load balancer.

Discussion:
for this connection received on the old IP address, but MAY continue to process delayed packets. <ins> The addresses that a server provides in the preferred_address transport parameter are only valid for the connection in which they are provided.  A client MUST NOT use these for other connections, including connections that are resumed from the current connection. </ins> 9.6.3. A client might need to perform a connection migration before it has

A client that migrates to a new address SHOULD use a preferred address from the same address family for the server. <ins> The connection ID provided in the preferred_address transport parameter is not specific to the addresses that are provided.  This connection ID is provided to ensure that the client has a connection ID available for migration, but the client MAY use this connection ID on any path. </ins> 9.7. Endpoints that send data using IPv6 SHOULD apply an IPv6 flow label
Change:
Addresses NAME comments on . While this adds a new MUST NOT, I believe it's editorial because it's simply stating the implicit result of the "MUST verify" in that PR. If anyone disagrees, speak up and I'll change it. Separately, I think there's a case for this "MUST NOT" to be a "SHOULD NOT," as we all know there are situations in which clients proceed through a certificate warning. It's a reasonable semantic distinction whether the client does not consider the server authoritative but processes the result anyway (MUST NOT), or considers the server authoritative because the user told it to (SHOULD NOT). Opinions on the bikeshed welcome.

Discussion:
subjectAltName field of the certificate (see RFC6125).  For a host that is an IP address, the client MUST verify that the address appears as an iPAddress in the subjectAltName field of the <del> certificate. </del> <ins> certificate.  If the hostname or address is not present in the certificate, the client MUST NOT consider the server authoritative for origins containing that hostname or address.  See Section 5.4 of SEMANTICS for more detail on authoritative access. </ins> Clients SHOULD NOT open more than one HTTP/3 connection to a given host and port pair, where the host is derived from a URI, a selected
Change:
We already had something here, but I think that it missed the central reason, which is the combination of: wanting to replace all connection IDs having used the limit from activeconnectionid_limit wanting to ensure that there is >= 1 available connection IDs left This phrasing isn't quite that explicit, but I think that it is clear enough.
It is not obvious from this, but the intent here is to allow NEWCONNECTIONID to exceed the limit from activeconnectionid_limit.
Nice wording, looks good!

Discussion:
stop using the corresponding connection IDs and retire them with RETIRE_CONNECTION_ID frames before adding the newly provided connection ID to the set of active connection IDs.  This ordering <del> allows an endpoint that has already supplied its peer with as many connection IDs as allowed by the active_connection_id_limit transport parameter to replace those connection IDs with new ones as necessary. Failure to cease using the connection IDs when requested can result in connection failures, as the issuing endpoint might be unable to </del> <ins> allows an endpoint to replace all active connection IDs without the possibility of a peer having no available connection IDs and without exceeding the limit the peer sets in the active_connection_id_limit transport parameter; see transport-parameter-definitions.  Failure to cease using the connection IDs when requested can result in connection failures, as the issuing endpoint might be unable to </ins> continue using the connection IDs with the active connection. 5.2.
Change:
This is what the pseudocode says, but I couldn't find anywhere in the text that clarified that if there were no ack-eliciting packets to arm PTO from, use Now().

Discussion:
generated, it is possible that the probe timer expiration is due to an incorrect RTT estimate at the client.  To allow the client to improve its RTT estimate, the new packet that it sends MUST be ack- <del> eliciting.  If Handshake keys are available to the client, it MUST send a Handshake packet, and otherwise it MUST send an Initial packet in a UDP datagram of at least 1200 bytes. </del> <ins> eliciting. </ins> Initial packets and Handshake packets could be never acknowledged, but they are removed from bytes in flight when the Initial and

its address validation (see Section 8 of QUIC-TRANSPORT).  That is, the client MUST set the probe timer if the client has not received an acknowledgement for one of its Handshake or 1-RTT packets, and has <del> not received a HANDSHAKE_DONE frame. </del> <ins> not received a HANDSHAKE_DONE frame.  If Handshake keys are available to the client, it MUST send a Handshake packet, and otherwise it MUST send an Initial packet in a UDP datagram of at least 1200 bytes. A client could have received and acknowledged a Handshake packet, causing it to discard state for the Initial packet number space, but not sent any ack-eliciting Handshake packets.  In this case, the PTO is set from the current time. </ins> 5.2.3.
Change:
The new principle is to only use backticks when referring to variables in pseudocode. There were two such instances that remain.
In I came up with a principle that might apply to use of . Field names, frame names, transport parameter names, and error codes don't use any form of decoration. But if reference is being made to a variable in pseudocode, we would use backticks to distinguish it from. Qpack is a little tricky here because there is a mix of things. Note: backticks are quoted in for HTML and in double quotes () in text output. Sparing use is probably best.
WFM. Thanks. I was never clear on whether "Base" or "Required Insert Count" referred to pseudocode variables or not.

Discussion:
4.5.1.2. <del> The "Base" is used to resolve references in the dynamic table as </del> <ins> The Base is used to resolve references in the dynamic table as </ins> described in relative-indexing. To save space, the Base is encoded relative to the Required Insert <del> Count using a one-bit sign ('S') and the "Delta Base" value.  A sign </del> <ins> Count using a one-bit sign ('S') and the Delta Base value.  A sign </ins> bit of 0 indicates that the Base is greater than or equal to the value of the Required Insert Count; the decoder adds the value of Delta Base to the Required Insert Count to determine the value of the
Change:
Draft 27 says: Maybe I'm missing it but I can't see where we say how the GoAway receiver handles an seeing the GoAway ID getting increased. We typically state what the receiver should do in such a case. For instance, with MAXPUSHID we say " receipt of a MAXPUSHID that contains a smaller value than previously received MUST be treated as a connection error of type H3IDERROR.". I suggest that we need text that states receiving a larger GOAWAY ID than previously received MUST be treated as a connection error of type H3IDERROR. N.B. since draft-27 we landed changes to make the GOAWAY symmetrical. I believe this issue is still applicable to the most recent editors draft
H3IDERROR SGTM

Discussion:
send multiple GOAWAY frames indicating different identifiers, but MUST NOT increase the identifier value they send, since clients might already have retried unprocessed requests on another connection. <ins> Receiving a GOAWAY containing a larger identifier than previously received MUST be treated as a connection error of type H3_ID_ERROR. </ins> An endpoint that is attempting to gracefully shut down a connection can send a GOAWAY frame with a value set to the maximum possible
Change:
Happened to notice that the updated figure (didn't check the old one) was inconsistent with the text about the allowed length of the CID fields. Should be editorial, since the text wins any conflicts.
Bah, yes, 255 bytes = 2,040 bits.
:D That's exactly the process that my mind followed.
Both section 4.2 and 4.3 say Unfortunately, the doesn't have Xs. I'm not sure how to reword this to support both formats.
how about :)
I think this was fixed by URL, I dont know if that was just a coincidence or it was untagged
That was intentional. I just neglected to tag this.

Discussion:
4.1. <del> Long headers take the form described in fig-long.  Bits that have version-specific semantics are marked with an X. </del> <ins> Long headers take the form described in fig-long. </ins> A QUIC packet with a long header has the high bit of the first byte set to 1.  All other bits in that byte are version specific.

4.2. <del> Short headers take the form described in fig-short.  Bits that have version-specific semantics are marked with an X. </del> <ins> Short headers take the form described in fig-short. </ins> A QUIC packet with a short header has the high bit of the first byte set to 0.
Change:
Clarifies the impact of the anti-amplification factor on congestion control. Part of
When the client has a large first flight (post-quantum, or 0-RTT), it can send 10 packets at once. But that does not mean that the server can immediately send as much as 3x it receives in response, because that is above the INITCWND - the initial assumption about the network capacity. Things to be considered here are: Server cannot rely on CC until the client's address is validated, because an attacker might spoof Initial ACKs. At the very least, server needs to send one Initial in response to every client Initial packet not containing ACKs, otherwise the handshake might fail when there is heavy loss. Based on this observation, to me it seems that the easiest way of going forward would be to state that the amplification limit changes from 3x to 1x once the amount of data being sent by the server reaches INITCWND. Disclaimer: this issue popped up while trying to find out a response to NAME claim that quicly sends 3x that is above INITCWND, when the client sends a large amount of 0-RTT data. He's correct, and NAME and I think that this is a spec-issue.
Just to clarify, only an on-path attacker can do this, right?
I agree it should be limited to INITCWND. Here's how I read(and intended to write) the text: 1) Congestion control always applies, because I don't know of anywhere we say otherwise. 2) In addition, prior to address validation, the amplification limit of 3x also applies on the server side. Init CWND section: URL
NAME An off-path attacker can do that. An attacker can easily guess the packet number that the server uses, and spoof an ACK without actually receiving a packet from the server. Note also that there is no guarantee that there would be enough entropy in server-generated CID, even though a server can generate CIDs in such a manner. That's why we postpone the validation of the path until the server receives a Handshake packet. NAME I think I agree with you that the limit can be defined as .
Thanks NAME PTAL at PR and see if that clarifies this issue or if something else is necessary.
At the editor's meeting, we concluded that the pseudocode did not represent the current text about re-arming the PTO alarm. I merged the first PR because I think it's a nice clarification and I'll send out a PR for the pseudocode.
Thank you for the quick PR. I've stated my slight preference, but the text looks already :+1: to me.

Discussion:
the byte limit to account for the smaller 8 byte overhead of UDP compared to the 20 byte overhead for TCP. <ins> Prior to validating the client's address, the server can be further limited by the anti-amplification limit as specified in Section 8.1 of QUIC-TRANSPORT.  Though the anti-amplification limit can prevent the congestion window from being fully utilized and therefore slow down the increase in congestion window, it does not directly affect the congestion window. </ins> The minimum congestion window is the smallest value the congestion window can decrease to as a response to loss, ECN-CE, or persistent congestion.  The RECOMMENDED value is 2 * max_datagram_size.
Change:
The rules for the active connection ID limit were such that the brief bump that NEWCONNECTIONID + Retire Prior To could add was not permitted. Strictly speaking, if you requested retirement, the connection IDs that you requested be retired are still active until you receive a RETIRECONNECTIONID frame. That means that you were technically violating this MUST in the spec. Adding an exception for this case was the best way I could see to fix this. The other was to change the definition of "active connection ID". I tried that and, while it was a smaller change, it made the definition less crisp. This approach seems best. (This is not new normative requirements as this is already .)
LGTMThanks for making (yet) another attempt to clarify this. Looks good.

Discussion:
preferred_address transport parameter. An endpoint SHOULD ensure that its peer has a sufficient number of <del> available and unused connection IDs.  Endpoints store received connection IDs for future use and advertise the number of connection IDs they are willing to store with the active_connection_id_limit transport parameter.  An endpoint MUST NOT provide more connection IDs than the peer's limit.  An endpoint that receives more connection IDs than its advertised active_connection_id_limit MUST close the connection with an error of type CONNECTION_ID_LIMIT_ERROR. </del> <ins> available and unused connection IDs.  Endpoints advertise the number of active connection IDs they are willing to maintain using the active_connection_id_limit transport parameter.  An endpoint MUST NOT provide more connection IDs than the peer's limit.  An endpoint MAY send connection IDs that temporarily exceed a peer's limit if the NEW_CONNECTION_ID frame also requires the retirement of any excess, by including a sufficiently large value in the Retire Prior To field. A NEW_CONNECTION_ID frame might cause an endpoint to add some active connection IDs and retire others based on the value of the Retire Prior To field.  After processing a NEW_CONNECTION_ID frame and adding and retiring active connection IDs, if the number of active connection IDs exceeds the value advertised in its active_connection_id_limit transport parameter, an endpoint MUST close the connection with an error of type CONNECTION_ID_LIMIT_ERROR. </ins> An endpoint SHOULD supply a new connection ID when the peer retires a connection ID.  If an endpoint provided fewer connection IDs than the