Subject: [tcpm] RACK - variable explanation

From: Felix Weinrank <[email-masked]>
Date: Thu, 22 Nov 2018 13:25:24 +0100

Hey RACK authors,

we're evaluating the nuts and bolts of RACK in its current version and 
we are missing variable explanations.
Most of the variables are listed and explained in section 5 (Definitions 
of variables) but at least two are missing.

SND.UNA
RACK.dupthresh << This is where we're stuck

And I think this paragraph from section 5 needs two cosmetic newlines:
"RACK.reo_wnd_persist" is the number of loss recoveries before
resetting RACK.reo_wnd "RACK.dsack" indicates if a DSACK option has
been received since last RACK.reo_wnd change "RACK.pkts_sacked"
returns the total number of packets selectively acknowledged in the
SACK scoreboard.

Best regards
Felix Weinrank

---

From: Neal Cardwell <[email-masked]>
Date: Thu, 22 Nov 2018 09:58:40 -0500

> of variables) but at least two are missing.

Thanks for pointing these out! We'll add these in the next draft.

> SND.UNA

The RACK draft uses the SND.UNA and SND.NXT notations from the TCP RFC
(from https://tools.ietf.org/html/rfc793#section-3.3 on page 25):

   SND.UNA = oldest unacknowledged sequence number

   SND.NXT = next sequence number to be sent

> RACK.dupthresh << This is where we're stuck

This is using the DupThresh term from RFC 6675, "A Conservative Loss
Recovery Algorithm Based on Selective Acknowledgment (SACK) for TCP"
(from https://tools.ietf.org/html/rfc6675 on page 4):

   We define a variable "DupThresh" that holds the number of duplicate
   acknowledgments required to trigger a retransmission.  Per [RFC5681],
   this threshold is defined to be 3 duplicate acknowledgments.

> returns the total number of packets selectively acknowledged in the

Thanks for pointing out the missing newlines! We will try to get that
formatting cleaned up in the next rev.

thanks,
neal

---

From: Michael Tuexen <[email-masked]>
Date: Thu, 22 Nov 2018 16:01:09 +0100

> On 22. Nov 2018, at 13:25, Felix Weinrank <[email-masked]> wrote:
> 
> Hey RACK authors,
> 
> we're evaluating the nuts and bolts of RACK in its current version and we are missing variable explanations.
> Most of the variables are listed and explained in section 5 (Definitions of variables) but at least two are missing.
> 
> SND.UNA
The above is a standard TCP variable explained in
https://tools.ietf.org/html/rfc793#section-3.2

Best regards
Michael
> _______________________________________________
> tcpm mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tcpm

---

From: Michael Tuexen <[email-masked]>
Date: Thu, 22 Nov 2018 16:03:39 +0100

> On 22. Nov 2018, at 15:58, Neal Cardwell <ncardwell=[email-masked]> wrote:
> 
Please add such a description for RACK.dupthresh to Section 5.

Best regards
Michael

---

From: Felix Weinrank <[email-masked]>
Date: Thu, 22 Nov 2018 16:28:26 +0100

>     this threshold is defined to be 3 duplicate acknowledgments.
Thanks for the explanation.

I don't completely understand the following check:

        If RACK.reordering_seen is FALSE:
            If in loss recovery:  /* If in fast or timeout recovery */
                RACK.reo_wnd = 0
                Return
            Else if RACK.pkts_sacked >= RACK.dupthresh:
                RACK.reo_wnd = 0
                return

The Draft says:
"RACK.pkts_sacked" returns the total number of packets selectively 
acknowledged in the SACK scoreboard.

Whats the purpose of this check: RACK.pkts_sacked >= RACK.dupthresh

Best regards
Felix

---

From: Neal Cardwell <[email-masked]>
Date: Thu, 22 Nov 2018 10:28:17 -0500

> Please add such a description for RACK.dupthresh to Section 5.

Thanks, Michael. Based on this discussion, we have inserted a
definition of RACK.dupthresh in Section 5 in our internal version of
the draft, so it will be in the next rev.

thanks,
neal

---

From: Michael Tuexen <[email-masked]>
Date: Thu, 22 Nov 2018 17:00:59 +0100

> On 22. Nov 2018, at 16:28, Neal Cardwell <[email-masked]> wrote:
> 
Great, thanks a lot.

Best regards
Michael

---

From: Neal Cardwell <[email-masked]>
Date: Thu, 22 Nov 2018 11:16:26 -0500

> Whats the purpose of this check: RACK.pkts_sacked >= RACK.dupthresh

This is the traditional TCP Fast Retransmit heuristic, described in
https://tools.ietf.org/html/rfc5681 in section 3.2, and
https://tools.ietf.org/html/rfc6675 in section 5, and the older
https://tools.ietf.org/html/rfc2001 in section 3.

One way to think about it would be: if a receiver selectively
acknowledges a data sequence range, then that means there is an
unacknowledged "hole" in the sequence space below the selectively
acknowledged range.  There are two main possibilities for this hole:
(1) That unacknowledged hole will stay unacknowledged indefinitely,
suggesting that the original packets containing that data were
permanently lost, and need to be retransmitted (which this algorithm
triggers). (2) That unacknowledged hole will be acknowledged later,
which would suggest that the network reordered the data somewhere in
transit, delaying the earlier data and causing it to arrive after the
later data. Waiting for three data segments to be selectively
acknowledged allows extra "settling" time for that reordered packet to
make it to the receiver and fill that hole; this implicit settling
delay helps avoid spurious retransmits in cases where the network has
started to reorder packets but the sender has not had a chance to
observe the reordering yet. For cases where the sender has observed
reordering (RACK.reord is true) then the sender maintains (in
RACK.reo_wnd) an explicit estimate of how long (in time) it should
wait for such reordering to settle, before triggering a fast
retransmit.

BTW, for consistency, the line that says:

should use the "RACK.reord" name, and should be:

   If RACK.reord is FALSE:

That will be fixed in the next rev.

thanks,
neal

---

From: Felix Weinrank <[email-masked]>
Date: Fri, 23 Nov 2018 17:43:06 +0100

Thank you very much for the explanation, this helps a lot! :)

Felix

---

From: "Scheffenegger, Richard" <[email-masked]>
Date: Wed, 28 Nov 2018 16:27:47 +0100

Hi Neal,

> https://tools.ietf.org/html/rfc2001 in section 3.

To be pedandic, only RFC3517 and RFC6675 would be applicable directly, 
as RACK requires SACK support.

Also, RFC6675 explicitly shortened the trigger condition from receiving 
3 DupACKs down to FACK > (dupthresh - 1)*SMSS. That is, RFC6675 allows
entering Loss Recovery on the first ACK(SACK), without waiting for any 
duplicate ACKs at all... Thus it is much more "aggressive", and I've 
seen two independent examples recently, where Receivers exploit this 
capability (and don't work well against a RFC3517 sender).

Earlier 3517 still needed 3 duplicate ACKs.

In that context, RACK takes a middle ground, as the receiver has to have 
seen dupthresh data segments, but the sender can enter loss recovery 
already, even when ACK loss, ACK compression or ACK thinning are 
prevalent in the return path.

(A single ACK, with an appropriate SACK block(s) is still sufficient to 
enter LR with RACK, but unlike 6675, positive proof that 3 packets got 
delivered is required).

Which is a Good Thing (TM) :)

---

From: Ilpo Järvinen <[email-masked]>
Date: Wed, 28 Nov 2018 17:56:44 +0200 (EET)

On Wed, 28 Nov 2018, Richard Scheffenegger wrote:
> To be pedandic, only RFC3517 and RFC6675 would be applicable directly, as RACK
> requires SACK support.
> 
> Also, RFC6675 explicitly shortened the trigger condition from receiving 3
> DupACKs down to FACK > (dupthresh - 1)*SMSS. 

Where does that "FACK" part come from? Not from RFC6675 for sure. The 
condition given in RFC6675 requires at least that many bytes to be 
acknowledged by SACK blocks to trigger recovery, not just sequence 
distance like FACK does.

> That is, RFC6675 allows
> duplicate ACKs at all... Thus it is much more "aggressive", and I've seen two
> independent examples recently, where Receivers exploit this capability (and
> don't work well against a RFC3517 sender).
> 
> In that context, RACK takes a middle ground, as the receiver has to have seen
> dupthresh data segments, but the sender can enter loss recovery already, even
> when ACK loss, ACK compression or ACK thinning are prevalent in the return
> path.
> 
> (A single ACK, with an appropriate SACK block(s) is still sufficient to enter
> LR with RACK, but unlike 6675, positive proof that 3 packets got delivered is
> required).
> 

RFC6675 algorithm requires a positive proof that at least 3 MSS sized 
packets were delirered. The algorithm just doesn't use dup ACK as a proxy 
for that but bases the decision on scoreboard details only. Maybe you're 
misreading the RFC6675 somehow?

-- 
 i.

---

From: Yuchung Cheng <[email-masked]>
Date: Wed, 28 Nov 2018 08:09:38 -0800

> misreading the RFC6675 somehow?
This is to echo Ilpo's question that RFC6675 requires 3 OOO pkts to trigger.