jiebi/CodeConvo huggingface dataset:
Change:
and by documenting the core difference between TCP's RTO and QUIC's PTO.
QUIC: TCP:
Discussed in ZRH. Difference to be explained as an editorial comment.
Specifically, we'll add some text that describes how PTO in QUIC is different than RTO and TLP in TCP.
"When an ACK frame is received that establishes loss of all in-flight packets sent over a long enough period of time, the network is considered to be experiencing persistent congestion." QUIC declares persistent congestion only upon receipt of an ACK for a packet sent after entering loss recovery. This means that the cwnd will remain large and usable even if there is prolonged network silence with packets outstanding. If the state of the transport was application limited, this can cause a large burst on the network. In TCP, an RTO causes immediate drop of the cwnd to min_cwnd. Ideally QUIC should drop the cwnd in the same timescale as TCP would. Typically minrto for the Internet is 200 msec or 300 msec (and larger if the RTT is larger).
I do not want to change the existing algorithm, because the app-limited case is the case when the sender is strictly less aggressive than the congestion controller limits, so I believe it's less likely to cause issues for the network. I can write text pointing out this difference.
Discussed in ZRH. Proposed resolution is to close with no action. Editorial issue to explain the difference to TCP and its safety.
NAME this was in the latest batch of consensus calls, but you didn't mark it has having consensus. Can you review please?
You are correct, I missed this one somehow sorry so moving to has consensus
LGTM

Discussion:
a peer to maintain a more accurate round-trip time estimate (see Section 13.2 of QUIC-TRANSPORT). <ins> 3.1.7. QUIC uses a probe timeout (see pto), with a timer based on TCP's RTO computation.  QUIC's PTO includes the peer's maximum expected acknowledgement delay instead of using a fixed minimum timeout.  QUIC does not collapse the congestion window until persistent congestion (persistent-congestion) is declared, unlike TCP, which collapses the congestion window upon expiry of an RTO.  Instead of collapsing the congestion window and declaring everything in-flight lost, QUIC allows probe packets to temporarily exceed the congestion window whenever the timer expires. In doing this, QUIC avoids unnecessary congestion window reductions, obviating the need for correcting mechanisms such as F-RTO RFC5682. Since QUIC does not collapse the congestion window on a PTO expiration, a QUIC sender is not limited from sending more in-flight packets after a PTO expiration if it still has available congestion window.  This occurs when a sender is application-limited and the PTO timer expires.  This is more aggressive than TCP's RTO mechanism when application-limited, but identical when not application-limited. A single packet loss at the tail does not indicate persistent congestion, so QUIC specifies a time-based definition to ensure one or more packets are sent prior to a dramatic decrease in congestion window; see persistent-congestion. </ins> 4. At a high level, an endpoint measures the time from when a packet was
Change:
Similar to TCP as described in Section 5 of RFC 6675
Should we restrict this to retransmittable frames that were lost in the packet? If it was a small packet, can I pack to the MTU? What about pure ACKs that I've declared lost?
Those are great questions. There are two goals in my mind. The first is to ensure loss recovery is not unnecessarily slower than TCP. The second is to ensure this behavior isn't significantly more aggressive than TCP. But within those bounds, I'm inclined to not be too restrictive, if that makes sense? Suggestions welcome if you think they'd be an improvement.
Well the pedantic answer is that TCP would only detect a loss if there was something in the bytestream. the QUIC equivalents would then be any packet that contained STREAM, CRYPTO, MAXSTREAMDATA, etc, plus any packet that flipped the key update bit. But not ACK, MAX_DATA, and other things that are in the TCP header. That is obviously a dumb way to approach things. I don't actually have a strong opinion on this one way of the other, but if I read the draft correctly, the loss of an ACK-only packet will affect cwnd in QUIC but not TCP (granted, a cwnd-constrained endpoint sending pure ACKs is a corner case). So I guess I'd err on the side of permitting the packet in response to loss of an ACK, as we're already quite a bit less aggressive than TCP in that case. Anyway, do we want any normative language against, say, using this permission to send high-priority new data instead of the lost data?
Adding language against sending new data or data besides data that's been lost couples the "can I send" with "what should I send" questions more than I would like unless it's absolutely critical. FYI, to be declared lost, it must be in-flight: URL "A packet is declared lost if it meets all the following conditions: The packet is unacknowledged, in-flight, and was sent prior to an acknowledged packet."
Ah, I think we're fine then.
TCP recommends that a sender retransmit a packet immediately upon detecting the first loss in a recovery window (see Section 3.2, second para, of RFC 5681; Section 5 of RFC 6675 seems to follow the same idea). QUIC should at least allow the same. Not doing this can delay loss recovery by 0.5 RTT, which is not great. This replaces ; this is a more correct description of the problem, which is a design issue.
Discussed in ZRH. Proposed resolution is to get a PR done.

Discussion:
round trip.  During recovery, the congestion window remains unchanged irrespective of new losses or increases in the ECN-CE counter. <ins> When entering recovery, a single packet MAY be sent even if bytes in flight now exceeds the recently reduced congestion window.  This speeds up loss recovery if the data in the lost packet is retransmitted and is similar to TCP as described in Section 5 of RFC6675.  If further packets are lost while the sender is in recovery, sending any packets in response MUST obey the congestion window limit. </ins> 6.6. During the handshake, some packet protection keys might not be
Change:
From NAME and NAME comments on
In I received a number of comments on the existing text from NAME and NAME . This is an issue to track improving that text in a separate PR. One suggestion was to introduce an ITO(Idle Timeout) acronym.
NAME thinks cognitive load is increased by ITO and it's not that much shorter, so let's not do that.

Discussion:
An endpoint restarts its idle timer when a packet from its peer is received and processed successfully.  The idle timer is also <del> restarted when sending an ack-eliciting packet (see QUIC-RECOVERY), but only if no other ack-eliciting packets have been sent since last receiving a packet.  Restarting when sending packets ensures that connections do not prematurely time out when initiating new activity. An endpoint might need to send packets to avoid an idle timeout if it is unable to send application data due to being blocked on flow control limits; see flow-control. </del> <ins> restarted when sending the first ack-eliciting packet (see QUIC- RECOVERY) after receiving a packet.  Restarting when sending packets ensures that connections do not prematurely time out when initiating new activity.  Only restarting when sending after receipt of a packet ensures the idle timeout is not excessively lengthened past the time the peer's timeout has expired.  An endpoint might need to send packets to avoid an idle timeout if it is unable to send application data due to being blocked on flow control limits; see flow-control. </ins> An endpoint that sends packets near the end of the idle timeout period risks having those packets discarded if its peer enters the draining state before the packets arrive.  If a peer could time out within a Probe Timeout (PTO; see Section 6.6 of QUIC-RECOVERY), it is <del> advisable to test for liveness before sending any data that cannot be retried safely.  Note that it is likely that only applications or application protocols will know what information can be retried. </del> <ins> advisable to probe the path with an ack-eliciting packet to ensure the connection is still responsive before sending any data that cannot be retried safely.  Note that it is likely that only applications or application protocols will know what information can be retried. </ins> 10.3.
Change:
Much belated, this attempts to address the concerns about deadlocking. Basically, this says that you should avoid instructions that don't have flow control credit. It doesn't say how an encoder might learn what limits are, but we've seen a range of tactics being used in implementations and I don't want to get into transport API debates. This doesn't cover the memory exhaustion attack that NAME suggests on the issue; I think that is better covered more generally by the connection-level flow control limits.
I debated adding another paragraph:
Thanks for adding this!

Discussion:
2.1.4. <ins> Writing instructions on streams that are limited by flow control can produce deadlocks. A decoder might stop issuing flow control credit on the stream that carries a header block until the necessary updates are received on the encoder stream.  If the granting of flow control credit on the encoder stream (or the connection as a whole) depends on the consumption and release of data on the stream carrying the header block, a deadlock might result. More generally, a stream containing a large instruction can become deadlocked if the decoder withholds flow control credit until the instruction is completely received. To avoid these deadlocks, an encoder SHOULD avoid writing an instruction unless sufficient stream and connection flow control credit is available for the entire instruction. 2.1.5. </ins> The Known Received Count is the total number of dynamic table insertions and duplications acknowledged by the decoder.  The encoder tracks the Known Received Count in order to identify which dynamic
Change:
In recovery for maxackdelay of 0.
Section 5.2.1 of -recovery-25 says: However, Section 13.2.5 of -transport-25 doesn't actually say that (anymore?) Section 13.2.1 says so I guess at least the reference is incorrect. But since Section 19.3 only has a SHOULD for encoding zero and the pseudo code simply uses the encoded ACK delay, if the ACK sender doesn't encode zero, the ACK receiver will compute its RTT based on the encoded ACK delay.
The intent is to use 0 as a peer maxackdelay for the Initial and Handshake packet number spaces. The pseudocode says: ackdelay = min(Ack Delay in ACK Frame, maxack_delay) So for Initial and Handshake, min(Ack Delay, 0) = 0 The text in the "Estimating smoothed RTT and RTTVar" section is fairly clear I think? I fixed the section reference in
I understood the in the to be the value of the transport parameter?
Not for Initial and Handshake PN spaces. Would it be helpful to have a comment above the min() in the pseudocode?
That would at least help me (pointing out it is NOT the value of the TP, although the name is the same.)
I noticed the pseudocode before UpdateRtt() already makes this fairly clear. I can fold the pn_space check into UpdateRtt if you think it would read more clearly?
Ah, so we are not limiting , we are overwriting .

Discussion:
estimate (4*rttvar), and max_ack_delay, to account for the maximum time by which a receiver might delay sending an acknowledgement. When the PTO is armed for Initial or Handshake packet number spaces, <del> the max_ack_delay is 0, as specified in 13.2.5 of QUIC-TRANSPORT. </del> <ins> the max_ack_delay is 0, as specified in 13.2.1 of QUIC-TRANSPORT. </ins> The PTO value MUST be set to at least kGranularity, to avoid the timer expiring immediately.
Change:
by clarifying that one may start with a smaller time threshold, not a smaller packet threshold.
The doc says: "Implementations that detect spurious retransmissions and increase the reordering threshold in packets or time MAY choose to start with smaller initial reordering thresholds to minimize recovery latency." For the packet based threshold does that this say that a smaller initial value than 3 packets could be used? Is that really sensible? And for a time based threshold I don't really understand what this means because the threshold is anyway calculated dynamically based on the RTT, so there is no real initial value. I guess there was a time when the threshold was a fixed value and this sentence is maybe a left-over?
Given the current guidance to never use packet thresholds below 3, I think this text should be changed to be clear that you can start with a smaller fraction of RTT and it only applies to time threshold.
I think the fix will be editorial, but once a PR is out we'll know for sure.
If it's only about time-based threshold, any advise should be moved in the respective subsection. However, I would also be okay to just remove this sentence/paragraph...

Discussion:
Spuriously declaring packets as lost leads to unnecessary retransmissions and may result in degraded performance due to the actions of the congestion controller upon detecting loss. <del> Implementations that detect spurious retransmissions and increase the reordering threshold in packets or time MAY choose to start with smaller initial reordering thresholds to minimize recovery latency. </del> <ins> Implementations can detect spurious retransmissions and increase the reordering threshold in packets or time to reduce future spurious retransmissions and loss events.  Implementations with adaptive time thresholds MAY choose to start with smaller initial reordering thresholds to minimize recovery latency. </ins> 5.1.1.
Change:
I believe this section was mistakenly on the wrong level. I also added a reference to a later section to the last sentence. Alternatively this sentence could just be removed as this is normatively specified later on.

Discussion:
is expected to both expire earlier than the PTO and be less likely to spuriously retransmit data. <del> 5.3. </del> <ins> 5.2.2. </ins> The initial probe timeout for a new connection or new path SHOULD be set to twice the initial RTT.  Resumed connections over the same

Initial packets and Handshake packets could be never acknowledged, but they are removed from bytes in flight when the Initial and <del> Handshake keys are discarded.  When Initial or Handshake keys are discarded, the PTO and loss detection timers MUST be reset, because discarding keys indicates forward progress and the loss detection timer may have been set for a now discarded packet number space. </del> <ins> Handshake keys are discarded, as described below in Section discarding-packets.  When Initial or Handshake keys are discarded, the PTO and loss detection timers MUST be reset, because discarding keys indicates forward progress and the loss detection timer might have been set for a now discarded packet number space. </ins> <del> 5.3.1. </del> <ins> 5.2.3. </ins> When a PTO timer expires, a sender MUST send at least one ack- eliciting packet in the packet number space as a probe, unless there

Sending different payloads each time reduces the chances of spurious retransmission. <del> 5.3.2. </del> <ins> 5.2.4. </ins> Delivery or loss of packets in flight is established when an ACK frame is received that newly acknowledges one or more packets.

detection proceeds as dictated by packet and time threshold mechanisms; see ack-loss-detection. <del> 5.4. </del> <ins> 5.3. </ins> A Retry packet causes a client to send another Initial packet, effectively restarting the connection process.  A Retry packet

Version Negotiation packet is received.  The client MAY use this value in place of its default for the initial RTT estimate. <del> 5.5. </del> <ins> 5.4. </ins> When packet protection keys are discarded (see Section 4.10 of QUIC- TLS), all packets that were sent with those keys can no longer be
Change:
Follow-up to URL
Or "for indicating" :man_shrugging: not sure what the most appropriate one is.

Discussion:
target host to the server during the TLS handshake.  If the server is identified by a DNS name, clients MUST send the Server Name Indication (SNI) RFC6066 TLS extension unless an alternative <del> mechanism for indicate the target host is used. </del> <ins> mechanism to indicate the target host is used. </ins> QUIC connections are established as described in QUIC-TRANSPORT. During connection establishment, HTTP/3 support is indicated by
Change:
This isn't strictly necessary, as it might be implied by the definition of a connection ID. I tried tweaking the connection ID definition, but it is hard to say anything concrete because of the way that addressing can also be used in combination with connection IDs to identify a connection at an endpoint. So I left that alone.
I agree that a connection ID identifies one session, and due to forbidden correlation, it is clear that a connection ID in use cannot proliferate. However, this is not implied for newly issued connection IDs. There is precedence for new tokens which do apply to new connections, so I think it is worth being precise here.
added the text " Connection IDs that are issued and not retired are considered active; any active connection ID is valid for use at any time, in any packet type. " As far as I can tell there is no text specifying that an issued connection ID cannot be used with subsequent connections. The introduction to connection IDs state that there must not be correlation across connections, but if an issued connection ID was never consumed, there would be no correlation because it was transmitted encrypted.
Not really sure if this is necessary. The text around this sentence implies that connection IDs identify one connection (which shouldn't be too surprising in the first place). It's only when you take this one sentence out of context, that the "problem" of occurs.

Discussion:
its peer invalidates the connection ID via a RETIRE_CONNECTION_ID frame (frame-retire-connection-id).  Connection IDs that are issued and not retired are considered active; any active connection ID is <del> valid for use at any time, in any packet type.  This includes the connection ID issued by the server via the preferred_address transport parameter. </del> <ins> valid for use with the current connection at any time, in any packet type.  This includes the connection ID issued by the server via the preferred_address transport parameter. </ins> An endpoint SHOULD ensure that its peer has a sufficient number of available and unused connection IDs.  Endpoints store received
Change:
Clarifies exactly what the implications of not arming PTO for ApplicationData prior to handshake complete. This came from a discussion with a coworker who read the transport and recovery drafts, but not TLS.
Thanks! I think this is much clearer from implementation perspective.

Discussion:
number spaces, the timer MUST be set for the packet number space with the earliest timeout, except for ApplicationData, which MUST be ignored until the handshake completes; see Section 4.1.1 of QUIC-TLS. <del> Not arming the PTO for ApplicationData prioritizes completing the handshake and prevents the server from sending a 1-RTT packet on a PTO before before it has the keys to process a 1-RTT packet. </del> <ins> Not arming the PTO for ApplicationData prevents a client from retransmitting a 0-RTT packet on a PTO expiration before confirming that the server is able to decrypt 0-RTT packets, and prevents a server from sending a 1-RTT packet on a PTO expiration before it has the keys to process an acknowledgement. </ins> When a PTO timer expires, the PTO period MUST be set to twice its current value.  This exponential reduction in the sender's rate is
Change:
This my need a design issue because I suggest to use two SHOULDs instead of should. However, I would first like to get some feedback if people agree.
I think this is editorial, because it fixes an error. I always intended these to be normative SHOULD/SHOULD NOT
I'm going with editorial also.
Yup, this is editorial.
Thanks, this is certainly what I meant when I wrote this text.

Discussion:
congestion window, or a pacer might pace out packets handed to it by the congestion controller.  Timely delivery of ACK frames is important for efficient loss recovery.  Packets containing only ACK <del> frames should therefore not be paced, to avoid delaying their </del> <ins> frames SHOULD therefore not be paced, to avoid delaying their </ins> delivery to the peer. Sending multiple packets into the network without any delay between

A sender that paces packets (see pacing) might delay sending packets and not fully utilize the congestion window due to this delay.  A <del> sender should not consider itself application limited if it would </del> <ins> sender SHOULD NOT consider itself application limited if it would </ins> have fully utilized the congestion window without pacing delay. A sender MAY implement alternative mechanisms to update its
Change:
The recovery draft says: "Resumed connections over the same network SHOULD use the previous connection's final smoothed RTT value as the resumed connection's initial RTT." I wonder if we should change this to a MAY, as there is also a temporal aspect. Or maybe we should say more about this? Also note that draft-ietf-tcpm-2140bis is probably related.
I would agree with switching to MAY. Even mentioning this leads to some incentive to implement, so the effect on implementation is similar. But we really don't need to recommend something like this.

Discussion:
The initial probe timeout for a new connection or new path SHOULD be set to twice the initial RTT.  Resumed connections over the same <del> network SHOULD use the previous connection's final smoothed RTT value as the resumed connection's initial RTT.  If no previous RTT is </del> <ins> network MAY use the previous connection's final smoothed RTT value as the resumed connection's initial RTT.  If no previous RTT is </ins> available, the initial RTT SHOULD be set to 500ms, resulting in a 1 second initial timeout as recommended in RFC6298.
Change:
I believe this always should have been normative, so this change is editorial, but I'll let the editors confirm that.

Discussion:
maximum ack delay.  Packets that are not ack-eliciting are only acknowledged when an ACK frame is sent for other reasons. <del> When sending a packet for any reason, an endpoint should attempt to </del> <ins> When sending a packet for any reason, an endpoint SHOULD attempt to </ins> bundle an ACK frame if one has not been sent recently.  Doing so helps with timely loss detection at the peer.
Change:
Adds more text about what the constant kGranularity represents where it's first used and changes a SHOULD to a RECOMMENDED. Inspired by
This seems reasonable.

Discussion:
acknowledged, an endpoint SHOULD declare an earlier packet lost if it was sent a threshold amount of time in the past.  To avoid declaring packets as lost too early, this time threshold MUST be set to at <del> least kGranularity.  The time threshold is: </del> <ins> least the local timer granularity, as indicated by the kGranularity constant.  The time threshold is: </ins> If packets sent prior to the largest acknowledged packet cannot yet be declared lost, then a timer SHOULD be set for the remaining time.
Change:
I assume this has been the intention all along, but I do not find normative language in the current draft.

Discussion:
contain the final size of the stream.  Setting this bit indicates that the frame marks the end of the stream. <del> An endpoint that receives a STREAM frame for a send-only stream MUST terminate the connection with error STREAM_STATE_ERROR. </del> <ins> An endpoint MUST terminate the connection with error STREAM_STATE_ERROR if it receives a STREAM frame for a locally- initiated stream that has not yet been created, or for a send-only stream. </ins> The STREAM frames are shown in fig-stream.