Re: [tcpm] WGLC for draft-ietf-tcpm-accurate-ecn-23

rs.ietf@gmx.at Thu, 08 June 2023 00:22 UTC

Return-Path: <rs.ietf@gmx.at>
X-Original-To: tcpm@ietfa.amsl.com
Delivered-To: tcpm@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 0A95DC151B0B for <tcpm@ietfa.amsl.com>; Wed, 7 Jun 2023 17:22:40 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -6.695
X-Spam-Level:
X-Spam-Status: No, score=-6.695 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, NICE_REPLY_A=-0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=fail (2048-bit key) reason="fail (message has been altered)" header.d=gmx.at
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id o_t-iNh27ANP for <tcpm@ietfa.amsl.com>; Wed, 7 Jun 2023 17:22:36 -0700 (PDT)
Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 72DB7C1519BE for <tcpm@ietf.org>; Wed, 7 Jun 2023 17:22:35 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.at; s=s31663417; t=1686183703; x=1686788503; i=rs.ietf@gmx.at; bh=1YJKMYobvAYbsiXgJUUn4DEw7SRUEzsBxpKfH3KwuBk=; h=X-UI-Sender-Class:Date:From:Reply-To:Subject:To:Cc:References:In-Reply- To; b=AhW/D+Q8q2XLdIoghqzntdp/W0mdrghabexjuQRkosnGj1CRNsPzADteh74NvOTDTMiKHCY zczl+cx/fIRptmHVw2Wc1arJqX6Zd3niP90nSz/rdQ+In+amRA8LmYMqTZsDnSjxuFtEd+VE6 fu/GU7XnUcjitotm0rMzpGNXc2Asj1E+QKlOP+vAMSUM9PA4CJXna50g/PlxxVlQMwMw4xZ0U T0DTVAGqn5qlzHrJl1u76zvtw/TI8Tia2/7T+AAXpfE/KjHm8Ugh+RcF1BsIZr0Bmx9mpmlEc e/dMnhnEJwrzbElPDxLp2qgJo1NOF6Uks7+09JEFsAIY42RVUHgQ==
X-UI-Sender-Class: 724b4f7f-cbec-4199-ad4e-598c01a50d3a
Received: from [192.168.233.104] ([185.236.167.136]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MCbEf-1qG9xc14s7-009foW; Thu, 08 Jun 2023 02:21:43 +0200
Message-ID: <eebc0dbc-1d32-3b52-2f04-c21eae1dbb39@gmx.at>
Date: Thu, 08 Jun 2023 02:21:37 +0200
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.11.2
From: rs.ietf@gmx.at
Reply-To: rs.ietf@gmx.at
To: Markku Kojo <kojo@cs.helsinki.fi>, Bob Briscoe <ietf@bobbriscoe.net>, Mirja Kuehlewind <ietf@kuehlewind.net>
Cc: tcpm@ietf.org
References: <7EC77745-BA44-4CA5-8B14-9430988B7510@fh-muenster.de> <alpine.DEB.2.21.2303260458560.4394@hp8x-60.cs.helsinki.fi> <2c3e57b6-68c3-6664-3034-410ee4379899@gmx.at> <f39cde47-aefe-4e2e-133a-c19ebd5f8dca@cs.helsinki.fi>
In-Reply-To: <f39cde47-aefe-4e2e-133a-c19ebd5f8dca@cs.helsinki.fi>
Content-Type: text/plain; charset="UTF-8"; format="flowed"
Content-Transfer-Encoding: quoted-printable
X-Provags-ID: V03:K1:UzFTH4NlVtTP4piQsVjpit3YA9OOC96dUPs4NLDO55p9k2TVEbg 3HPhhvoK1rnOW638hbXy8DTZ0MA3p5Loi8U+VLNkTEwCqP/wawaILZIhRzaNraS5hVbp8Tj NveL0RyDlPFmNugEGVx4YolWIkv6zzxUyTtUAG714rTwFRHnmMsT0WHcxfgbm+P9S0LK5cL GNzTi6vCPrOcgqwA9Q6bQ==
UI-OutboundReport: notjunk:1;M01:P0:m3jHxW48O9w=;wYtKqwvTqmbAvWit15d/+y/ekLW I9Rs+GWTWFeOzmbXrb+1BavwA8VYJVwg1vZ3tRgml0lYO0NpR/gEBUOw34XyBEM7qz4HfmPuH wJb+sHR8JyouDrYZuj9fosykq2+/pPQly5KLTKYjcHz8/oZM0/XQh3jJf44FIofCGsrgSoAfx FOQm7baYrSbRpSMnI/wibuVdtv5NsmZj6zIJdkY4nxdRiqEVfwZnyJ79/Kw7uyo6yTM/Q0gcg zy+/We6aA6rIB0zEdNWVCLrYrm3Fo2hOeEOM3a5cxRthbT1aW9OEhLu1MhiFLc5KOQwt7/1gs EjxxM8zkSLfi9AQp4WZE2miiv5eZTuLDYgCR6jBHlVPzP74YzIcNkB/a5ROVFJiybCIz4onfA HnwABYgzcx4hs4amAN7u2vlQuq1RzoeI340nn1X0ZVobU6LrDD22eacz4TS3mp+Cbm8+0TzL2 tCUv5gALJBA/zD+FR+HiSY9/N8OoVBrQ28STT2VpUOe3OUpUio7J8/Ga01uvARIb7K5AkUGr+ IIqD3Nk6x/4+D69b0OFCEg3CHILoh0KSAJYlBfdjKOB3leb3LrDZi1vRWgPcLGKpFPlqQBvyn L/aozaMqMTRvMExnFFffSCqeQ5oQBdf4+g3oasbAo7sLvoySb9//G6M+22nvBzJrP7Rz8zVld tkkutbuPf1D/a34ynLpltlByBQ/vqkpGYc7sbLajtxmyRwRPzI2e0HxaJu+1vLcC0gxTrAtTW 0U5Uz280fBnAU5hD2QNCAUDwh6sG001dOaObVBfnb1EdN5XmmxL7kdSvHNgFBcxzZe8fQsjBX rPb20/RWPKOAwfrQYgYPlxrP/pdoT1ic5WFrwioydTXd6N9AxuA/F/PoftPmXJI+D2lcq49OB HvI9Jz9qOmTWN5XMmmNy+UBUjB23DNlIa58Ste/VXKw6TxkR+deLQBThQzIiRSNjSDDzFYipf mmzifkIlK6irOjHJ2zJTc3AplaQ=
Archived-At: <https://mailarchive.ietf.org/arch/msg/tcpm/iJ1O6VtAARs1QPh1BwgJg8KuymA>
Subject: Re: [tcpm] WGLC for draft-ietf-tcpm-accurate-ecn-23
X-BeenThere: tcpm@ietf.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <tcpm.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tcpm>, <mailto:tcpm-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tcpm/>
List-Post: <mailto:tcpm@ietf.org>
List-Help: <mailto:tcpm-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 08 Jun 2023 00:22:40 -0000

Hi Markku,

see inline with [RS]

> Please find a few scenarios related to the problems with Acks of Acks available at:
>
>   https://www.cs.helsinki.fi/u/kojo/IETF/AccECN2023.pdf

>> On Mon, 27 Mar 2023, rs.ietf@gmx.at wrote:
>
>
> This is all clear. Given that the ECT-marked pure Acks are present only in experiments (ECN++ or maybe some others), why does this stds track document even mention them and the need to send Acks of Acks which are not part of the stds track protocol but only valid with experiments like ECN++  Handling CE-marked pure Acks is clearly experimental and it seems too early and unmature to decide how to best convey feedback on them in a stds track protocol. Experimental protocol would be different but I don't want to open that discussion, wg has made its decision.

[RS] Expirience has shown, that it is much harder to deploy a change in the receiver side, than it is to deploy a unilateral change on the sender side. Therefore, the reaction of the receiver (reflector for ECN marks) needs to be defined more stringent - while also trying to be ready for possible future extensibility of the signaling schemes for yet unforeseen purposes.

[RS] By defining a clear mechanism, which has benign impact even if abused (a stream of CE-marked ACKs will trigger at most 1/3 counter-driven ACKs for the CE marks; a pathological stream of alternating CE and non-CE may, if advice in the draft is not heeded, trigger at most 1/2 change-triggered ACKs for those CE marks; if these ACKs are then ECT-marked (experimental), and the reverse path exhibits similar congestion markings, there may be a certain amount of "ACK-ping-ping" but it's dampened and will quickly die down (a few RTTs at most).

[RS] But to reiterate, the most extrem of such "dampend avalance" effects may only show up in partial conformant AccECN implementations


>> Now, CE-on-ACK:
>>
>> As long as the side receiving the CE-marked ACK has any more data
>> outstanding to be sent - the incremented ACE counter will be
>> piggy-backed on this new data packet. Further, the text in the AccECN
>> draft is also written in a way that this incremented ACE counter does
>> *NOT* need immediate reflection, but rather may increase by at least 3.
>>
>> So, as long as either half-connection has more data to send, there is
>> no risk of any ACK-on-ACK ping-pong, even when all the pure ACKs on one
>> half-connection get CE marked.
>> The only point in the evolution of a TCP session, where ACK-on-ACK could
>> be expected is when
>>
>> Host A no longer has any data (new, or retransmissions) to transmit
>> Host B no longer has any data (new, or retransmissions) to transmit
>> The Path for *both* Half-Connections experience severe congestion
>> (100% CE marking probability on the pure ACKs).
>
> This all clear but sounds like a bit limited view of the possible scenarios. There are several variations of bidirectional data transmission where sending data alternates between the end points, e.g., with a typical request-reply type of application behaviour. Please see my discussion on my  Fig. 2 towards the end.
>
>> Since no new, or retransmitted data would be ready to piggy-back the
>> changed ACE counters, I do not see how this rapidely dampening
>> ACK-on-ACK scenario would have any impact on any of the mechansisms
>> (Fast Retransmit doesn't trigger on the multiple idential ACK fields on
>> data packets, when the receiver doesn't have data to send).
>
> The dampening ping-pong effect is not a big concern but sending unwarranted dupAcks is. Please see Figure 1 of my example scenarios. It's a slight variation of the scenario that Bob pointed out on slide 6 here:
>
>   https://datatracker.ietf.org/meeting/111/materials/slides-111-tcpm-accurate-ecn-01
>
> It also corresponds pretty much to the scenario you described in your follow-up message that I try to cover here as well (sorry for not copying it here). The major difference is in that neither the scenario on the slide 6 nor the one in your follow-up description continued far enough to fully understand all problems the Acks of Acks create.
> > Now, let's look at my Fig 1 and assume no SACK nor Timestamps are in use, so the TCP senders employ NewReno.

[RS] Then neither Host A nor B are supposed to send out ECT-enabled ACKs in the first place. Severe congestion on the Return Path would lead to ACK loss rather than CE-marked ACKs, and no ACKs reflecting the changed CE counter from A to B (as non-ECT pure ACKs don't change the counter)...

> A and B alternate in sending data. A starts with a window size of at least 18 MSS that is enough to trigger 9 cumulative Acks from B to A. The direction from B to A is (heavily) congested so that at least 9 pure Acks get CE marked and trigger at least 3 extra dupAcks from A to B that do not correspond to any data packet from B to A that have left the network as required by RFC 5681 (that is, this is a violation of the crucial requirement in RFC 5681 that is a prerequisite for correct operation of several stds track and other CC algos).
>
> Once the first two dupAcks arrive at B they incorrectly fool Limited Transmit into sending two extra data packets even though no data packets have left the network (the justification for Limited Transmit to send new data packet relies on packet conservation principle and that a dupAck indicates a data packet has left the network as required in RFC 5681).
> When the 3rd dupAck arrives at B, it triggers a false Fast Retransmit and fools B to enter Fast Recovery. The major problem of false Fast Retransmit is not the potential unnecessary reduction of cwnd that hurts the flow from B to A but the subsequent unnecessary retransmissions during Fast Recovery that hurt others by injecting unnecessary load into the network;
> when the original Acks from A to B start flowing in, the TCP sender at B considers them as partial Acks and triggers an unnecessary rexmit for each original cumulative Ack, which flow in at the bottleneck line rate. Moreover, if there are more than 3 Acks of Acks (=dupAcks) each of them fool Fast Recovery into incorrectly increasing cwnd by one MSS and send out an extra new data segment, making B more aggresive than allowed (also due to violating "MUST NOT" in RFC 5681).
>
> These Acks of Acks are problematic also in a slightly alternate scenario, where B first (before A) starts sending data (data pkts 1-100) but maybe to some extent simultaneously with A and B encounters a data packet loss and correctly enters loss recovery (Fast Recovery). In this case, once A starts receiving CE-marked pure Acks (Acks 22, 24,...) after the data packets from B, A will continue injecting extra dupAcks to B that will make it send more new packets during Fast Recovery than allowed, i.e., it causes harm to others by being too aggressive. If the path from B to A is highly congested such that B and other flows competing it have a relatively small cwnd of a few pkts only, then just a few Acks of Acks from A to B may result in B effectively not reacting to congestion at all during the fast recovery. Definitely something to avoid.

[RS] Again, your scenario falls outside the scope of the document; while I agree with the analysis, there are additional assumptions:
- either a incorrect/ignorant implementation, where the Host sends out ECT-marked pure ACKs, when neither SACK nor TSopt are available.
- a middlebox, incorrectly, but selectively tweaking the "TOS" byte to make the pure non-ECT-ACKs suddenly ECT-ACKs (or CE-ACKs; if that would be the case for data segments, that path would be unusable with ECN) close to the respective Host.
(a receiver could also choose to ignore CE-marked pure ACKs from incrementing the CE counter, and subsequent mechanisms to convey this change to the other side, when the session is not SACK or TSopt enabled. I believe this is one aspect that could be added under a "MAY" in the draft. If memory serves, we didn't want to have too many dependencies in the std-track document with tangential mechanisms though.)

[RS] If the congestion is real, very likely a significant fraction of the erranously retransmitted packet will get lost, and multiple rounds of cwnd reduction will furthermore decrease the effective sending rate - after the initial burst which, as you correctly point out, could harm other flows.


> Timestamps:
> ===========
>
> Let's next assume timestamps are in use. If I understand it correctly, the current proposal to avoid interpreting Acks of Acks as dupAcks is:
>
>   "If timestamps are in use, and the incoming pure ACK
>    echoes a timestamp older than the oldest unacknowledged
>    data, it is not a duplicate."
>
> If we look at my Fig 1 and assume that timestamps are in use and the timestamp value for each data packet is the same as its sequence number, that is, the timestamp for data 0 from B to A has TSval=0, etc.
>
> Now, let's first assume pure Acks are not ECT (Acks of Acks denoted as red do not occur) and there is a normal case with a packet loss from B to A (data pkt 1 is dropped). My apologies for not drawing this separately.
> When the data pkts 2, 3, and 4 from B to A arrive at A, they trigger dupAcks that carry Ack=1 and TSecr=0 as per RFC 7323. The echoed timestamp TSecr=0 is older than the timestamp value of the oldest unacknowledged data (data 1 that has TSval=1). These are definitely dupAcks but the proposed rule above would declare them not being dupAcks and hence prevent the normal dupAck-based loss detection from working!?

[RS] I believe this sentence erroneously contains a logical negation;

[RS] With a hole in the received data sequence, TSecr will continue to reflect back the TSval of the oldest observed continous data segment, as you correctly point out;

[RS] However, with all data received in-sequence, followed by pure ACKs with newer timestamps, TSecr will reflect the TSval of the most recently observed pure ACK.

[RS] So,
	If timestamps are in use, and the incoming pure ACK echoes
	a timestamp more recent than the oldest acknowledged data,
	it is not a duplicate. If it is older than the oldest
	unacknowledged data, it is a duplicate.

>> If we then assume pure Acks are ECT-marked in Fig 1, what would be the TSecr in the three first dupAcks? What is the rule to set TSecr in Acks that ack pure Acks and where is it specified? And, how would it prevent the Acks of Acks from being interpreted as dupAcks? I am probably missing something here. Please explain.

[RS] See RFC7323; Section 4.2, rule (2).

[RS] Pure ACKs (with "newer" timestamps; all the blue CE-marked Acks) will update ts.recent when there is no hole in the received sequence space. Thus the first red ACK (with updated CE counter) will have the TSecr 3, followed by TSecr 6 and TSecr 9.

[RS] On a genuine loss, as you correctly stated, TSecr would remain at 0 for these consecutive Dupacks, differentiating these two cases from each other.

[RS] That quoted statement from draft -22 needs to be updated (in the ECN++ draft).
>
> I didn't include a scenario of problems with Eifel detection because I am still not sure what is the TSecr value you "assume" is delivered with Acks of Acks? I also later noticed that the scenario I first had in mind was also possible without Acks of Acks if data packets are reordered similar to Acks of Acks in my scenario. So, probably it is only that Acks of Ack will make the problem to occur more often because small Acks are more likely to get reordered than larger data pkts, particularly if they are CE marked and operate in an L4S setting.
>
>
> Spurious RTO detection
> ======================
>
> If we next look at the Fig 3 where Fig 3a) represents the normal behavior of F-RTO in a typical case which may result in spurious timeout that F-RTO is designed to detect. A and B alternate in sending data. B first sends several data packets (packets 2000 - 2000+n) that get all cumalatively acked. Then A continues by sending data (pkts 101 - 200) but due to (wireless) network conditions the acks get delayed such that A's RTO expires spuriously. A sets cwnd = 1, rexmits data pkt 101 and enters slow start. Because the RTO was spurious, the original ack (ack 103) arrives and increases cwnd by 1. A sends two new data pkts (pkts 200 and 201) as per F-RTO and waits until an ack arrives. The Ack that arrives next is the next original ack (ack 105). Beacuse this Ack also an acked new data, F-RTO declares RTO spurious, exits RTO recovery and continues by sending new data. Everything worked as designed.
>
> In Fig 3b) we have the same setting but now pure Acks are marked ECT.
> There is some congestion from A to B such that at least three of the cumulative Acks from A to B get CE-marked and trigger an extra dupAck from B to A even though no data pkt has left the network. This dupAck precedes the cumulative Acks from B to A and is delayed just like the cumulative Acks. A's RTO expires spuriously and it enters RTO recovery like in Fig 3a) but now the first ack to arrive at A is the extra dupAck.

[RS] With a timestamp older than the RTO retransmitted data packet; A can therefore deduce (when using the TSopt) that this ACK was not in fact ACKing the RTO retransmission...

  Therefore, F-RTO incorrectly declares that the RTO was not spurious and continues RTO recovery by retransmitting unacknowledged data in slow start.

[RS] Only when no TS is used; SACK with DSACK would be another way of detecting this, although delayed by one ACK in your example. With either of these two (required to have ECT-enabled ACKs) options, there is no ambiguity and this case can be resolved, the spurious RTO reverted...

When the original Acks start flowing in at the bottleneck rate, the TCP sender at A increases cwnd in slow start on each original Ack that arrives and unnecessarily retransmits the next segments at higher speed than before the RTO expired. Hence, it causes significant harm to the others by bursting out unnecessarily the whole window of data. These unnecessary rexmits are the major problem both with false Fast
> Retransmits as well as spurious RTOs, not the potentially unnecessary reduction of cwnd that harms the flow itself. That is also why the F-RTO and Eifel algos sepateted the spurious rexmit detection from the response to it; the detections itself is crucial as it avoids the unnecessary rexmits even if the sender decides not to implement the response that may revert the cwnd back to its previous value and thereby helps the flow itself.
>
>> I suspect there may be a misunderstanding here, that there is a need to
>> instantaneously send out a pure ACK right after receiving a CE-marked
>> ACK. Which there is not - normal delayed ACK, and minimum ACE counter
>> change heuristics are there to prevent this particular case.
>
> That was not the case as you can now see.
>
>> While we couldn't come up with any example of the ACK-on-CE-marked-ACK
>> causing misbehavior (note that these AccECN Acks do carry changed
>> information, the new, incremented ACE counter in order to keep both
>> sides in sync there), the text suggesting for the sender not also
>> implementing either SACK or Timestamps was added as a safety measure.
>
> Because there is significant harm that Acks of Acks will cause to all algos that trust on that TCP implementations honor RFC 5681 and send a dupAck only when a data packet has left the network, it is crucial that Acks of Acks MUST NOT be generated when SACK is not in use.

[RS] SACK or TSopt; Agreed.

> This can be forced either by prohibiting ECT-marked pure Acks or by prohibiting Acking of pure Acks. Currently the draft says "SHOULD NOT send ECN-capable pure ACKs". Why "SHOULD NOT", instead of "MUST NOT"? What might be the valid reasons when pure Acks would be allowed to be ECT-marked, resulting in Acks of Acks and violation of RFC 5681 and all problems discussed above and more (which were not discussed, e.g., PipeAck calculation in RFC 7661 and calculating DeliveredData in PRR, etc.)?

[RS] MUST NOT is certainly more appropriate, when neither SACK or TS are in use.

> The same holds even if timestamps are in use unless someone specifies and shows how timestamps can reliably be used to distinquish "fake" dupAcks (Acks of Acks) from real dupAcks without breaking any of the existing mechanisms that rely on timestamps.

[RS] See above; pure ACKs will update ts.recent (TSecr) if received after all data is received in-sequence, thereby allowing the distinction between the true DupAck and CE-counter update cases.

> When SACK is in use and pure Acks are marked ECT, it seems possible to distinguish "fake" dupAcks from real dupAcks. However, one must first specify how pure Acks are acknowledged. This seems to require modification to RFC 2018 (as I already explained in my reply to Bob but seemingly need to clarify as Bob didn't get the problem, pls see my new reply to Bob).
>
>
> Are Acks of Acks useful?
> ========================
>
> Last, let's consider whether acking pure acks is useful, and if so, when. As an important principle when deciding whether to inject packets into the network one should use the robustness principle: ""be conservative in what you send ...". That is, one should carefully consider whether the packets are really needed; are they useful, and if so, when, or are they possibly unnecessary, and if so, when.
>
> We can start with the example given in the AccECN draft (-24), Sec 5.2.2.5.1:
>
>   "In a unidirectional data scenario from host A to B where both hosts
>   support AccECN, if the Data Receiver (B) has chosen to use ECN-
>   capable pure ACKs [I-D.ietf-tcpm-generalized-ecn] and enough of these
>   ACKs become CE-marked, then the 'Increment-Triggered ACKs' rule
>   ensures that the Data Sender (A) gives B sufficient feedback about
>   this congestion. Normally, the Data Sender (A) can piggyback that
>   feedback on its data. But if A stops sending data, the second part of
>   the 'Increment-Triggered ACKs' rule ensures that A emits a pure ACK
>   for at least every third CE-marked incoming ACK over the subsequent
>   round trip."
>
> The above describes unidirectional data scenario, which is quite typical and claims that this ensures sufficient feedback [on CE-marked ACKs]. Sure, it does. But is this necessary?  Obviously, in this case the feedback can be used only for Ack CC because B is not sending anything.
> However, B cannot apply Ack CC until A sends new data, so it is enough that the feedback is delivered with next data segment(s) and sending it separately in Acks of Acks earlier is absolutely unnecessary, just resulting in additional packet load in the network.

[RS] You miss the case, where B may choose to start sending data itself - and can incorporate the updated path information into the congestion state, *prior* of starting to send that new data.

[RS] But in the pure unidirectional case, yes, AckCC would currently be one potential future use case.

>
> The draft continues:
>
>   "... in this case it is mandatory for A to emit ACKs of ACKs because they
>    feed back new congestion state (useful in case B starts sending)."
>
> As explained above, clearly it is not mandatory for A to emit ACKs of ACKs. But, as the draft correctly says, it is useful [only] in case B starts sending, but not always (e.g., if the TCP conncetion in half-open, B never can start sending).
>
> Even if B starts sending, it is not necessarily useful (or practical).
> Let's now look at the Fig 2 of my scenarios, where apps on A and B use very common request-reply type of communication: in this case A sends very short requests (maybe a few bytes only) and B replies with long replies. And this is continuous, interactive communication with quite strict delay requirements such that it is important that A is able to send the next request immediately after the previous reply from B. B has increased its cwnd such that it may send all packets of reply in one RTT
> (B is application limited, but RFC 7661 or RFC 5681 would allow it to continue with the same cwnd from RTT to another as long as there is no congestion from B to A).
>
> A sends the request (data 100) and B replies with n data segments, resulting in approx. n/2 cumulative Acks. The path from A to B is congested (by other traffic) such that many Acks get CE-marked, resulting in up to n/6 Acks of Acks that preceed the next round of data from B to A.
> This is continuous meaning that up to 16+% of packets from B to A are Acks of Acks if the path from A to B remains congested, which is possible if there is a large number of competing flows (even if they react to congestion). The figure is missing the later rounds of possible ping-pong Acks of Acks that may add to the Ack os Ack of the next round(s). Having these later, dampening ping-pong Acks requires, of course, that path from B to A is also congested. For simplicity, let's also assume that Acks of Acks are somehow prevented from being interpreted as dupAcks, that is, they do a not trigger false Fast Retransmits (and are not illustriated in the Fig even though they would cause additional problems also in this scenario if interpreted as dupAcks).
>
> Now, let's consider usefulness of the Acks of Acks carrying congestion feedback. When A receives the feedback it may apply either Ack CC to reduce cumulative ack rate or decrease cwnd to reduce the data rate from A to B. If A uses the feedback for Ack CC purposes only (e.g., it learns via AccECN option that ack pkts only are contributing to the congestion), sending separate Acks of Acks is quite unnecessary as the feedback can be timely delivered with the data packets from B to A. If A decides to react by reducing its data rate, the early feedback with Acks of Acks might be useful. However, it might also result in undesired effects, maybe because A cannot distinguish whether it is its Ack or data that is contributing to the congestion when AckECN option is not in use. If A decides to reduce its data rate and cwnd = 1 MSS, the only way to do it is to delay the next data pkt which would result in undesired delay in delivering the next delay-sensitive request even though the
> data rate from A to B was not contributing to the congestion (much) at all. So, if Ack congestion is automatically reflected back to A (the data receiver) but data vs. Ack congestion is not separated, A as a data sender may have a hard dilemma to solve. Furthermore, if A is sending such small reguests (<= 1 MSS) and is practically application limited, its cwnd is likely to be larger than 1 MSS. If it decides to reduce cwnd due to Acks of Acks reporting (Ack) congestion, its is likely to have a null effect. That is, it seems that Ack congestion is best reacted by Ack CC reducing (cummulative) Ack rate only.
>
> One additional example where reflecting Ack congestion blindly in Ack of Acks is quite unnecessary is when there is a hole in the sequence space.
> Assume A is sending data to B and a pkt gets dropped. This results in B doubling its ack rate for one RTT once it starts injecting dupAcks due to arriving out-of-order data. Now, if path from B to A is already congested or becomes congested due to increased ack rate, some (or many) of the dupAcks get CE-marked. That results in congestion feedback in Acks of Acks from A to B but B should not react to this added congestion feedback, because a pkt was lost and A will react by decreasing its data rate that will decrease future ack rate. In addition, the dupAcks were delivered only temporarily at the double rate and B will automatically stop injecting dupAcks and thereby first halves its Ack rate in one RTT and then returns back to sending cumulative acks with a reduced rate from what it was sending before the pkt drop was detected. Hence, also in this case Acks of Acks reporting congestion feedback are completely unnecessary.
>
> Considering what I said above, in case one needs Acks of Acks, wouldn't it be much more effective to dampen ping-pongs, if one specifies that Ack of an Ack reporting CE on a pure Ack can only be sent if the pure Ack advanced SND.UNA, i.e., only count and report marked bytes/pkts in cumulative Acks. I don't find any reason to report CE-marked dupAcks (like in the previous exampel above) because the pkt load they represent is temporary extra load that has dissapeared by the time the feedback arrives at the other end. So, they are not subject to be CC reacted as the system has already reacted and removed that part of load. Or maybe I am missing something?


[RS] This is a very valuable discussion to have. However, it appears to me, that this is not something in scope for the signalling schema to solve, but rather higher level mechanisms such as AckCC, Congestion Response etc; one insight to take away here is, that a host having negotiated AccECN and also doing ECN++ and SACK/TS, will need to be able to selectively toggle ECT-capable ACKs for extreme situations where the additional load of AccECN-stipulated ACKs-for-CE-ACKs itself becomes a significant source of congestion. However, I want to repeat that this is not something we have to address in the signaling protocol itself, and can be worked out e.g. in the ECN++ or AckCC experiments.

>
> So, the only case in which I can identify Acks of Acks potentially being useful is a slightly modified scenario of my Fig 2 where A sends a larger request, i.e., a number of data pkts, instead of just one.
> Even in this case the Acks of Acks tend to arrive too late and can be used only for controlling data rate in the next round when the congestion information might already be stale. Hence, maybe the only scenario where Acks of Acks may be useful is when the interaction between A and B is not delay sensitive and A waits for a while after the data segments of the reply from B have arrived before it starts sending its next request? Otherwise, Acks of Acks seem to serve Ack congestion control only which is an open issues and definitely not mature for stds track at this time.
>
> To summarise:
> =============
>
> It seems that Acks of Acks are mostly unnecessary and do not help much in terms of providing more timely feedback. Therefore, it would be useful to carefully consider whether it is reasonable to nail down in a stds track document a behavior (blindly Acking Acks for CE feedback) that in most cases seems injecting additional packets to the network unnecessarily.


[RS] And an implementer is not forced to send out ECT-capable ACKs blindly; However, in order to have a consistent and future proof capability in the receivers, a consistent and timely reflection of the CE marks (and marked bytes) seems good to have; to reiterate - there are examples where signalling protocols designed for one purpose have shown unexpectedly useful (or less so), for dramatically different purposes later on (e.g. Eifel with TSopt, as one of many). It is easy to mitigate all the above objections by unilateral action by the sender (not send ECT-enabled pure ACKs). However, enabling this feedback if it turns out to be valuable (e.g. retaining CC state while the half-connection is idle in a more appropriate state) would be much harder, if the capability does not exist in a dependable fashion the the receivers (CE reflectors).


>
> What specifically strikes me is that currently the draft mandates this behavior with a MUST in Sec 3.2.2.5.1, Increment-Triggered ACKs:
>
>   "An AccECN Data Receiver MUST emit an ACK if 'n' CE marks have arrived
>   since the previous ACK."
>
> Why cannot this be SHOULD?

[RS] See above; consistent "reflector" / receiver behavior is much more valuable for future proofing a signalling protocol, than making aspects of this optional - forcing a future sender to deduce the probable behavior of a particular receiver...

>
> This later part of the rule seems to serve ack congestion control only as discussed above:
>
>   "If there is no newly delivered data to acknowledge, 'n' SHOULD be 3 and
>   MUST be no less than 3. In either case, 'n' MUST be no greater than 7"
>
> If specified like this and one wants to enable ECT-marked pure Acks, it mandates always conveying feedback on Ack congestion in Acks of Acks.
> Also, when the data sender decides to do Ack CC just by reducing its data rate, which requires no feedback to data receiver. Instead, any feedback is likely to be mistreated and ack rate gets double controlled.
>
> If the first MUST in Increment-Triggered ACKs rule is made SHOULD, then one could omit the later part of the rule. This would require reformulating the rule, I believe.
>
> Why? An implementor may want to benefit from ECT-marked Acks but avoid sending unnecessary Acks of Acks.
> That is, a valid reason for omitting SHOULD would be to separate Ack CC from data CC such that CE-marked data pkts would be reported as per this draft but the data sender could benefit from CE-marked Ack info and decide to apply Ack CC and report it separately or not report it at all to the other end. The latter would allow the data sender to control ack flow by controlling its data sending rate, reguiring no communication with the other end. In the former case, the data sender could use some other means to report Ack congestion to or control Ack congestion with the data receiver (e.g., Ack Rate option).
>
> I am not claiming that this would be somehow better approach but given that Ack CC is still open research or at least experimental, I think we should not nail down and restrict how to do it in this stds track document to be.
>
>> But if we have not considered a particular corner case, please let us
>> discuss that!
>
> AFAIK, none of the cases I described is a corner case but likely to occur often in very typical application use cases.
>