Subject: [tcpm] ECN++

From: "Scheffenegger, Richard" <[email-masked]>
Date: Fri, 10 Jan 2020 01:08:04 +0100

Marcelo, Bob,

I just noted that there is a slight oversight in FreeBSD currently,
which results in all session that are simultaneously ECN-enabled and
SACK-permitted to effectively send out retransmissions with the ECT0
codepoint.

Strictly speaking, this is in violation of RFC3168, but might also be a
good (nearly a decade long) validation of the performance of ECN++ for
all types of data segments (new and retransmitted ones), although at a
low and implicit exposure...

On that note, since I think ECN++ is quite valuable (with a number of
published research finding this change to be crucial), perhaps you can
summarize the outstanding issues (other than more reviewers required; I
admit I still haven't gone through all the delta between -04 and -05).

Best regards,
   Richard

---

From: "Scheffenegger, Richard" <[email-masked]>
Date: Wed, 15 Jan 2020 21:42:28 +0100

Hi,

Yet another interesting observation – as fbsd currently doesn’t refrain
from marking SACK-retransmission to be not-ECT, you can actually end up
getting a CE mark on a retransmission across a ECN-enabled congestion point.

Obviously this is better than loss…

What happens next is, that fbsd "honors" that ECE mark, since it is in
loss-recovery, not congestion-recovery. It adjusts the recovery_point to
the current snd_max (rightmost sent segment), and adjusts ssthresh and
cwnd by multiplicative decrease factor...

Furthermore, it appears that it also resets the traversal of the SACK
scoreboard (incidential a "good" thing, as a few earlier retransmissions
also got dropped, not marked, and are being resent without an RTO).

But in the context of ECN++, what would be the expected response here?

I assume, that with the exception of the fresh traversal of the SACK
scoreboard, the above steps seem sensible.

Any thoughts on this interesting interaction between ECE (during SACK
loss recovery)?

Best regards,
    Richard

Am 10.01.2020 um 01:08 schrieb Scheffenegger, Richard:
> _______________________________________________
> tcpm mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tcpm

---

From: "Scheffenegger, Richard" <[email-masked]>
Date: Sat, 25 Jan 2020 11:41:16 +0100

Hi Group, Marcelo, Bob,

Another update in this context, which IMHO may be discussed as an actual
change of mechanism with ECN++.

I was looking into the very poor interaction of ECN between a Linux
client and a BSD server, with request-response workload. That is, where
each side sends out less than MSS data, before the application waits for
the other side to respond to this.

Neal pointed out this statement in RFC3168:

    ...the TCP sender sets the CWR flag in
    the TCP header of the first new data packet sent after the window
    reduction.  ...
    When the TCP data sender is ready to set the CWR bit after reducing
    the congestion window, it SHOULD set the CWR bit only on the first
    new data packet that it transmits.

However, BSD is sending out the CWR as soon as possible - while Linux
interprets the SHOULD overly strictly (IMHO) and ignores CWR unless it
is received with (new) data.

But binding the CWR flag to a new data segment delays the ECN signaling
loop artificially (for long runs of unidirectional transmitted data),
and it is not clear what the benefit there would be, as the CWR flag is
not retransmitted anyway (thus not bound to a point in the sequence
number space).

I therefore propose a change in the Generalized ECN draft, to lift the
above restriction (while it is "only" a SHOULD, this is one more example
of an overly strict receiving-side implementation), and no longer
artificially delay the CWR signal - to become also more useful for
passive measurements.

Richard

For those interested: The effect of ignoring the CWR on non-new-data
segments by Linux is, that the ECE flag is left latched. Thus BSD
continues window-after-window with cwnd reductions, and due to another
bug where the ECN-induced reduction has no lower bound, eventually cwnd
ends up at 0 Byte and is only increased to 1 Byte by a Timer - until by
pure chance, the CWR is sent together with 1 new byte of data. But in
the preceeding minutes, the session only saw progress by less than 1
byte / RTT...