Nice find, Martin!

I second Ian that this problem deserves a GitHub issue.

Regarding how we proceed, I think we can simply remove the statement: “When
an ack-eliciting packet is received with a packet number less than Largest
Acked, this still triggers an immediate acknowledgement in an effort to
avoid the packet being spuriously declared lost.”

Consider Packet-number-based loss detection:

When a sender advertises an ack_frequency.reordering_threshold of N, the
assumption is that the sender will not declare a packet lost until the gap
between the packet number (PN) of an outstanding packet and the largest PN
acknowledged becomes greater than N.

This, in turn, means that the receiver does not need to acknowledge such
packets immediately *if the PN of the out-of-order packet falls within the
gap defined by ack_frequency.reordering_threshold*.

Otherwise, the packet must be acknowledged immediately, but in fact
Section 6.2 already states: “An endpoint that receives an ACK_FREQUENCY
frame with a non-zero Reordering Threshold value SHOULD send an immediate
ACK when the gap between the smallest Unreported Missing packet and the
Largest Unacked is greater than or equal to the Reordering Threshold value.”

Consider Time-based loss detection:

The idea behind time-based loss detection is that *any* packet can be
acknowledged within a certain timeframe. It is reasonable to argue that
this timeframe equals the one-way delay in each direction plus the
max_ack_delay value. Under that interpretation, it is safe to delay ACKs
for out-of-order packets that fall within the threshold advertised in the
ACK_FREQUENCY frame.
Thoughts? It has been a while since I last thought about Ack Frequency, so
I could be missing something.

2025年5月16日(金) 3:40 Martin Duke <[email protected]>:

> Ack-Eliciting Threshold:
>> A variable-length integer representing the maximum number of
>> ack-eliciting packets the recipient of this frame receives before sending
>> an acknowledgment.
>
>
> ack-eliciting-threshold has no reference to packet gaps. The plain meaning
> of this definition is that, absent any other rules about gap fillers, every
> (ack_eliciting_threshold + 1) packets would be acked regardless of their
> relationship to largest_acked.
>
> On Thu, May 15, 2025 at 11:35 AM Mirja Kuehlewind <
> [email protected]> wrote:
>
>> The ack_eliciting_threshold is only defined in relation to packet gaps
>> and not when a gap gets filled. You could only relay on the normal ack
>> delay for that but that might be quite high.
>>
>>
>>
>>
>>
>>
>>
>> *From: *Martin Duke <[email protected]>
>> *Date: *Thursday, 15. May 2025 at 19:43
>> *To: *Mirja Kuehlewind <[email protected]>
>> *Cc: *Ian Swett <[email protected]>, IETF QUIC WG <
>> [email protected]>
>> *Subject: *Re: Old packets in draft-ietf-quic-ack-frequency-11
>>
>>
>>
>> Compared to acking packets occasionally in accordance with
>> ack_eliciting_threshold.
>>
>>
>>
>> On Thu, May 15, 2025 at 10:27 AM Mirja Kuehlewind <
>> [email protected]> wrote:
>>
>> „accomplishes very little“ compared to what? Not acking is not an option
>> and as such we simply apply the rule that is already in RFC9000 without
>> further optimization. In other words we simply didn’t consider
>> changing/optimizating the “gap filling” logic in the draft. I guess you
>> could so something like only sending an ACK for the first packet in a gap
>> and if the gap is filled completely but that sounds all complicated.
>>
>>
>>
>>
>>
>> *From: *Martin Duke <[email protected]>
>> *Date: *Thursday, 15. May 2025 at 18:06
>> *To: *Mirja Kuehlewind <[email protected]>
>> *Cc: *Ian Swett <[email protected]>, IETF QUIC WG <
>> [email protected]>
>> *Subject: *Re: Old packets in draft-ietf-quic-ack-frequency-11
>>
>>
>>
>> I agree that not sending acks at all would be a problem.
>>
>>
>>
>> I don't have any data. But my contention is that the current rule
>> accomplishes very little while making this "not super likely" case
>> considerably worse.
>>
>>
>>
>> On Thu, May 15, 2025 at 9:01 AM Mirja Kuehlewind <
>> [email protected]> wrote:
>>
>> Note that issue #306 was also related to this:
>> https://github.com/quicwg/ack-frequency/issues/306
>>
>>
>>
>> As I said there, you could probably further optimize this but it would be
>> a mistake if you don’t send ACK for packets that arrive late at all (which
>> wasn’t clearly explicitly covered in the draft before).
>>
>>
>>
>> However, I think your example below is also not the super likely case. In
>> your examples it’s basically that packets 10 and 11 arrive earlier, while a
>> whole range of packets would get delayed. So not sure how important it is
>> to optimize for that case. I would expect it is more likely to see single
>> packets re-ordered. Do you happen to have any data on re-ordering patterns?
>>
>>
>>
>> Mirja
>>
>>
>>
>>
>>
>>
>>
>> *From: *Ian Swett <[email protected]>
>> *Date: *Thursday, 15. May 2025 at 17:34
>> *To: *Martin Duke <[email protected]>
>> *Cc: *IETF QUIC WG <[email protected]>, Ian Swett <ianswett=
>> [email protected]>
>> *Subject: *Re: Old packets in draft-ietf-quic-ack-frequency-11
>>
>>
>>
>> These are some excellent observations and please file an issue.  I'm not
>> sure we want to make substantial changes, but we might want to at least
>> call this out.
>>
>>
>>
>> If the peer is accurately communicating their packet threshold in the
>> ACK_FREQUENCY frame, then I believe you're correct that this requirement to
>> immediately send an ACK is useless, at least for the purposes of packet
>> threshold loss detection.  Time threshold is much more difficult to
>> reason about, particularly because transmission delays are variable and
>> timers aren't perfect.  Currently the peer's ack delay is included in PTO
>> timer, but not time threshold loss detection, because this immediate ACK
>> behavior is assumed.
>>
>>
>>
>> There are some potential interactions with congestion control,
>> particularly when first entering recovery when the CWND might have
>> decreased substantially and/or you're doing packet conservation.  You might
>> be able to declare a number of packets lost, but only send one or two, so
>> getting an ACK earlier could prevent some spurious retransmissions.  Or it
>> might not because the ACKs you're getting might be exactly the packets
>> you've already spuriously retransmitted.
>>
>>
>>
>> Thanks, Ian
>>
>>
>>
>> On Thu, May 15, 2025 at 10:37 AM Martin Duke <[email protected]>
>> wrote:
>>
>> I'm finally turning my attention to updating our ack-frequency
>> implementation from draft-iyengar-quic-delayed-ack-01 (!!!) to the current
>> draft.
>>
>>
>>
>> *TL;DR **The ack-frequency draft defers to RFC 9000 by saying that any
>> packet < largest_acked is acked immediately regardless of any of the
>> ACK_FREQUENCY frame fields. Maybe that's suboptimal?*
>>
>> I stumbled across issue 304
>> <https://github.com/quicwg/ack-frequency/issues/304>,  which clarifies
>> that RFC 9000 rules about ACKing packets < largest_acked still apply:
>>
>> When an ack-eliciting packet is received with a packet number less than
>> Largest Acked, this still triggers an immediate acknowledgement in an
>> effort to avoid the packet being spuriously declared lost.
>>
>>
>>
>> To be clear: this totally works, and in no case makes things worse than
>> the baseline. In the "normal" case when packet gaps are loss, not
>> reordering, it has no effect at all.
>>
>>
>>
>> However, I wonder if this rule is far less than optimal in cases with a
>> lot of reordering, and may add little to no value in more common cases.
>> Loss and reordering both manifest as a sudden jump in sequence number; if a
>> reordering case, the gap packets will arrive later. The reordering_thresh
>> field can suppress the ack of this first jump, but not the followon packets
>> with lower numbers.
>>
>>
>>
>> For example, Say that ack_eliciting_threshold is 1 (the default) but
>> reordering_threshold is zero (meaning, ignore reordering). If the pattern
>> of packet arrival is 10, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, then there will be
>> 10 ACKs: one for 11, as the second packet to arrive, and then one for each
>> of 1:9 because they are all less than largest_acked. In this case, network
>> reordering has caused the ack rate to be roughly double what the receiver
>> requested. Without the text in question, one would expect an ack for 11, 2,
>> 4, 6, and 8.
>>
>>
>>
>> In the issue, the stipulation is that acking these packets will prevent
>> spurious retransmits. If true, that would be valuable. However:
>>
>>
>>
>> - If the sender is using RFC 9002 time-based recovery, the important
>> thing is that the ack arrives before the timeout. IIUC, this is best
>> ensured via requested_max_ack_delay rather than through this mechanism.
>>
>>
>>
>> - If the sender is using packet-based recovery, the additional acks don't
>> really help. If ack_eliciting_threshold is set correctly, there won't be a
>> retransmission until another ACK arrives. If the ACK is delayed till
>> another packet arrives, the sender's state for the early packet won't
>> change in the meantime.
>>
>>
>>
>> I find this hard to reason about, and am happy to be told I'm holding it
>> wrong. There are second-order considerations about lost acks, etc. But if
>> others think the text is suboptimal, I'm happy to file an issue.
>>
>>
>>
>> Martin
>>
>>

-- 
Kazuho Oku

Reply via email to