RFC 9768
More Accurate Explicit Congestion Notification (AccECN) Feedback in TCP
RFC 9768 ๐ฆโจ Part 1 of 17
Title block tea โ
- Who wrote it: B. Briscoe (Independent), M. Kรผhlewind (Ericsson), and R. Scheffenegger (NetApp) ๐ซถ
- Stream: IETF ๐ธ
- Category: Standards Track, so it's a real Internet standard ๐
- Date: April 2026 ๐ฆ
- Updates: RFC 3168 ๐ฅ This one doesn't replace it, it levels it up.
- ISSN: 2070-1721
Abstract ๐
Okay so, Explicit Congestion Notification (ECN) is how network nodes can mark IP packets instead of dropping them to say "hey, things are getting a bit crowded." The receiver with an ECN-capable transport protocol passes that info back to the sender. The problem is that ECN was originally designed for TCP so that only one feedback signal per Round-Trip Time (RTT) could get through. Not ideal, bestie ๐
Newer mechanisms like Congestion Exposure (ConEx), Data Center TCP (DCTCP), and Low Latency, Low Loss, and Scalable Throughput (L4S) really need more accurate feedback whenever more than one marking shows up in a single RTT. This document updates the original ECN spec from RFC 3168 with a scheme that gives more than one feedback signal per RTT in the TCP header. It's called More Accurate ECN (AccECN) ๐
TCP header space is scarce, so AccECN takes a reserved header bit that used to belong to the ECN-nonce. It also overloads the two existing ECN flags in the TCP header. That extra room gets used to feed back the IP-ECN field seen during TCP connection establishment too. Supplementary feedback can optionally go in two new TCP Option alternatives, which are never used on the TCP SYN. The document also covers how middleboxes should treat this updated TCP wire protocol ๐
Status of This Memo โจ
This is an Internet Standards Track document. ๐
It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 7841 ๐ง
Info about the current status of this document, any errata, and how to give feedback on it lives at https://www.rfc-editor.org/info/rfc9768 ๐ธ
Copyright Notice ๐
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. ๐
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as in effect on the date it was published. Please read these carefully, because they spell out your rights and restrictions for this document. Code Components pulled out of this document must include the Revised BSD License text described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Revised BSD License describes ๐ซถ
This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) who control the copyright in some of that material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. Unless you get an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process. The exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐
Table of Contents ๐
1. Introduction
1.1. Document Roadmap
1.2. Goals
1.3. Terminology
1.4. Recap of Existing ECN Feedback in IP/TCP
2. AccECN Protocol Overview and Rationale
2.1. Capability Negotiation
2.2. Feedback Mechanism
2.3. Delayed ACKs and Resilience Against ACK Loss
2.4. Feedback Metrics
2.5. Generic (Mechanistic) Reflector
3. AccECN Protocol Specification
3.1. Negotiating to Use AccECN
3.1.1. Negotiation During the TCP Three-Way Handshake
3.1.2. Backward Compatibility
3.1.3. Forward Compatibility
3.1.4. Multiple SYNs or SYN/ACKs
3.1.4.1. Retransmitted SYNs
3.1.4.2. Retransmitted SYN/ACKs
3.1.5. Implications of AccECN Mode
3.2. AccECN Feedback
3.2.1. Initialization of Feedback Counters
3.2.2. The ACE Field
3.2.2.1. ACE Field on the ACK of the SYN/ACK
3.2.2.2. Encoding and Decoding Feedback in the ACE Field
3.2.2.3. Testing for Mangling of the IP/ECN Field
3.2.2.4. Testing for Zeroing of the ACE Field
3.2.2.5. Safety Against Ambiguity of the ACE Field
3.2.3. The AccECN Option
3.2.3.1. Encoding and Decoding Feedback in the AccECN Option
Fields
3.2.3.2. Path Traversal of the AccECN Option
3.2.3.3. Usage of the AccECN TCP Option
3.3. AccECN Compliance Requirements for TCP Proxies, Offload
Engines, and Other Middleboxes
3.3.1. Requirements for TCP Proxies
3.3.2. Requirements for Transparent Middleboxes and TCP
Normalizers
3.3.3. Requirements for TCP ACK Filtering
3.3.4. Requirements for TCP Segmentation Offload and Large
Receive Offload
4. Updates to RFC 3168
5. Interaction with TCP Variants
5.1. Compatibility with SYN Cookies
5.2. Compatibility with TCP Experiments and Common TCP Options
5.3. Compatibility with Feedback Integrity Mechanisms
6. Summary: Protocol Properties
7. IANA Considerations
8. Security and Privacy Considerations
9. References
9.1. Normative References
9.2. Informative References
Appendix A. Example Algorithms
A.1. Example Algorithm to Encode/Decode the AccECN Option
A.2. Example Algorithm for Safety Against Long Sequences of ACK
Loss
A.2.1. Safety Algorithm Without the AccECN Option
A.2.2. Safety Algorithm With the AccECN Option
A.3. Example Algorithm to Estimate Marked Bytes from Marked
Packets
A.4. Example Algorithm to Count Not-ECT Bytes
Appendix B. Rationale for Usage of TCP Header Flags
B.1. Three TCP Header Flags in the SYN-SYN/ACK Handshake
B.2. Four Codepoints in the SYN/ACK
B.3. Space for Future Evolution
Acknowledgements
Authors' Addresses
1. Introduction ๐ฆ
Okay, so, Explicit Congestion Notification (ECN) [RFC3168] is how network nodes can mark IP packets instead of dropping them to signal incipient congestion to the endpoints. Receivers with an ECN-capable transport protocol feed that info back to the sender. In RFC 3168, ECN was specified for TCP so that only one feedback signal could be sent per Round-Trip Time (RTT). That's honestly enough for congestion control schemes like Reno [RFC5681] and CUBIC [RFC9438], since they cut their congestion window by a fixed factor whenever congestion happens within an RTT, no matter how many congestion markings came in ๐
Then came the newer mechanisms: Congestion Exposure (ConEx [RFC7713]), DCTCP [RFC8257], and L4S [RFC9330]. They need to know when more than one marking is received in one RTT, and the feedback scheme in [RFC3168] simply can't tell them that. ๐ญ
This document specifies an update to the ECN feedback scheme of RFC 3168 that gives more accurate information. It can be used by these and potentially other future TCP extensions, while still supporting the existing TCP congestion controllers that use just one feedback signal per round. Quick aside on the vocab: "congestion control" is the IETF's term for data rate management. It's the algorithm a sender uses to optimize its sending rate, so it transmits data as fast as the network can carry it, but no faster โจ A fuller explanation of why this spec exists is in the associated requirements document [RFC7560] ๐ธ
This document specifies a Standards Track scheme for ECN feedback in the TCP header that gives more than one feedback signal per RTT. It's called the "more Accurate ECN feedback" scheme, or AccECN for short ๐ This document updates RFC 3168 with respect to negotiation and use of the feedback scheme for TCP. Everything else in RFC 3168, apart from the TCP feedback scheme and its negotiation, stays the same. Most importantly, the definition of ECN at the IP layer is untouched. Section 4 details the parts of RFC 3168 that this document updates ๐ง
This document uses the term "Classic ECN feedback" when it needs to tell apart the TCP/ECN feedback scheme defined in [RFC3168] from the AccECN TCP feedback scheme. AccECN is meant to be a complete replacement for Classic TCP/ECN feedback, not a fork in the design of TCP ๐ AccECN feedback works alongside TCP's loss feedback, and it can coexist with hosts that still use Classic TCP/ECN feedback. Its applicability includes the public Internet, private IP networks like data centres, and even non-IP networks over which TCP is used. It works whether or not nodes on the path support ECN, and no matter which flavour of ECN they run ๐
AccECN overloads the two existing ECN flags in the TCP header. It also takes the currently reserved flag (previously called NS) in the TCP header and uses it as one 3-bit counter field for feeding back the number of packets marked as congestion experienced (CE) ๐ Because these three bits have new definitions, both ends have to support the new wire protocol before it can be used. So during the TCP handshake, the two ends use these three bits to negotiate the most advanced feedback protocol they can both support, and they do it in a way that stays backward compatible with [RFC3168] ๐ซถ
AccECN is solely a change to the TCP wire protocol. It covers the negotiation and signaling of more Accurate ECN feedback from a TCP Data Receiver to a Data Sender. It's completely independent of how TCP responds to congestion feedback, which is out of scope, even though responding well is the whole motivation for Accurate ECN feedback ๐ Like Classic ECN feedback, AccECN can be used by standard Reno or CUBIC congestion control [RFC5681] [RFC9438] to respond to the existence of at least one congestion notification within a round trip. Unlike Reno or CUBIC, AccECN can also respond to the extent of congestion notification over a round trip, the way DCTCP does in controlled environments [RFC8257] ๐
For congestion response, this specification refers to the original ECN specification adopted in 2001 [RFC3168], as updated by the more relaxed rules introduced in 2018 to allow ECN experiments [RFC8311]. Those rules cover a TCP-based Low Latency Low Loss Scalable (L4S) congestion control [RFC9330], or Alternative Backoff with ECN (ABE) [RFC8511] โญ
Section 5.2 explains how AccECN is compatible with commonly used TCP Options, with a number of current experimental modifications to TCP, and with SYN cookies ๐ธ
1.1. Document Roadmap
The following introductory section outlines the goals of AccECN (Section 1.2). Then, terminology is defined (Section 1.3) and a recap of existing prerequisite technology is given (Section 1.4).
Section 2 gives an informative overview of the AccECN protocol. Then Section 3 gives the normative protocol specification, and Section 3.3 collects requirements for proxies, offload engines, and other middleboxes. Section 4 clarifies which aspects of RFC 3168 are updated by AccECN. Section 5 assesses the interaction of AccECN with commonly used variants of TCP, whether they are standardized or not. Then Section 6 summarizes the features and properties of AccECN.
Section 7 summarizes the protocol fields and numbers that IANA assigned, and Section 8 points to the aspects of the protocol that will be of interest to the security community.
Appendix A gives pseudocode examples for the various algorithms that AccECN uses, and Appendix B explains why AccECN uses flags in the main TCP header and quantifies the space left for future use.
1.2. Goals
[RFC7560] enumerates requirements that a candidate feedback scheme needs to satisfy, under the headings: resilience, timeliness, integrity, accuracy (including ordering and lack of bias), complexity, overhead, and compatibility (both backward and forward). It recognizes that a perfect scheme that fully satisfies all the requirements is unlikely and tradeoffs between requirements are likely. Section 6 assesses the properties of AccECN against these requirements and discusses the tradeoffs.
The requirements document recognizes that a protocol as ubiquitous as TCP needs to be able to serve as-yet-unspecified requirements. Therefore, an AccECN receiver acts as a generic (mechanistic) reflector of congestion information with the aim that new sender behaviours can be deployed unilaterally in the future (see Section 2.5).
1.3. Terminology
AccECN: The more Accurate ECN feedback scheme.
Classic ECN: The ECN protocol specified in [RFC3168].
Classic ECN feedback: The feedback aspect of the ECN protocol specified in [RFC3168], including generation, encoding, transmission and decoding of feedback, but not the Data Sender's subsequent response to that feedback.
ACK: A TCP acknowledgement, with or without a data payload (ACK=1).
Pure ACK: A TCP acknowledgement without a data payload.
Acceptable packet / segment: A packet or segment that passes the acceptability tests in [RFC9293] and [RFC5961], or that has passed other tests with equivalent protection.
TCP Client: The TCP stack that originates a connection (the initiator).
TCP Server: The TCP stack that responds to a connection request (the listener).
Three-way handshake: The procedure used to establish a TCP connection as described in the TCP protocol specification [RFC9293].
Data Receiver: The endpoint of a TCP half-connection that receives data and sends AccECN feedback.
Data Sender: The endpoint of a TCP half-connection that sends data and receives AccECN feedback.
In a mild abuse of terminology, this document sometimes refers to 'TCP packets' instead of 'TCP segments'.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
1.4. Recap of Existing ECN Feedback in IP/TCP
Explicit Congestion Notification (ECN) [RFC3168] can be split into two parts conceptually. In the forward direction, alongside the data stream, it uses a 2-bit field in the IP header. This is referred to as IP ECN later on. This signal carried in the IP (Layer 3) header is exposed to network devices, which can modify it when they start to experience congestion (see Table 1). The second part is the feedback mechanism, by which the data receiver notifies the current congestion state to the original data sender of the intermediate path. That returned signal is carried in a transport-protocol-specific manner, and is not to be modified by intermediate network devices. While ECN is in active use for protocols such as QUIC [RFC9000], SCTP [RFC9260], RTP [RFC6679], and Remote Direct Memory Access over Converged Ethernet [RoCEv2], this document only concerns itself with the specific implementation for the TCP protocol.
Once ECN has been negotiated for a transport layer connection, the Data Sender for either half-connection can set two possible codepoints (ECT(0) or ECT(1)) in the IP header of a data packet to indicate an ECN-capable transport (ECT). If the ECN codepoint is 0b00, the packet is considered to have been sent by a Not ECN-capable Transport (Not-ECT). When a network node experiences congestion, it will occasionally either drop or mark a packet, with the choice depending on the packet's ECN codepoint. If the codepoint is Not- ECT, only drop is appropriate. If the codepoint is ECT(0) or ECT(1), the node can mark the packet by setting the ECN codepoint to 0b11, which is termed 'Congestion Experienced' (CE), or loosely a 'congestion mark'. Table 1 summarises these codepoints.
+==================+================+===========================+
| IP-ECN Codepoint | Codepoint Name | Description |
+==================+================+===========================+
| 0b00 | Not-ECT | Not ECN-Capable Transport |
+------------------+----------------+---------------------------+
| 0b01 | ECT(1) | ECN-Capable Transport (1) |
+------------------+----------------+---------------------------+
| 0b10 | ECT(0) | ECN-Capable Transport (0) |
+------------------+----------------+---------------------------+
| 0b11 | CE | Congestion Experienced |
+------------------+----------------+---------------------------+
Table 1: The ECN Field in the IP Header
In the TCP header, the first two bits in byte 14 (the TCP header flags at bit offsets 8 and 9 labelled Congestion Window Reduced (CWR) and Explicit Congestion notification Echo (ECE) in Figure 1) are defined as flags for the use of Classic ECN [RFC3168]. A TCP Client indicates that it supports Classic ECN feedback by setting (CWR,ECE) = (1,1) in the SYN, and an ECN-enabled TCP Server confirms Classic ECN support by setting (CWR,ECE) = (0,1) in the SYN/ACK. On reception of a CE-marked packet at the IP layer, the Data Receiver for that half-connection starts to set the Echo Congestion Experienced (ECE) flag continuously in the TCP header of ACKs, which gives the signal resilience to loss or reordering of ACKs. The Data Sender for the same half-connection confirms that it has received at least one ECE signal by responding with the CWR flag, which allows the Data Receiver to stop repeating the ECN-Echo flag. This always leads to a full RTT of ACKs with ECE set. Thus Classic ECN cannot feed back any additional CE markings arriving within this RTT.
The last bit in byte 13 of the TCP header (the TCP header flag at bit offset 7 in Figure 1) was defined as the Nonce Sum (NS) for the ECN- nonce [RFC3540]. In the absence of widespread deployment, RFC 3540 was reclassified as Historic [RFC8311] and the respective flag was marked as "Reserved", which made this TCP flag available for use by AccECN instead.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | N | C | E | U | A | P | R | S | F |
| Header Length | Reserved | S | W | C | R | C | S | S | Y | I |
| | | | R | E | G | K | H | T | N | N |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Figure 1: TCP Header Flags as Defined Before the Nonce Sum Flag
Reverted to Reserved
- AccECN Protocol Overview and Rationale
This section provides an informative overview of the AccECN protocol that is normatively specified in Section 3.
Like the general TCP approach, the Data Receiver of each TCP half- connection sends AccECN feedback to the Data Sender on TCP acknowledgements, reusing data packets of the other half-connection whenever possible.
The AccECN protocol has had to be designed in two parts:
- an essential feedback part that reuses the TCP-ECN header bits for the Data Receiver to feed back the number of packets arriving with CE in the IP-ECN field. This provides more accuracy than Classic ECN feedback, but limited resilience against ACK loss.
- a supplementary feedback part using one of two new alternative AccECN TCP Options that provide additional feedback on the number of payload bytes that arrive marked with each of the three ECN codepoints in the IP-ECN field (not just CE marks). See the BCP on Byte and Packet Congestion Notification [RFC7141] for the rationale determining that conveying congested payload bytes should be preferred over just providing feedback about congested packets. This also provides greater resilience against ACK loss than the essential feedback, but it is currently more likely to suffer from middlebox interference.
The two part design was necessary, given limitations on the space available for TCP Options and given the possibility that certain incorrectly designed middleboxes might prevent TCP from using any new options.
The essential feedback part overloads the previous definition of the three flags in the TCP header that had been assigned for use by Classic ECN. This design choice deliberately allows AccECN peers to replace the Classic ECN feedback protocol, rather than leaving Classic ECN feedback intact and adding more accurate feedback separately because:
- this efficiently reuses scarce TCP header space, given TCP Option space is approaching saturation;
- a single upgrade path for the TCP protocol is preferable to a fork in the design that modifies the TCP header to convey all ECN feedback;
- otherwise, Classic and Accurate ECN feedback could give conflicting feedback about the same segment, which could open up new security concerns and make implementations unnecessarily complex;
- middleboxes are more likely to faithfully forward the TCP-ECN flags than newly defined areas of the TCP header.
AccECN is designed to work even if the supplementary feedback part is removed or zeroed out, as long as the essential feedback part gets through.
2.1. Capability Negotiation ๐ค
okay bestie, so AccECN changes the wire protocol of the main TCP header ๐ณ, which means it can only be used if both endpoints have been upgraded to understand it ๐ . no cap, it's giving "you can't just wing it." The TCP Client signals support for AccECN on the initial SYN of a connection, and the TCP Server signals whether it supports AccECN on the SYN/ACK ๐. The TCP flags on the SYN that the TCP Client uses to signal AccECN support were carefully picked so that a TCP Server will read them as a request to support the most recent variant of ECN feedback that it supports ๐ง. Then the TCP Client falls back to that same variant of ECN feedback โจ. the way that's so considerate ngl ๐ซถ
An AccECN TCP Client doesn't send an AccECN Option on the SYN because SYN option space is limited ๐. The TCP Server sends an AccECN Option on the SYN/ACK, and the TCP Client sends one on the first ACK to test whether the network path forwards these options correctly ๐.
2.2. Feedback Mechanism ๐ฌ
okay so a Data Receiver keeps four counters ๐ข, all set to start at the beginning of the half-connection. Three of them count the arriving payload bytes marked CE, ECT(1), and ECT(0) in the IP-ECN field ๐. These byte counters only look at the TCP payload length, so the TCP header and TCP Options don't get counted ๐
โโ๏ธ. The fourth counter counts the number of packets that show up marked with a CE codepoint, and that includes control packets without payload if they're CE-marked ๐ฉ.
The Data Sender keeps four matching counters for the half-connection too ๐ฏโโ๏ธ. The AccECN protocol is designed so they end up matching the Data Receiver's counters, just after a little delay โณ.
Each ACK carries the three least significant bits (LSBs) of the packet-based CE counter, using the ECN bits in the TCP header. Those bits are now renamed the Accurate ECN (ACE) field (see Figure 3) ๐ฆ. The 24 LSBs of some or all of the byte counters can optionally be carried in an AccECN Option ๐. To use limited option space efficiently, there are two alternative forms of the AccECN Option, with the fields in the opposite order to each other ๐งฉ.
2.3. Delayed ACKs and Resilience Against ACK Loss ๐ง
with both the ACE and the AccECN Option mechanisms, the Data Receiver keeps repeating the current LSBs of each of its counters ๐. Nobody needs to acknowledge those repeated counters, which is why the CWR mechanism of [RFC3168] isn't used anymore ๐. Even if some ACKs get lost, the Data Sender ought to be able to work out how much to increment its own counters, even if the protocol field has wrapped ๐ง .
The 3-bit ACE field can wrap pretty often ๐. So even if it looks like it went up by one (say), it might have actually cycled all the way around and then gone up by one ๐ตโ๐ซ. The Data Receiver is not allowed to delay sending an ACK long enough for the ACE field to cycle ๐ซ. But ACKs arriving at the Data Sender can still cycle, because a whole run of ACKs carrying the in-between values might all get lost or delayed on the way ๐ฆ.
The fields in an AccECN Option are bigger, but they go up in bigger steps because they count bytes, not packets ๐. Still, their size was picked so a whole cycle of the field would never happen between ACKs unless there had been an absurdly long run of ACK losses ๐. So as long as an AccECN Option is available, it can be treated as a dependable feedback channel ๐.
If an AccECN Option isn't available, e.g., a middlebox is stripping it, the AccECN protocol will only feed back information on CE markings (using the ACE field) ๐ซ . Not ideal, but it's still enough, because it's envisaged that neither ECT(0) nor ECT(1) will ever indicate more severe congestion than CE, even though future uses for ECT(0) or ECT(1) are still unclear [RFC8311] ๐ฎ. Since the 3-bit ACE field is so small, when it's the only field available, the Data Sender has to interpret it by assuming the most likely wrap, but with a degree of conservatism ๐ง.
Certain specified events trigger the Data Receiver to include an AccECN Option on an ACK โก. The rules are designed so that the order in which different markings arrive at the receiver gets communicated to the sender (as long as options are reaching the sender and as long as there's no ACK loss) ๐บ๏ธ. Implementations are encouraged to send an AccECN Option more frequently, but that's left up to the implementer ๐ซถ.
2.4. Feedback Metrics ๐
the CE packet counter in the ACE field and the CE byte counter in AccECN Options both give feedback on received CE marks ๐ท๏ธ. The CE packet counter includes control packets that don't have payload data, while the CE byte counter only includes marked payload bytes ๐ฏ. If both are present, the byte counter in an AccECN Option gives the more accurate info needed for modern congestion control and policing schemes, such as L4S, DCTCP, or ConEx ๐๏ธ. If AccECN Options get stripped, a simple algorithm to estimate the number of marked bytes from the ACE field is given in Appendix A.3 ๐งฎ.
The AccECN design was generalized so it ought to be able to support possible future uses of the experimental ECT(1) codepoint other than the L4S experiment [RFC9330] ๐. Those could be things like a lower severity signal or a more instant congestion signal than CE โก.
Feedback in bytes protects against the receiver, or a middlebox, using attacks similar to 'ACK-Division' to artificially inflate the congestion window ๐ค. That's why [RFC5681] now recommends that TCP counts acknowledged bytes, not packets ๐ .
2.5. Generic (Mechanistic) Reflector ๐ช
the ACE field gives feedback about CE markings in the IP-ECN field of both data and control packets ๐จ. According to [RFC3168], the Data Sender is meant to set the IP-ECN field of control packets to Not-ECT. But in certain private networks (e.g., data centres), control packets are set to be ECN-capable, because they're exactly the packets that performance depends on most ๐ข.
so AccECN is designed to be a generic reflector of whatever ECN markings it sees, whether or not they follow a current standard ๐ชโจ. As standards evolve, Data Senders can upgrade on their own without any need for receivers to upgrade too ๐.
It's also handy to rely on that generic reflection behaviour when senders need to test for unexpected interference with markings (for instance Sections 3.2.2.3, 3.2.2.4, and 3.2.3.2 of the present document and paragraph 2 of Section 20.2 of [RFC3168]) ๐ต๏ธโโ๏ธ.
The initial SYN and SYN/ACK are the most critical control packets, so AccECN feeds back their IP-ECN fields ๐. Even though [RFC3168] prohibits ECN-capable SYNs and SYN/ACKs, feeding back ECN marking on the SYN and SYN/ACK supports future scenarios where SYNs might be ECN-enabled (without prejudging whether they ought to be) ๐ญ. For instance, [RFC8311] updates this part of RFC 3168 to allow experimentation with ECN-capable TCP control packets ๐งช.
Even if the TCP Client (or Server) has set the SYN (or SYN/ACK) to Not-ECT in compliance with RFC 3168, feedback on the state of the IP-ECN field when it arrives at the receiver could still be useful ๐. That's because middleboxes have been known to overwrite the IP-ECN field as if it's still part of the old Type of Service (ToS) field [Mandalari18] ๐ฑ. For example, if a TCP Client set the SYN to Not-ECT but gets feedback that the IP-ECN field on the SYN arrived with a different codepoint, it can detect that middlebox interference ๐ต๏ธ. Before AccECN, neither end knew what IP-ECN field the other one sent ๐. So if a TCP Server received ECT or CE on a SYN, it couldn't know whether that was invalid, because only the TCP Client knew whether it originally marked the SYN as Not-ECT (or ECT) ๐คทโโ๏ธ. Therefore, prior to AccECN, the Server's only safe move in that situation was to disable ECN for the connection ๐. Now the AccECN protocol lets the Server and Client feed back the ECN field received on the SYN and SYN/ACK to their peer, which then has all the info to decide whether the connection has to fall back from supporting ECN (or not) ๐ง ๐.
3. AccECN Protocol Specification ๐ฆ
3.1. Negotiating to Use AccECN ๐
3.1.1. Negotiation During the TCP Three-Way Handshake ๐ค
okay so given the ECN-nonce [RFC3540] has been reclassified as Historic [RFC8311], the TCP flag that used to be called NS (Nonce Sum) is now renamed the AE (Accurate ECN) flag (the TCP header flag at bit offset 7 in Figure 2) ๐ท๏ธ. See the IANA Considerations in Section 7 ๐.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | A | C | E | U | A | P | R | S | F |
| Header Length | Reserved | E | W | C | R | C | S | S | Y | I |
| | | | R | E | G | K | H | T | N | N |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Figure 2: The New Definition of the TCP Header Flags During the TCP Three-Way Handshake
during the TCP three-way handshake at the start of a connection, to request more Accurate ECN feedback, the TCP Client (host A) MUST set the TCP flags (AE,CWR,ECE) = (1,1,1) in the initial SYN segment ๐โโ๏ธโจ.
If a TCP Server (host B) that is AccECN-enabled receives a SYN with the above three flags set, it MUST set both its half-connections into AccECN mode ๐ธ. Then it MUST set the AE, CWR, and ECE TCP flags on the SYN/ACK to the combination in the top block of Table 2 that feeds back the IP-ECN field that arrived on the SYN ๐. This applies whether or not the Server itself supports setting the IP-ECN field on a SYN or SYN/ACK (see Section 2.5 for rationale) ๐
.
When the TCP Server returns any of the four combinations in the top block of Table 2, it confirms that it supports AccECN ๐ฅณ. The TCP Server MUST NOT set one of these four combinations of flags on the SYN/ACK unless the preceding SYN requested support for AccECN as above ๐ซ.
Once a TCP Client (A) has sent the above SYN to declare that it supports AccECN, and once it has received the above SYN/ACK segment confirming that the TCP Server supports AccECN, the TCP Client MUST set both its half-connections into AccECN mode ๐. The TCP Client MUST NOT enter AccECN mode (or any feedback mode) before it has received the first SYN/ACK โธ๏ธ.
Once in AccECN mode, a TCP Client or Server has the rights and obligations defined in Section 3.1.5 concerning use of ECN ๐.
The procedures for retransmission of SYNs or SYN/ACKs are given in Section 3.1.4 ๐.
It is RECOMMENDED that the AccECN protocol be implemented alongside Selective Acknowledgement (SACK) [RFC2018] ๐งก. If SACK is implemented with AccECN, Duplicate Selective Acknowledgement (D-SACK) [RFC2883] MUST also be implemented ๐ซถ.
3.1.2. Backward Compatibility ๐
Okay bestie, the TCP flags used to signal AccECN support on the SYN were picked SO carefully so that everything can naturally fall back to earlier stages of ECN evolution ๐ฆ Table 2 lays out every negotiation possibility that involves at least one AccECN-capable host. The first two columns use these abbreviations:
- AccECN: Supports more Accurate ECN feedback (the present specification).
- Nonce: Supports ECN-nonce feedback [RFC3540].
- ECN: Supports 'Classic' ECN feedback [RFC3168].
- No ECN: Not ECN-capable. Implicit congestion notification using packet drop.
+========+========+============+============+======================+
| Host A | Host B | SYN | SYN/ACK | Feedback Mode |
| | | A->B | B->A | of Host A |
| | | AE CWR ECE | AE CWR ECE | |
+========+========+============+============+======================+
| AccECN | AccECN | 1 1 1 | 0 1 0 | AccECN (Not-ECT SYN) |
| AccECN | AccECN | 1 1 1 | 0 1 1 | AccECN (ECT1 on SYN) |
| AccECN | AccECN | 1 1 1 | 1 0 0 | AccECN (ECT0 on SYN) |
| AccECN | AccECN | 1 1 1 | 1 1 0 | AccECN (CE on SYN) |
+--------+--------+------------+------------+----------------------+
+--------+--------+------------+------------+----------------------+
| AccECN | Nonce | 1 1 1 | 1 0 1 | (Reserved) |
| AccECN | ECN | 1 1 1 | 0 0 1 | Classic ECN |
| AccECN | No ECN | 1 1 1 | 0 0 0 | Not ECN |
+--------+--------+------------+------------+----------------------+
+--------+--------+------------+------------+----------------------+
| Nonce | AccECN | 0 1 1 | 0 0 1 | Classic ECN |
| ECN | AccECN | 0 1 1 | 0 0 1 | Classic ECN |
| No ECN | AccECN | 0 0 0 | 0 0 0 | Not ECN |
+--------+--------+------------+------------+----------------------+
+--------+--------+------------+------------+----------------------+
| AccECN | Broken | 1 1 1 | 1 1 1 | Not ECN |
+--------+--------+------------+------------+----------------------+
Table 2: ECN Capability Negotiation Between Client (A) and
Server (B)
Table 2 is split into blocks, with each block separated by an empty row. Here's how the blocks work ๐
- The top block shows the case already described in Section 3.1 where both endpoints support AccECN and how the TCP Server (B) indicates congestion feedback.
- The second block shows the cases where the TCP Client (A) supports AccECN but the TCP Server (B) supports some earlier variant of TCP feedback, as indicated in its SYN/ACK. Therefore, as soon as an AccECN-capable TCP Client (A) receives the SYN/ACK shown, it MUST set both its half-connections into the feedback mode shown in the rightmost column. If the TCP Client has set itself into Classic ECN feedback mode, it MUST comply with [RFC3168].
An AccECN implementation has no need to recognize or support the Server response labelled 'Nonce' or ECN-nonce feedback more generally [RFC3540], as RFC 3540 has been reclassified as Historic [RFC8311]. AccECN is compatible with alternative ECN feedback integrity approaches to the nonce (see Section 5.3). The SYN/ACK labelled 'Nonce' with (AE,CWR,ECE) = (1,0,1) is reserved for future use. A TCP Client (A) that receives such a SYN/ACK follows the procedure for forward compatibility given in Section 3.1.3.
- The third block shows the cases where the TCP Server (B) supports AccECN but the TCP Client (A) supports some earlier variant of TCP feedback, as indicated in its SYN.
When an AccECN-enabled TCP Server (B) receives a SYN with (AE,CWR,ECE) = (0,1,1), it MUST do one of the following:
- Set both its half-connections into the Classic ECN feedback mode and return a SYN/ACK with (AE,CWR,ECE) = (0,0,1) as shown. Then it MUST comply with [RFC3168].
- Set both its half-connections into Not ECN mode and return a SYN/ACK with (AE,CWR,ECE) = (0,0,0), then continue with ECN disabled. This latter case is unlikely to be desirable, but it is allowed as a possibility, e.g., for minimal TCP implementations.
When an AccECN-enabled TCP Server (B) receives a SYN with (AE,CWR,ECE) = (0,0,0), it MUST set both its half-connections into the Not ECN feedback mode, return a SYN/ACK with (AE,CWR,ECE) = (0,0,0) as shown, and continue with ECN disabled.
- The fourth block displays a combination labelled 'Broken'. Some older TCP Server implementations incorrectly set the TCP-ECN flags in the SYN/ACK by reflecting those in the SYN. Such broken TCP Servers (B) cannot support ECN; so as soon as an AccECN-capable TCP Client (A) receives such a broken SYN/ACK, it MUST fall back to Not ECN mode for both its half-connections and continue with ECN disabled.
The following additional rules don't fit the structure of the table, but they complement it:
- Simultaneous Open: An originating AccECN Host (A), having sent a SYN with (AE,CWR,ECE) = (1,1,1), might receive another SYN from host B. Host A MUST then enter the same feedback mode as it would have entered had it been a responding host and received the same SYN. Then host A MUST send the same SYN/ACK as it would have sent had it been a responding host.
- In-window SYN during TIME-WAIT: Many TCP implementations create a new TCP connection if they receive an in-window SYN packet during TIME-WAIT state. When a TCP host enters TIME-WAIT or CLOSED state, it ought to ignore any previous state about the negotiation of AccECN for that connection and renegotiate the feedback mode according to Table 2.
3.1.3. Forward Compatibility ๐ง
If a TCP Server that implements AccECN receives a SYN with the three TCP header flags (AE,CWR,ECE) set to any combination other than (0,0,0), (0,1,1), or (1,1,1) and it does not have logic specific to such a combination, the Server MUST negotiate the use of AccECN as if the three flags had been set to (1,1,1). However, an AccECN Client implementation MUST NOT send a SYN with any combination other than the three listed.
If a TCP Client sent a SYN requesting AccECN feedback with (AE,CWR,ECE) = (1,1,1) and then receives a SYN/ACK with the currently reserved combination (AE,CWR,ECE) = (1,0,1) but it does not have logic specific to such a combination, the Client MUST enable AccECN mode as if the SYN/ACK confirmed that the Server supported AccECN and as if it fed back that the IP-ECN field on the SYN had arrived unchanged. However, an AccECN Server implementation MUST NOT send a SYN/ACK with this combination (AE,CWR,ECE) = (1,0,1).
For the avoidance of doubt, the behaviour described in the present specification applies whether or not the three remaining reserved TCP header flags are zero.
All of these requirements ensure that future uses of all the Reserved combinations of all the TCP header bits on a SYN or SYN/ACK (see Table 2) can rely on consistent behaviour from the installed base of AccECN implementations. See Appendix B.3 for related discussion.
3.1.4. Multiple SYNs or SYN/ACKs ๐ธ
3.1.4.1. Retransmitted SYNs
If the sender of an AccECN SYN (the TCP Client) times out before receiving the SYN/ACK, it SHOULD attempt to negotiate the use of AccECN at least one more time by continuing to set all three TCP-ECN flags (AE,CWR,ECE) = (1,1,1) on the first retransmitted SYN (using the usual retransmission timeouts). If this first retransmission also fails to be acknowledged, in deployment scenarios where AccECN path traversal might be problematic, the TCP Client SHOULD send subsequent retransmissions of the SYN with the three TCP-ECN flags cleared (AE,CWR,ECE) = (0,0,0). Such a retransmitted SYN MUST use the same initial sequence number (ISN) as the original SYN.
Retrying once before fall-back adds delay in the case where a middlebox drops an AccECN (or ECN) SYN deliberately. However, recent measurements [Mandalari18] imply that a drop is less likely to be due to middlebox interference than other intermittent causes of loss, e.g., congestion, wireless transmission loss, etc.
Implementers MAY use other fall-back strategies if they are found to be more effective, e.g., attempting to negotiate AccECN on the SYN only once or more than twice (most appropriate during high levels of congestion).
Further it might make sense to also remove any other new or experimental fields or options on the SYN in case a middlebox might be blocking them, although the required behaviour will depend on the specification of the other option(s) and any attempt to coordinate fall-back between different modules of the stack. For instance, if taking part in an [RFC8311] experiment that allows ECT on a SYN, it would be advisable to have a fall-back strategy that tries use of AccECN without setting ECT on the SYN.
Whichever fall-back strategy is used, the TCP initiator SHOULD cache failed connection attempts. If it does, it SHOULD NOT give up attempting to negotiate AccECN on the SYN of subsequent connection attempts until it is clear that the blockage is persistently and specifically due to AccECN. The cache needs to be arranged to expire so that the initiator will infrequently attempt to check whether the problem has been resolved.
All fall-back strategies will need to follow all the normative rules in Section 3.1.5, which concern behaviour when SYNs or SYN/ACKs negotiating different types of feedback have been sent within the same connection, including the possibility that they arrive out of order. As examples, the following non-normative bullets call out those rules from Section 3.1.5 that apply to the above fall-back strategies:
- Once the TCP Client has sent SYNs with (AE,CWR,ECE) = (1,1,1) and with (AE,CWR,ECE) = (0,0,0), it might eventually receive a SYN/ACK from the Server in response to one, the other, or both, and possibly reordered.
- Such a TCP Client enters the feedback mode appropriate to the first SYN/ACK it receives according to Table 2, and it does not switch to a different mode, whatever other SYN/ACKs it might receive or send.
- If a TCP Client has entered AccECN mode but then subsequently sends a SYN or receives a SYN/ACK with (AE,CWR,ECE) = (0,0,0), it is still allowed to set ECT on packets for the rest of the connection. Note that this rule is different from that of a Server in an equivalent position (Section 3.1.5 explains).
- Having entered AccECN mode, in general a TCP Client commits to respond to any incoming congestion feedback, whether or not it sets ECT on outgoing packets (for rationale and some exceptions see Section 3.2.2.3, Section 3.2.2.4).
- Having entered AccECN mode, a TCP Client commits to using AccECN to feed back the IP-ECN field in incoming packets for the rest of the connection, as specified in Section 3.2, even if it is not itself setting ECT on outgoing packets.
3.1.4.2. Retransmitted SYN/ACKs โจ
Okay bestie, so a TCP Server can send more than one SYN/ACK, and each one can be saying a different feedback mode ๐ฆ. It might fall back to a SYN/ACK with (AE,CWR,ECE) = (0,0,0) after its earlier AccECN SYN/ACKs have timed out (Section 3.2.3.2.2) ๐, or it might just be acknowledging different retransmissions of the SYN (Section 3.1.4.1) ๐ธ.
Every fall-back strategy has to follow all the normative rules in Section 3.1.5 ๐ซถ. Those rules cover what happens when SYNs or SYN/ACKs that negotiate different types of feedback get sent in the same connection, even if they show up out of order ๐ญ. The bullets below are non-normative, but they call out the Section 3.1.5 rules that apply to these fall-back strategies:
- An AccECN-capable TCP Server enters the feedback mode that matches the first SYN it receives, using Table 2 ๐ . After that it doesn't switch modes, no matter what other SYNs show up or what SYN/ACKs it sends. Main character energy ๐.
- If a TCP Server in AccECN mode receives a SYN with
(AE,CWR,ECE) = (0,0,0), it preferably acknowledges that SYN first with an AccECN SYN/ACK ๐. It can also retry with a SYN/ACK with(AE,CWR,ECE) = (0,0,0)๐. - If a TCP Server in AccECN mode sends several AccECN SYN/ACKs, it uses the TCP-ECN flags in each one to feed back the IP-ECN field on the latest SYN that arrived ๐ฅ.
- If a TCP Server enters AccECN mode and then later sends a SYN/ACK, or receives a SYN, with
(AE,CWR,ECE) = (0,0,0), it's not allowed to set ECT on any packet for the rest of the connection ๐. - Once a TCP Server is in AccECN mode, it generally commits to responding to any incoming congestion feedback, whether or not it sets ECT on its outgoing packets ๐. (For the reasoning and a few exceptions, see Sections 3.2.2.3 and 3.2.2.4.)
- Once a TCP Server is in AccECN mode, it commits to using AccECN to feed back the IP-ECN field in incoming packets for the rest of the connection, as Section 3.2 specifies. That's true even if it isn't setting ECT on its own outgoing packets ๐ง.
3.1.5. Implications of AccECN Mode โจ
Section 3.1.1 describes the only ways a host can enter AccECN mode, whether it's the Client or the Server ๐.
An implementation that supports AccECN gets some rights and obligations about using ECN, and these update the ones in Section 6.1.1 of [RFC3168] ๐. This section uses the following definitions:
- 'During the handshake': the connection states before synchronization.
- 'Valid SYN': a SYN with the same port numbers and the same ISN as the SYN that first caused the Server to open the connection. An 'Acceptable' packet is defined in Section 1.3 ๐ฆ.
Now for handling SYNs or SYN/ACKs of multiple types (like fall-back) ๐ธ:
- Any implementation that supports AccECN:
- It MUST NOT switch into a different feedback mode from the one it first entered according to Table 2 ๐ซ, no matter whether it later receives valid SYNs or Acceptable SYN/ACKs of different types ๐ .
- It SHOULD ignore the TCP-ECN flags in SYNs or SYN/ACKs that arrive after the implementation reaches the ESTABLISHED state, in line with the general TCP approach [RFC9293] โจ.
Reason: reaching ESTABLISHED state means at least one SYN and one SYN/ACK have successfully been delivered ๐ซถ. All the handshake fall-back rules are designed to work from those packets that made it across the path, no matter which other handshake packets get lost or delayed ๐.
- It MUST NOT send a 'Classic' ECN-setup SYN [RFC3168] with
(AE,CWR,ECE) = (0,1,1)and a SYN with(AE,CWR,ECE) = (1,1,1)requesting AccECN feedback within the same connection ๐. - It MUST NOT send a 'Classic' ECN-setup SYN/ACK [RFC3168] with
(AE,CWR,ECE) = (0,0,1)and a SYN/ACK agreeing to use AccECN feedback within the same connection ๐. - It MUST reset the connection with a RST packet if it receives a 'Classic' ECN-setup SYN with
(AE,CWR,ECE) = (0,1,1)and a SYN requesting AccECN feedback during the same handshake ๐ฅ. - It MUST reset the connection with a RST packet if it receives a 'Classic' ECN-setup SYN/ACK with
(AE,CWR,ECE) = (0,0,1)and a SYN/ACK agreeing to use AccECN feedback during the same handshake ๐.
The last four rules are necessary because, if one peer negotiated the feedback mode in two different types of handshake, the other peer couldn't know for certain which handshake packets were eventually received, or in what order ๐ญ. Without these rules, the two peers could end up using different ECN feedback modes without knowing it ๐.
- A host in AccECN mode that is feeding back the IP-ECN field on a SYN or SYN/ACK:
- It MUST feed back the IP-ECN field on the latest valid SYN or Acceptable SYN/ACK to arrive ๐.
- A TCP Server already in AccECN mode:
- It SHOULD acknowledge a valid SYN that arrives with
(AE,CWR,ECE) = (0,0,0)by emitting an AccECN SYN/ACK. It uses the right combination of TCP-ECN flags to feed back the IP-ECN field of this latest SYN ๐ง. - It MAY acknowledge a valid SYN that arrives with
(AE,CWR,ECE) = (0,0,0)by sending a SYN/ACK with(AE,CWR,ECE) = (0,0,0)๐.
- It SHOULD acknowledge a valid SYN that arrives with
Rationale: when a SYN arrives with (AE,CWR,ECE) = (0,0,0) at a TCP Server that's already in AccECN mode, it probably means the TCP Client never got the previous AccECN SYN/ACK the Server sent ๐ฅบ. So the first bullet recommends trying at least one more AccECN SYN/ACK ๐. The second bullet recognizes that the Server might eventually need to fall back to a non-ECN SYN/ACK ๐. Either way, the TCP Server stays in AccECN feedback mode, because of the earlier rule against switching modes โจ.
- An AccECN-capable TCP Server already in Not ECN mode:
- It SHOULD respond to any later valid SYN with a SYN/ACK with
(AE,CWR,ECE) = (0,0,0), even if the SYN is offering to negotiate Classic ECN or AccECN feedback mode ๐ซง.
- It SHOULD respond to any later valid SYN with a SYN/ACK with
Rationale: there's no point in the Server offering any type of ECN feedback when the Client won't be using ECN anyway ๐. There's no interoperability reason to make this rule mandatory, though ๐ฆ.
If for any reason a host isn't willing to provide ECN feedback on a particular TCP connection, it SHOULD clear the AE, CWR, and ECE flags in all the SYN and/or SYN/ACK packets it sends ๐ธ.
Sending ECT:
- Any implementation that supports AccECN:
- It MUST NOT set ECT if it is in Not ECN feedback mode ๐ โโ๏ธ.
- A Data Sender in AccECN mode:
- It SHOULD set an ECT codepoint in the IP header of packets to tell the network that the transport is capable of, and willing to take part in, ECN for this packet ๐.
- It MAY not set ECT on any packet, for instance if it has reason to believe such a packet would get blocked ๐.
- A TCP Server in AccECN mode:
- It MUST NOT set ECT on any packet for the rest of the connection if it has received or sent at least one valid SYN or Acceptable SYN/ACK with
(AE,CWR,ECE) = (0,0,0)during the handshake ๐ซ.
- It MUST NOT set ECT on any packet for the rest of the connection if it has received or sent at least one valid SYN or Acceptable SYN/ACK with
This rule only applies to a Server, because when a Server enters AccECN mode, it doesn't know for sure whether the Client will end up in AccECN mode too ๐คทโโ๏ธ. But when a Client enters AccECN mode, it can be certain the Server is already in AccECN feedback mode ๐ .
Congestion response:
- A host in AccECN mode:
- It is obliged to respond appropriately to AccECN feedback that shows there were ECN marks on packets it had sent earlier. "Appropriately" is defined in Section 6.1 of [RFC3168] and updated by Sections 2.1 and 4.1 of [RFC8311] ๐.
- It is still obliged to respond appropriately to congestion feedback, even when it's only sending non-ECN-capable packets. (For the reasoning, some examples and some exceptions, see Sections 3.2.2.3 and 3.2.2.4.) ๐ง
- It is still obliged to respond appropriately to congestion feedback, even if it has sent or received a SYN or SYN/ACK packet with
(AE,CWR,ECE) = (0,0,0)during the handshake ๐ฅ. - It MUST NOT set CWR to indicate that it has received and responded to indications of congestion ๐.
For the avoidance of doubt, this is unlike an RFC 3168 data sender ๐. It also doesn't stop the Data Sender from setting the bits of the ACE counter field, which includes an overloaded use of that same bit ๐.
Receiving ECT:
- A host in AccECN mode:
- It MUST feed back the information in the IP-ECN field of incoming packets using Accurate ECN feedback, as specified in Section 3.2 ๐ซถ.
For the avoidance of doubt, this requirement still stands even if the AccECN host has also sent or received a SYN or SYN/ACK with (AE,CWR,ECE) = (0,0,0) ๐. Reason: a SYN or SYN/ACK like that implies some form of packet mangling might be present ๐ฌ. Even if the remote peer isn't setting ECT, the bits could still be set erroneously by packet mangling at the IP layer (see Section 3.2.2.3) ๐. In those cases the Data Sender is best placed to decide whether the ECN markings are valid, but it can only do that if the Data Receiver mechanistically feeds back any ECN markings ๐ง . This approach won't lead to TCP Options being generated unnecessarily if the recommended simple scheme in Section 3.2.3.3 is used, because no byte counters will change if no packets are set to ECT ๐.
- It MUST NOT use reception of packets with ECT set in the IP-ECN field as an implicit signal that the peer is ECN-capable ๐ซ.
Reason: ECT at the IP layer doesn't explicitly confirm the peer has the correct ECN feedback logic, because the packets could have been mangled at the IP layer ๐.
3.2. AccECN Feedback โจ
okay bestie, feedback time ๐ Each Data Receiver of each half-connection keeps four counters: r.cep, r.ceb, r.e0b, and r.e1b. ๐ง
- The Data Receiver MUST increment the CE packet counter (
r.cep) for every Acceptable packet it receives with the CE code point in the IP-ECN field. That includes CE-marked control packets and retransmissions, but excludes CE on SYN packets (SYN=1; ACK=0). ๐ - A Data Receiver that supports sending AccECN TCP Options MUST increment the
r.ceb,r.e0b, orr.e1bbyte counters by the number of TCP payload octets in Acceptable packets marked with the CE, ECT(0), and ECT(1) codepoint in their IP-ECN field. That includes payload octets on control packets and retransmissions, but not payload octets on SYN packets (SYN=1; ACK=0). ๐
Each Data Sender of each half-connection maintains four counters, s.cep, s.ceb, s.e0b, and s.e1b, which are meant to track the matching counters at the Data Receiver. ๐ฆ
A Data Receiver feeds back the CE packet counter using the Accurate ECN (ACE) field, as explained in Section 3.2.2. It can also optionally feed back all the byte counters using the AccECN TCP Option, as specified in Section 3.2.3. ๐ธ
Whenever a Data Receiver feeds back the value of any counter, it MUST report the most recent value. That's true whether it's in a pure ACK, or an ACK piggybacked on a packet used by the other half-connection, and whether that packet carries new payload data or a retransmission. So the feedback on a retransmitted packet is unlikely to match the feedback on the original packet. ๐ฅ
3.2.1. Initialization of Feedback Counters
When a host first enters AccECN mode in its role as a Data Receiver, it initializes its counters to r.cep = 5, r.e0b = r.e1b = 1, and r.ceb = 0. โจ
Non-zero initial values support a stateless handshake (see Section 5.1). They also make sure the values are distinct from cases where the fields have been incorrectly zeroed (e.g., by middleboxes -- see Section 3.2.3.2.4). ๐
When a host enters AccECN mode in its role as a Data Sender, it initializes its counters to s.cep = 5, s.e0b = s.e1b = 1, and s.ceb = 0. ๐
3.2.2. The ACE Field
After AccECN has been negotiated on the SYN and SYN/ACK, both hosts overload the three TCP flags (AE, CWR, and ECE) in the main TCP header as one 3-bit field. Then that field gets a new name, ACE, as shown in Figure 3. ๐
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | U | A | P | R | S | F |
| Header Length | Reserved | ACE | R | C | S | S | Y | I |
| | | | G | K | H | T | N | N |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Figure 3: Definition of the ACE Field Within Bytes 13 and 14 of the TCP Header (When AccECN Has Been Negotiated and SYN=0).
The original definition of these three flags in the TCP header, including the addition of ECN-nonce support, is shown for comparison in Figure 1. This specification does not rename these three TCP flags to ACE unconditionally. It just overloads them with another name and definition once an AccECN connection has been established. ๐
With one exception (Section 3.2.2.1), a host with both of its half-connections in AccECN mode MUST interpret the AE, CWR, and ECE flags as the 3-bit ACE counter on a segment with the SYN flag cleared (SYN=0). On such a packet, a Data Receiver MUST encode the 3 least significant bits of its r.cep counter into the ACE field that it feeds back to the Data Sender. The least significant bit is at bit offset 9 in Figure 3. A host MUST NOT interpret the three flags as a 3-bit ACE field on any segment with SYN=1 (whether ACK is 0 or 1), or if AccECN negotiation is incomplete or has not succeeded. ๐
Both parts of each of these conditions are equally important. For instance, even if AccECN negotiation has been successful, the ACE field is not defined on any segments with SYN=1. That covers things like a retransmission of an unacknowledged SYN/ACK, or when both ends send SYN/ACKs after AccECN support has been successfully negotiated during a simultaneous open. ๐ซถ
3.2.2.1. ACE Field on the ACK of the SYN/ACK
If the TCP Client (A) in AccECN mode uses a pure ACK with no SACK blocks to acknowledge the SYN/ACK, it MUST use the binary encoding in Table 3 when writing the ACE field. That's the same encoding used on the SYN/ACK in Table 2. This feeds back which of the 4 possible values of the IP-ECN field was on the SYN/ACK. This shall be called the "handshake encoding" of the ACE field, and it is the only exception to the rule that the ACE field carries the 3 least significant bits of the r.cep counter on packets with SYN=0. ๐ฆ
Normally, a TCP Client acknowledges a SYN/ACK with an ACK that satisfies the above conditions anyway (SYN=0, no data, no SACK blocks). If an AccECN TCP Client intends to acknowledge the SYN/ACK with a packet that does not satisfy these conditions (e.g., it has data to include on the ACK), it SHOULD first send a pure ACK that does satisfy these conditions (see Section 5.2). That way it can feed back which of the four values of the IP-ECN field arrived on the SYN/ACK. A valid exception to this "SHOULD" would be where the implementation will only be used in an environment where mangling of the ECN field is unlikely. ๐ค
The TCP Client MUST also use the handshake encoding for the pure ACK of any retransmitted SYN/ACK that confirms the TCP Server supports AccECN. If the TCP Server does not receive the final ACK of the handshake before its retransmission timer expires, the procedure it follows is given in Section 3.1.4.2. โฐ
+==================+================+=====================+
| IP-ECN Codepoint | ACE on Pure | r.cep of TCP Client |
| on SYN/ACK | ACK of SYN/ACK | in AccECN Mode |
+==================+================+=====================+
| Not-ECT | 0b010 | 5 |
+------------------+----------------+---------------------+
| ECT(1) | 0b011 | 5 |
+------------------+----------------+---------------------+
| ECT(0) | 0b100 | 5 |
+------------------+----------------+---------------------+
| CE | 0b110 | 6 |
+------------------+----------------+---------------------+
Table 3: The Encoding of the ACE Field in the ACK of the SYN-ACK to Reflect the SYN-ACK's IP-ECN Field
When an AccECN Server in SYN-RCVD state receives a pure ACK with SYN=0 and no SACK blocks, it MUST infer the meaning of each possible value of the ACE field from Table 4, instead of treating the ACE field as a counter. As a result, an AccECN Server MUST set s.cep to the respective value, also shown in Table 4. ๐ง
Since this encoding of the ACE field on the ACK of a SYN/ACK is an exception, an AccECN Server using large receive offload (LRO) might prefer to disable LRO until it transitions out of SYN-RCVD state (when it first receives an ACK that covers the SYN/ACK). ๐ธ
+============+==========================+=====================+
| ACE on ACK | IP-ECN Codepoint on SYN/ | s.cep of TCP Server |
| of SYN/ACK | ACK Inferred by Server | in AccECN Mode |
+============+==========================+=====================+
| 0b000 | {Notes 1, 3} | Disable s.cep |
+------------+--------------------------+---------------------+
| 0b001 | {Notes 2, 3} | 5 |
+------------+--------------------------+---------------------+
| 0b010 | Not-ECT | 5 |
+------------+--------------------------+---------------------+
| 0b011 | ECT(1) | 5 |
+------------+--------------------------+---------------------+
| 0b100 | ECT(0) | 5 |
+------------+--------------------------+---------------------+
| 0b101 | Currently Unused {Note | 5 |
| | 2} | |
+------------+--------------------------+---------------------+
| 0b110 | CE | 6 |
+------------+--------------------------+---------------------+
| 0b111 | Currently Unused {Note | 5 |
| | 2} | |
+------------+--------------------------+---------------------+
Table 4: Meaning of the ACE Field on the ACK of the SYN/ACK
Note 1: If the Server is in AccECN mode and in SYN-RCVD state, and if it receives a value of zero on a pure ACK with SYN=0 and no SACK blocks, then for the rest of the connection the Server MUST NOT set ECT on outgoing packets and MUST NOT respond to AccECN feedback. Nonetheless, as a Data Receiver, it MUST NOT disable AccECN feedback. ๐
Any of the circumstances below could cause a value of zero. But whatever the cause, the actions above would be the appropriate response:
- The TCP Client has somehow entered No ECN feedback mode (most likely if the Server received a SYN or sent a SYN/ACK with (AE,CWR,ECE) = (0,0,0) after entering AccECN mode, but possible even if it didn't).
- The TCP Client genuinely might be in AccECN mode, but its count of received CE marks might have caused the ACE field to wrap to zero. This is highly unlikely, but not impossible, because the Server might have already sent multiple packets while still in SYN-RCVD state, e.g., using TFO (see Section 5.2), and some might have been CE-marked. Then ACE on the first ACK seen by the Server might be zero, due to previous ACKs experiencing an unfortunate pattern of loss or delay.
- There is some form of non-compliance at the TCP Client or on the path.
Note 2: If the Server is in AccECN mode, these values are Currently Unused, but the AccECN Server's behaviour is still defined for forward compatibility. Then the designer of a future protocol can know for certain what AccECN Servers will do with these codepoints. ๐ฎ
Note 3: In the case where a Server that implements AccECN is also using a stateless handshake (termed a SYN cookie), it will not remember whether it entered AccECN mode. The values 0b000 or 0b001 will remind it that it did not enter AccECN mode, because AccECN does not use them (see Section 5.1 for details). If a Server that uses a stateless handshake and implements AccECN receives either of these two values in the ACK, its action is implementation-dependent and outside the scope of this document. It will certainly not take the action in the third column because, after it receives either of these values, it is not in AccECN mode. That is, it will not disable ECN (at least not just because ACE is 0b000), and it will not set s.cep. ๐งโโ๏ธ
3.2.2.2. Encoding and Decoding Feedback in the ACE Field โจ
okay so whenever the Data Receiver sends an ACK with SYN=0 (with or without data) ๐, the Data Receiver MUST encode the least significant 3 bits of its r.cep counter into the ACE field. The one exception is when the handshake encoding from Section 3.2.2.1 applies. Check Appendix A.2 for examples.
Now the Data Sender's side. Whenever it receives an ACK with SYN=0 (with or without data), it first checks whether that ACK has already been superseded (defined in Appendix A.1) by another ACK. If so, it ignores the ECN feedback. If the ACK hasn't been superseded, and the special handshake encoding in Section 3.2.2.1 doesn't apply, the Data Sender decodes the ACE field like this (see Appendix A.2 for examples) ๐
- It takes the least significant 3 bits of its local
s.cepcounter and subtracts them from the incomingACEcounter. This gives the minimum positive increment it could apply tos.cep, assuming theACEfield only wrapped once at most. - It then follows the safety procedures in Section 3.2.2.5.2 to calculate or estimate how many packets the ACK could have acknowledged under the prevailing conditions. This tells it whether the
ACEfield might have wrapped more than once.
The encode/decode procedures during the three-way handshake are exceptions to the general rules above, so I'm spelling them out step by step below for clarity ๐ง
- If a TCP Server in AccECN mode receives a CE mark in the IP-ECN field of a SYN (
SYN=1,ACK=0), it MUST NOT incrementr.cep. It stays at its initial value of 5.
Reason: it would be redundant for the Server to include CE-marked SYNs in its r.cep counter, because it already reliably delivers feedback of any CE marking using the encoding in the top block of Table 2 in the SYN/ACK. This also means that when the Server starts using the ACE field, it hasn't unnecessarily used up more than one initial value. Those initial values can be used to negotiate variants of the AccECN protocol (see Appendix B.3). ๐ซถ
- If a TCP Client in AccECN mode receives CE feedback in the TCP flags of a SYN/ACK, it MUST NOT increment
s.cep. It stays at its initial value of 5, so that it stays in step withr.cepon the Server. The TCP Client still triggers the congestion control actions needed to respond to the CE feedback, though ๐ฆ - If a TCP Client in AccECN mode receives a CE mark in the IP-ECN field of a SYN/ACK, it MUST increment
r.cep, but no more than once, no matter how many CE-marked SYN/ACKs it receives. So it goes from 5 to 6, and no further. ๐
Reason: incrementing r.cep means the Client will eventually deliver any CE marking to the Server reliably once it starts using the ACE field. The Client also feeds back any CE marking on the ACK of the SYN/ACK using the encoding in Table 3. That ACK isn't delivered reliably, though, so it counts as a timely notification that is redundant but unreliable. The Client doesn't increment r.cep more than once, because the Server can only increment s.cep once (see the next bullet). This also limits the unnecessarily consumed initial values of the ACE field to two. ๐
- If a TCP Server in AccECN mode and in SYN-RCVD state receives CE feedback in the TCP flags of a pure ACK with no SACK blocks, it MUST increment
s.cep(from 5 to 6). The TCP Server then triggers the congestion control actions needed to respond to the CE feedback. ๐ฅ
Reasoning: the TCP Server can only increment s.cep once, because the first ACK it receives moves it out of SYN-RCVD state. The Server's congestion response would be no different even if it could receive feedback of more than one CE-marked SYN/ACK. ๐ง
Once the TCP Server transitions to ESTABLISHED state, it might later receive other pure ACK(s) with the handshake encoding in the ACE field. A Server MAY implement a test for such a case, but it is not required. So once it's in the ESTABLISHED state, it's enough for the Server to treat the ACE field as the normal ACE counter on all packets with SYN=0. ๐ธ
Reasoning: such ACKs will be pretty unusual. For example, a SYN/ACK (or an ACK of the SYN/ACK) might get delayed for longer than the Server's retransmission timeout, or the network might duplicate a packet. And any error in the feedback on such ACKs will only be temporary ๐ฆ
3.2.2.3. Testing for Mangling of the IP/ECN Field ๐ต๏ธโโ๏ธ
- TCP Client side:
The value of the TCP-ECN flags on the SYN/ACK tells you the value of the IP-ECN field when the SYN arrived at the Server. The TCP Client can compare that with how it originally set the IP-ECN field on the SYN. If this comparison implies an invalid transition (defined below) of the IP-ECN field, then for the rest of the half-connection the Client is advised to send non-ECN-capable packets. It still ought to respond to any feedback of CE markings (explained below). However, the TCP Client MUST remain in the AccECN feedback mode, and it MUST continue to feed back any ECN markings on arriving packets (in its role as Data Receiver). ๐
- TCP Server side:
The value of the ACE field on the last ACK of the three-way handshake tells you the value of the IP-ECN field when the SYN/ACK arrived at the TCP Client. The Server can compare that with how it originally set the IP-ECN field on the SYN/ACK. If this comparison implies an invalid transition of the IP-ECN field, then for the rest of the half-connection the Server is advised to send non-ECN-capable packets. It still ought to respond to any feedback of CE markings (explained below). However, the Server MUST remain in the AccECN feedback mode, and it MUST continue to feed back any ECN markings on arriving packets (in its role as Data Receiver). ๐ง
If a Data Sender in AccECN mode starts sending non-ECN-capable packets because it has detected mangling, it's still advised to respond to CE feedback. Here's why: any CE marking that reaches the Data Receiver could be the result of something early in the path mangling a non-ECN-capable IP-ECN field into an ECN-capable codepoint. Later on the path, a network bottleneck might then apply CE markings to signal genuine congestion. This argument holds whether the handshake packet the TCP Client or Server originally sent was non-ECN-capable or ECN-capable. Either way, an unsafe transition could mean non-ECN-capable packets later in the connection get mangled too. โ ๏ธ
Once a Data Sender has entered AccECN mode, it's advised to check whether it's receiving continuous feedback of CE. Exactly how to do this is beyond the scope of this specification. The sender might check whether the feedback for every packet it sends in the first three or four rounds indicates CE marking. If continuous CE marking is detected, then for the rest of the half-connection the Data Sender ought to send non-ECN-capable packets, and it's advised not to respond to any feedback of CE markings. The Data Sender might occasionally test whether it can go back to sending ECN-capable packets. ๐
The advice above, about switching to non-ECN-capable packets while still responding to CE markings unless they become continuous, is not stated normatively (in capitals). The reason is that the best strategy might depend on experience of the most likely types of mangling, which can only be known at deployment time. For instance, later in a connection, sender implementations might need to detect the onset (or the end) of mangling, and stop (or start) sending ECN-capable packets to match. ๐
As always, once a host has entered AccECN mode, it follows the general mandatory requirements (Section 3.1.5). That means it stays in the same feedback mode and keeps feeding back any ECN markings on arriving packets using AccECN feedback. This follows the general approach where an AccECN Data Receiver mechanistically reflects whatever it receives (Section 2.5) ๐ช
The ACK of the SYN/ACK isn't reliably delivered. The count of CE marks still gets delivered reliably in the end, though. If this ACK doesn't arrive, the Server is advised to keep sending ECN-capable packets without having tested for mangling of the IP-ECN field on the SYN/ACK. ๐ซง
All the fall-back behaviours in this section are needed in case mangling of the IP-ECN field is asymmetric. That's currently common over some mobile networks [Mandalari18]. In this case, one end might see no unsafe transition and keep sending ECN-capable packets, while the other end sees an unsafe transition and stops sending ECN-capable packets. ๐ฑ
Invalid transitions of the IP-ECN field are defined in Section 18 of the Classic ECN specification [RFC3168]. They're repeated here for convenience:
- the Not-ECT codepoint changes;
- either ECT codepoint transitions to Not-ECT;
- the CE codepoint changes.
RFC 3168 says that a router changing ECT to Not-ECT is invalid but safe. From a host's point of view, though, this transition is unsafe. It could be the result of two transitions at different routers on the path: ECT to CE (safe), then CE to Not-ECT (unsafe). This could easily happen where an ECN-enabled home router congests its upstream mobile broadband bottleneck link, and then the ingress to the mobile network clears the ECN field [Mandalari18]. ๐ โก๏ธ๐ถ
3.2.2.4. Testing for Zeroing of the ACE Field ๐ซฅ
This section is about the ACE field after the three-way handshake. It does NOT cover the case where the ACE field is zero when the handshake encoding has been used on the ACK of the SYN/ACK under the carefully worded conditions in Section 3.2.2.1.
Section 3.2.2 required the Data Receiver to initialize the r.cep counter to a non-zero value. So in either direction, the ACE counter ought to be non-zero in the first feedback packet (with or without data) that arrives at a host in AccECN mode after the three-way handshake. However, if reordering occurs, the first feedback packet to arrive won't necessarily be the same as the first packet in sequence order. Because of that, there's a chance the ACE field on the first packet to arrive after the handshake is genuinely zero, with no middlebox interference at all. Disabling ECN for a half-connection in that case would be unnecessary. So it is NOT RECOMMENDED for either Data Sender to explicitly test for zeroing or bleaching of the ACE field after the three-way handshake. ๐
โโ๏ธ
Further, the Data Sender MUST NOT test whether the arriving counter in the initial ACE field has been initialized to a specific valid value. This lets hosts use different initial values as an extra signalling channel in the future. ๐ฎ
3.2.2.5. Safety Against Ambiguity of the ACE Field ๐จ
If too many CE-marked segments are acknowledged at once, or if a long run of ACKs is lost or thinned out, the 3-bit counter in the ACE field might have cycled between two ACKs arriving at the Data Sender. The following safety procedures minimise this ambiguity. ๐ก๏ธ
3.2.2.5.1. Packet Receiver Safety Procedures ๐
okay bestie, this bit is about when the receiver of a packet in AccECN mode has to send an ACK back ๐ซถ there are two rules that decide it:
- Change-Triggered ACKs: An AccECN Data Receiver SHOULD emit an ACK whenever a data packet marked CE arrives after the previous packet was not CE.
Even though this rule says "SHOULD," it's lowkey crucial for a transition to trigger an ACK if at all possible ๐ญ the only valid exception is due to Large Receive Offload (LRO) or Generic Receive Offload (GRO), which we'll get to in a sec โจ
For the avoidance of doubt ๐ this rule only applies when data packets arrive, but the comparison with the previous packet counts any packet, not just data ones. main character rule, no cap ๐
- Increment-Triggered ACKs: An AccECN receiver of a packet MUST emit an ACK if 'n' CE marks have arrived since the previous ACK. If there is unacknowledged data at the receiver, 'n' SHOULD be 2. If there is no unacknowledged data at the receiver, 'n' SHOULD be 3 and MUST be no less than 3. In either case, 'n' MUST be no greater than 7. ๐ฅ
These rules for when to send an ACK are designed to be complemented by the ones in Section 3.2.3.3 ๐ฆ those cover whether an AccECN TCP Option ought to be included on ACKs. it's giving teamwork ๐ซถ
If the arrivals of a number of data packets are all processed as one event, e.g., using large receive offload (LRO) or generic receive offload (GRO), both the above rules SHOULD be interpreted as requiring multiple ACKs to be emitted back to back (for each transition and for each sequence of 'n' CE marks). If this is problematic for high performance, either rule can be interpreted as requiring just a single ACK at the end of the whole receive event. ๐ธ
Even if a bunch of data packets don't arrive as one event, the Change-Triggered ACKs rule could sometimes make the ACK rate a problem for high performance ๐ฌ (although high-performance protocols like DCTCP already use change-triggered ACKs successfully ๐). The reason for change-triggered ACKs is so the Data Sender can rely on them to detect queue growth as soon as possible, especially right at the start of a flow ๐ yes it can lead to some extra ACKs, but it feeds back the timing and order in which ECN marks are received with minimal extra complexity. If CE marks are infrequent, which is the case for most Active Queue Management (AQM) algorithms at the time of writing, or there are multiple marks in a row, the extra load will be low. However, marking patterns with lots of non-contiguous CE marks could increase the load a lot ๐ One possible compromise would be for the receiver to heuristically detect whether the sender is in slow-start, then implement change-triggered ACKs while the sender is in slow-start, and offload otherwise. โจ
In a scenario where both endpoints support AccECN, if host B has chosen to use ECN-capable pure ACKs (as allowed in [RFC8311] experiments) and enough of these ACKs become CE marked, then the Increment-Triggered ACKs rule makes sure its peer (host A) gives B enough feedback about this congestion on the ACKs from B to A ๐ normally, for instance in a unidirectional data scenario from host A to B, 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 requires A to emit a pure ACK for at least every third CE-marked incoming ACK over the subsequent round trip. ๐ง
Although TCP normally only ACKs data segments, in this case the increment-triggered ACK rule makes it mandatory for A to emit ACKs of ACKs ๐ญ this is justifiable because the ACKs in this case are ECN-capable, so even though the ACKs of these ACKs don't acknowledge new data, they still feed back new congestion state (useful in case B starts sending). The minimum of 3 for 'n' in this case makes sure that, even if A also uses ECN-capable pure ACKs, and even if there's pathological congestion in both directions, any resulting ping-pong of ACKs gets rapidly damped ๐
In the bidirectional scenario above, incoming ACKs of ACKs could be mistaken for duplicate ACKs. But ACKs of ACKs can be told apart from duplicate ACKs because they don't contain any SACK blocks, even when SACK has been negotiated ๐ฆ it's outside the scope of this AccECN specification to normatively specify this extra test for DupACKs, because ACKs of ACKs can only show up if the original ACKs are ECN-capable. Instead, any specification that allows ECN-capable pure ACKs MUST make sending ACKs of ACKs conditional on measures to distinguish ACKs of ACKs from DupACKs (see for example [ECN++]). All that's necessary here is to require that these ACKs of ACKs MUST NOT contain any SACK blocks (which normally wouldn't happen anyway). iykyk ๐๐
3.2.2.5.2. Data Sender Safety Procedures ๐ก๏ธ
okay so this part is for the Data Sender ๐ if it hasn't received AccECN TCP Options to give it more dependable information, and it detects that the ACE field could have cycled, it SHOULD deem whether it cycled by taking the safest likely case under the prevailing conditions. ๐ฌ it can check whether the counter could have cycled by using the jump in the acknowledgement number since the last ACK to calculate or estimate how many segments could have been acknowledged. There's an example algorithm to implement this policy in Appendix A.2 โจ an implementation MAY use an alternative algorithm, as long as it satisfies the requirements in this subsection. ๐
If missing acknowledgement numbers arrive later (reordering) and prove that the counter did not cycle, the Data Sender MAY attempt to neutralize the effect of any action it took based on a conservative assumption that it later found to be incorrect. ๐ซถ
The Data Sender can estimate how many packets (of any marking) an ACK acknowledges. If the ACE counter on an ACK seems to imply that the minimum number of newly CE-marked packets is greater than the number of newly acknowledged packets, the Data Sender SHOULD consider the ACE counter to be correct (and its count of control packets to be incomplete), unless it can be sure that it's counting all control packets correctly. ๐ that's it for this bit, bestie ๐
3.2.3. The AccECN Option โจ
Okay bestie, so there are two alternative AccECN Options ๐ฆ shown in Figure 4, and the initial 'E' of each field name stands for 'Echo' ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Kind = 172 | Length = 11 | EE0B field |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EE0B (cont'd) | ECEB field |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EE1B field | Order 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Kind = 174 | Length = 11 | EE1B field |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EE1B (cont'd) | ECEB field |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| EE0B field | Order 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 4: The Two Alternative AccECN TCP Options
Figure 4 shows two option field orders, order 0 and order 1 ๐ They are both made of three 24-bit fields. Order 0 gives you the 24 least significant bits of the r.e0b, r.ceb, and r.e1b counters, in that order. Order 1 gives you the same fields, just in the opposite order ๐
On each packet, the Data Receiver can use whichever order is more efficient โจ Either way, the bytes within the fields are in network byte order (big-endian) ๐ธ
Why three bytes (24 bits) and not something smaller? It's a balancing act ๐ง The goal was to strike a balance between TCP Option space usage and the fidelity the counters need for typical scenarios, like hardware TCP Segmentation Offloading (TSO) and periods when no option may be transmitted (for example, SACK loss recovery). If you only had 2 bytes (16 bits), the counters could easily roll over within a single TSO transmission or a large/generic receive offload (LRO/GRO) event, and that's a whole mess ๐ญ Having two distinct orderings also lets the most pertinent changes get sent in an abbreviated option (see below) ๐
Note that there is no field to feed back Not-ECT bytes ๐ Nonetheless, an algorithm for the Data Sender to work out the number of payload bytes received as Not-ECT is given in Appendix A.4.
When a Data Receiver sends an AccECN Option, it MUST set the Kind field to 172 if using Order 0, or to 174 if using Order 1 ๐ฅ These two new TCP Option Kinds are registered in Section 7 and are called AccECN0 and AccECN1, respectively ๐
Whenever a Data Receiver sends an AccECN Option, the rules in Section 3.2.3.3 let it leave unchanged fields off the tail of the option, which helps with option space limits ๐ It can do that as long as it keeps the order of the remaining fields and includes any field that has changed. The length field MUST indicate which fields are present, as follows:
+========+==================+==================+
| Length | Order 0 | Order 1 |
+========+==================+==================+
| 11 | EE0B, ECEB, EE1B | EE1B, ECEB, EE0B |
+--------+------------------+------------------+
| 8 | EE0B, ECEB | EE1B, ECEB |
+--------+------------------+------------------+
| 5 | EE0B | EE1B |
+--------+------------------+------------------+
| 2 | (empty) | (empty) |
+--------+------------------+------------------+
Table 5: Fields included in AccECN TCP
Options of each length and order
The empty option with Length=2 exists for one specific case ๐ฆ Sometimes an AccECN Option has to be sent (for example, on the SYN/ACK to test the path), but there's very limited space for it. That's when this one saves the day ๐ซถ
All implementations of a Data Sender that read any AccECN Option MUST be able to read AccECN Options of any of the above lengths ๐ For forward compatibility, if the AccECN Option is any other length, implementations MUST use those whole 3-octet fields that fit within the length, and ignore the remainder of the option by treating it as padding ๐
AccECN Options have to be optional to implement, because both sender and receiver have to be able to cope without options anyway, in cases where they don't traverse a network path ๐คทโโ๏ธ It is RECOMMENDED to implement both sending and receiving of AccECN Options. Support for them is especially valuable over paths with a high degree of ACK filtering, where the 3-bit ACE counter alone might sometimes be insufficient, because it's ambiguous whether it has wrapped ๐ญ If sending of AccECN Options is implemented, the fall-backs described in this document will need to be implemented as well, unless it's solely for a controlled environment where path traversal isn't considered a problem ๐ฅ Even if a developer doesn't implement logic to understand received AccECN Options, it is RECOMMENDED that they implement logic to send them. Otherwise, the remote peers that do implement the receiving logic will still be shut out of congestion feedback that's robust against the increasingly aggressive ACK filtering on the Internet ๐ Sending logic is also the simpler of the two sides to build, so no excuses ๐
If a Data Receiver intends to send an AccECN Option at any time during the rest of the connection, it is RECOMMENDED to also test path traversal of the AccECN Option, as specified in Section 3.2.3.2 ๐ง
3.2.3.1. Encoding and Decoding Feedback in the AccECN Option Fields
Whenever the Data Receiver includes any of the counter fields (ECEB, EE0B, EE1B) in an AccECN Option, it MUST encode the 24 least significant bits of the current value of the associated counter into the field: r.ceb, r.e0b, or r.e1b respectively ๐
Whenever the Data Sender receives an ACK carrying an AccECN Option, it first checks whether that ACK has already been superseded by another ACK. If it has, the Data Sender ignores the ECN feedback ๐ If it hasn't been superseded, the Data Sender normally decodes the fields in the AccECN Option like this ๐ง For each field, it takes the least significant 24 bits of its associated local counter (s.ceb, s.e0b, or s.e1b) and subtracts them from the counter in the matching field of the incoming AccECN Option (ECEB, EE0B, or EE1B, respectively). That gives the minimum positive increment it could apply to s.ceb, s.e0b, or s.e1b, assuming the field in the option only wrapped once at most โจ
Appendix A.1 gives an example algorithm for the Data Receiver to encode its byte counters into an AccECN Option, and for the Data Sender to decode the AccECN Option fields into its byte counters ๐
Note that, as specified in Section 3.2, any data on the SYN (SYN=1, ACK=0) is not included in any of the byte counters held locally for each ECN marking, nor in an AccECN Option on the wire ๐ธ
3.2.3.2. Path Traversal of the AccECN Option
3.2.3.2.1. Testing the AccECN Option During the Handshake
The TCP Client MUST NOT include an AccECN TCP Option on the SYN ๐ซ If there is somehow an AccECN Option on a SYN, it MUST be ignored when forwarded or received ๐งน
A TCP Server that confirms its support for AccECN (in response to an AccECN SYN from the Client, as described in Section 3.1) SHOULD include an AccECN TCP Option on the SYN/ACK ๐ฆ
A TCP Client that has successfully negotiated AccECN SHOULD include an AccECN Option in the first ACK at the end of the three-way handshake. However, this first ACK isn't delivered reliably, so the TCP Client SHOULD also include an AccECN Option on the first data segment it sends (if it ever sends one) ๐ซถ
A host MAY omit an AccECN Option in any of the above three cases, because of insufficient option space, or because it has cached knowledge that the packet would be likely to be blocked on the path to the other host if it included an AccECN Option ๐
3.2.3.2.2. Testing for Loss of Packets Carrying the AccECN Option ๐
Okay bestie, this is the "what if my packet just vanished into the void" section ๐ญ. If the TCP Server hasn't gotten an ACK for its SYN/ACK after the normal TCP timeout, or it gets a second SYN asking for AccECN support, then either the SYN/ACK just got lost (congestion, classic) or a middlebox is blocking AccECN Options ๐. To speed up setup where AccECN path traversal might be problematic, the TCP Server SHOULD retransmit the SYN/ACK with no AccECN Option. If that retransmission times out, the TCP Server SHOULD retransmit the SYN/ACK with (AE,CWR,ECE) = (0,0,0) and no AccECN Option to keep things moving, but it stays in AccECN feedback mode (per Section 3.1.5) โจ.
Note that a retransmitted AccECN SYN/ACK will not necessarily have the same TCP-ECN flags as the original SYN/ACK, because it feeds back the IP-ECN field of the latest SYN to have arrived (by the rule in Section 3.1.5).
This fall-back approach limits any interference from middleboxes that might drop packets with unknown options, even though SYN/ACK loss is more likely to be congestion ๐ธ. The TCP Server MAY try to send another packet with an AccECN Option later in the connection, but it ought to keep an eye on whether that packet gets lost too. If it does, the TCP Server SHOULD disable sending AccECN Options for this half-connection ๐ โโ๏ธ.
Implementers MAY use other fall-back strategies if they turn out to be more effective (e.g., retrying an AccECN Option a second time before falling back, which is most appropriate during high levels of congestion) ๐ง . Just know that other fall-back strategies will need to follow all the rules in Section 3.1.5, which cover behaviour when SYNs or SYN/ACKs negotiating different types of feedback have been sent within the same connection.
Further, it might make sense to also remove any other new or experimental fields or options from the SYN/ACK. The required behaviour depends on the specification of those other options and on any attempt to coordinate fall-back between different modules of the stack ๐งฉ.
If the TCP Client detects that the first data segment it sent with an AccECN Option was lost, and AccECN path traversal might be problematic in the deployment, it SHOULD fall back to no AccECN Option on the retransmission. Again, implementers MAY use other fall-back strategies, such as trying to retransmit a second segment with an AccECN Option before falling back, and/or caching whether AccECN Options are blocked for subsequent connections. [RFC9040] further discusses caching of TCP parameters and status information ๐.
If a middlebox is dropping packets with options it doesn't recognize, a host that sends little or no data and mostly pure ACKs won't inherently detect those losses ๐ฉ. Such a host MAY detect loss of ACKs carrying the AccECN Option by checking whether the acknowledged data always reappears as a retransmission. In those cases, the host SHOULD disable sending the AccECN Option for this half-connection.
If a host falls back to not sending AccECN Options, it keeps processing any incoming AccECN Options as normal ๐.
Either host MAY include AccECN Options in one or more subsequent segments to retest whether AccECN Options can traverse the path ๐.
Similarly, an AccECN endpoint MAY separately memorize which data packets carried an AccECN Option, and disable sending AccECN Options if the loss probability of those packets is significantly higher than that of all other data packets in the same connection ๐ .
3.2.3.2.3. Testing for Absence of the AccECN Option ๐ซฅ
If the TCP Client has successfully negotiated AccECN but doesn't receive an AccECN Option on the SYN/ACK (e.g., because it was stripped by a middlebox or never sent by the Server), the Client switches into a mode that assumes the AccECN Option isn't available for this half-connection ๐.
Similarly, if the TCP Server has successfully negotiated AccECN but doesn't receive an AccECN Option on the first segment that acknowledges sequence space at least covering the ISN, it switches into that same mode ๐.
While a host is in this mode, it MUST adopt the conservative interpretation of the ACE field discussed in Section 3.2.2.5 ๐ก๏ธ. However, it can't make any assumption about support for outgoing AccECN Options on the other half-connection, so it SHOULD keep sending AccECN Options itself (unless it has established that sending them is causing packets to be blocked, as in Section 3.2.3.2.2) โจ.
If a host is in the mode that assumes incoming AccECN Options are not available, but it receives an AccECN Option at any later point in the connection, that clearly means AccECN Options are no longer blocked on the path ๐. The AccECN endpoint MAY switch out of the mode that assumes AccECN Options are not available for this half-connection. Main character glow-up ๐ฆ.
3.2.3.2.4. Test for Zeroing of the AccECN Option ๐
For the merits of a related test for invalid initialization of the ACE field, see Section 3.2.2.4 ๐ง.
Section 3.2.1 required the Data Receiver to initialize the r.e0b and r.e1b counters to a non-zero value. So, in either direction, the initial value of the EE0B field or EE1B field in an AccECN Option (if one exists) ought to be non-zero. If AccECN has been negotiated:
- the TCP Server MAY check that the initial value of the
EE0Bfield or theEE1Bfield is non-zero in the first segment that acknowledges sequence space that at least covers the ISN plus 1. If it runs this test and either initial value is zero, the Server switches into a mode that ignores AccECN Options for this half-connection. - the TCP Client MAY check that the initial value of the
EE0Bfield or theEE1Bfield is non-zero on the SYN/ACK. If it runs this test and either initial value is zero, the Client switches into a mode that ignores AccECN Options for this half-connection.
While a host is in the mode that ignores AccECN Options, it MUST adopt the conservative interpretation of the ACE field discussed in Section 3.2.2.5 ๐ซก.
Note that the Data Sender MUST NOT test whether the arriving byte counters in an initial AccECN Option have been initialized to specific valid values. The checks above solely test whether these fields have been incorrectly zeroed. This allows hosts to use different initial values as an additional signalling channel in the future. Also note that the initial value of either field might be greater than its expected initial value, because the counters might already have been incremented. Nonetheless, the initial values of the counters have been chosen so that they cannot wrap to zero on these initial segments ๐.
3.2.3.2.5. Consistency Between AccECN Feedback Fields ๐
When AccECN Options are available, they ought to provide more unambiguous feedback. However, they supplement the ACE field but don't replace it. An endpoint using AccECN feedback MUST always reconcile the information in the ACE field with the information in any AccECN Option, so the state of the ACE-related packet counter can be relied on if future feedback doesn't carry an AccECN Option ๐งฎ.
If an AccECN Option is present, the s.cep counter might increase more than expected from the increase of the s.ceb counter (e.g., due to a CE-marked control packet). The sender's response to that situation is out of scope and needs to be handled in a specification that uses ECN-capable control packets ๐คทโโ๏ธ. Theoretically, this situation could also happen if a middlebox mangled an AccECN Option but not the ACE field. However, the Data Sender has to assume the integrity of AccECN Options is sound, based on the above test of the well-known initial values and, optionally, other integrity tests (Section 5.3) ๐.
If either endpoint detects that the s.ceb counter has increased but the s.cep counter hasn't (and, by testing ACK coverage, it is certain how much the ACE field has wrapped), and there's no explanation other than an invalid protocol transition caused by some form of feedback mangling, the Data Sender MUST disable sending ECN-capable packets for the rest of the half-connection. It does this by setting the IP-ECN field in all subsequent packets to Not-ECT ๐ซ๐ฅ.
3.2.3.3. Usage of the AccECN TCP Option โจ
okay bestie, so if a Data Receiver in AccECN mode wants to use AccECN TCP Options to send feedback, these rules decide when to include one and which fields go in it ๐ . Other options might be competing for the limited option space, so it's a whole vibe ๐ฅบ
Importance of Congestion Control: AccECN is for congestion control ๐ฅ, so implementations SHOULD generally prioritize it over other TCP Options when there isn't enough space for all the options in use.
If SACK has been negotiated [RFC2018], and the smallest recommended AccECN Option would leave insufficient space for two SACK blocks on a particular ACK, the Data Receiver MUST give precedence to the SACK option (total 18 octets), because loss feedback is more critical ๐ซถ.
Recommended Simple Scheme: The Data Receiver SHOULD include an AccECN TCP Option on every scheduled ACK if any byte counter has incremented since the last ACK. Whenever possible, it SHOULD include a field for every byte counter that has changed at some time during the connection (see examples later) โจ.
A scheduled ACK means an ACK that the Data Receiver would send under its regular delayed ACK rules. Recall that Section 1.3 defines an 'ACK' as either with data payload or without. The rule above is worded so that, in the common case where most of the data goes from a Server to a Client, the Server only includes an AccECN TCP Option while it's acknowledging data from the Client ๐ง.
When available TCP Option space is limited on particular packets, the recommended scheme will need to make some compromises ๐ฅฒ. To guide the implementer, the rules below are ranked in order of importance, but the final decision has to be implementation-dependent, because the tradeoffs will shift as new TCP Options get defined and new use-cases pop up ๐.
Necessary Option Length: When TCP Option space is limited, an AccECN TCP Option MAY be truncated to omit one or two fields from the end of the option, as indicated by the permitted variants listed in Table 5, provided that the counter(s) that have changed since the previous AccECN TCP Option are not omitted ๐.
If there is insufficient space to include an AccECN TCP Option containing the counter(s) that have changed since the previous AccECN TCP Option, then the entire AccECN TCP Option MUST be omitted. (see Section 3.2.3);
Change-Triggered AccECN TCP Options: If an arriving packet increments a different byte counter to the one incremented by the previous packet, the Data Receiver SHOULD feed it back in an AccECN Option on the next scheduled ACK ๐ฆ.
For the avoidance of doubt, this rule doesn't cover control packets with no payload, because they can't alter any byte counters ๐.
Continual Repetition: Otherwise, if arriving packets keep incrementing the same byte counter:
- the Data Receiver SHOULD include a counter that has continued to increment on the next scheduled ACK following a change-triggered AccECN TCP Option;
- while the same counter keeps incrementing, it SHOULD include the counter every n ACKs as consistently as possible, where n can be chosen by the implementer;
- it SHOULD always include an AccECN Option if the
r.cebcounter is incrementing, and it MAY include an AccECN Option ifr.e0borr.e1bis incrementing; - it SHOULD include each counter at least once for every
2^22bytes incremented, to prevent overflow during continual repetition ๐ฅ.
The above rules complement the ones in Section 3.2.2.5, which determine when to generate an ACK whether or not an AccECN TCP Option is going to be included ๐ .
The recommended scheme is meant to be a simple way to make sure all the relevant byte counters get carried on any ACK that reaches the Data Sender, no matter how many pure ACKs get filtered or coalesced along the network path. It also does this without eating up the space available for payload data with counter field(s) that have never changed ๐ซถโจ.
As an example of the recommended scheme: if ECT(0) is the only codepoint that has ever arrived in the IP-ECN field, the Data Receiver will feed back an AccECN0 TCP Option with only the EE0B field on every packet that acknowledges new data. However, as soon as even one CE-marked packet arrives, on every packet that acknowledges new data it will start including an option with two fields, EE0B and ECEB ๐ญ.
As a second example: if the first packet to arrive happens to be CE marked, the Data Receiver has to arbitrarily choose whether to put an EE0B field or an EE1B field in front of the ECEB field. If it chooses, say, EE0B but turns out never to receive ECT(0), it can start sending EE1B and ECEB instead. It doesn't have to include the EE0B field if the r.e0b counter never changed during the connection ๐.
With the recommended scheme, if the data sending direction switches during a connection, there can be cases where the AccECN TCP Option that's meant to feed back the counter values at the end of a volley in one direction never reaches the other peer, because of packet loss. ACE feedback ought to be enough to fill that gap, since accurate feedback becomes moot once data transmission has paused ๐ธ.
Appendix A.3 gives an example algorithm for estimating the number of marked bytes from the ACE field alone, for when AccECN Options aren't available ๐ง.
If a host has determined that segments with AccECN Options always seem to get discarded somewhere along the path, it is no longer obliged to follow any of the rules in this section ๐ฅ.
3.3. AccECN Compliance Requirements for TCP Proxies, Offload Engines, and Other Middleboxes ๐
Given AccECN changes the TCP protocol on the wire, this section specifies new requirements for certain networking equipment that forwards TCP and inspects TCP header information ๐.
3.3.1. Requirements for TCP Proxies
A big class of middleboxes splits TCP connections ๐ฆ. Such a middlebox would be compliant with the AccECN protocol if the TCP implementation on each side complied with the present AccECN specification, and each side negotiated AccECN independently of the other side โจ.
3.3.2. Requirements for Transparent Middleboxes and TCP Normalizers
Another big class of middleboxes intervenes to some degree at the transport layer, but tries to be transparent (invisible) to the end-to-end connection ๐ซฃ. A subset of this class tries to 'normalize' the TCP wire protocol by checking that all values in header fields comply with a pretty narrow reading of the TCP specifications, which also isn't always kept up to date ๐.
A middlebox that isn't normalizing the TCP protocol, and doesn't itself act as a back-to-back pair of TCP endpoints (i.e., a middlebox that intends to be transparent or invisible at the transport layer), ought to forward AccECN TCP Options unaltered. That's true whether or not the length value matches one of those specified in Section 3.2.3, and whether or not the initial values of the byte-counter fields match those in Section 3.2.1. This is because blocking values that look invalid stops the standardized set of values from ever being extended in the future. Outdated normalizers would end up blocking updated hosts from using the extended AccECN standard ๐ค.
A TCP normalizer is likely to block or alter an AccECN TCP Option if the length value or the initial values of its byte-counter fields don't match one of those specified in Sections 3.2.3 or 3.2.1. However, to comply with the present AccECN specification, a middlebox MUST NOT change the ACE field; or those fields of an AccECN Option that are currently specified in Section 3.2.3; or any AccECN field covered by integrity protection (e.g., [RFC5925]) ๐ซ๐.
3.3.3. Requirements for TCP ACK Filtering
Section 5.2.1 of [RFC3449] gives best current practice on filtering (aka thinning or coalescing) of pure TCP ACKs. It advises that filtering ACKs carrying ECN feedback ought to preserve the correct operation of ECN feedback. Since the present specification updates the operation of ECN feedback, this section discusses how an ACK filter might preserve the correct operation of AccECN feedback as well ๐ง.
The problem splits into two parts: figuring out if an ACK is part of a connection that's using AccECN, and then preserving the correct operation of AccECN feedback ๐:
- To determine whether a pure TCP ACK is part of an AccECN connection without resorting to connection tracking and per-flow state, a useful heuristic would be to check for a non-zero ECN field at the IP layer. The reason is that the ECN++ experiment only allows TCP pure ACKs to be ECN-capable if AccECN has been negotiated [ECN++]. This heuristic is simple and stateless. However, it might miss some AccECN ACKs, because AccECN can be used without ECN++. Even if a sender uses ECN++, it doesn't necessarily have to mark pure ACKs as ECN-capable. Only deployment experience will tell. Also, TCP ACKs might be ECN-capable owing to some scheme other than AccECN, e.g., [RFC5690] or some future standards action. Again, only deployment experience will tell ๐.
- The main concern with preserving correct AccECN operation is leaving enough ACKs for the Data Sender to work out whether the 3-bit ACE field has wrapped. In the worst case, in feedback about a run of received packets that were all ECN-marked, the ACE field will wrap every 8 acknowledged packets. ACE field wrap might be of less concern if packets also carry AccECN TCP Options. However, note that logic to read an AccECN TCP Option is optional to implement (albeit recommended, see Section 3.2.3). So one end writing an AccECN TCP Option into a packet doesn't necessarily mean the other end will read it ๐.
Note that the present specification of AccECN in TCP doesn't presume to rely on any of the above ACK filtering behaviour in the network. That's because it has to be robust against pre-existing network nodes that don't distinguish AccECN ACKs, and robust against ACK loss during overload more generally ๐ชโจ.
3.3.4. Requirements for TCP Segmentation Offload and Large Receive Offload โจ
Okay bestie, hardware that offloads certain TCP processing is its own whole big category of middlebox ๐ง. It's usually a feature of the host's network interface rather than its own little box ๐ฆ, but it still counts!
Offloading can happen on the transmit side, called TCP Segmentation Offload (TSO) ๐, and on the receive side, called Large Receive Offload (LRO) ๐ฅ.
On transmit, AccECN makes life easy ๐ . All the segments made from the same super-segment should keep the same ACE field ๐, so TSO is pretty straightforward.
BUT ๐ฌ with TSO hardware that supports [RFC3168], the CWR bit usually gets masked out on the middle and last segments. If that happens to an AccECN segment, the ACE field changes, and the other end would read it as having received a bunch of CE marks in the receive direction ๐. So currently available TSO hardware with [RFC3168] support may need some minor driver changes to adjust the bitmask for the first, middle, and last segments processed with TSO ๐ ๏ธ.
At the start, when Classic ECN [RFC3168] and Accurate ECN flows share the same offloading engine, the host software may need to work around incompatibilities (for example, when only global configurable TSO TCP Flag bitmasks are available). Otherwise, this would cause some issues ๐.
There are a couple of ways around it ๐ง. One is to only negotiate for Accurate ECN, but not offer a fall back to Classic ECN [RFC3168]. Another is to allow TSO only as long as the CWR flag in the TCP header is not set, which costs more processing overhead while the ACE field has this bit set ๐.
For LRO on the receive side, a different issue may pop up with hardware that supports Classic ECN [RFC3168] ๐.
The ACE field changes with every received CE marking, so today's receive offloading could lead to a ton of interrupts in high congestion situations ๐ญ. Honestly, that would be useful, because congestion information arrives sooner. But it could also seriously boost processor load, especially in scenarios like DCTCP or L4S where the marking rate is generally higher ๐ฅ.
Current offload hardware kicks a segment out of the coalescing process whenever the TCP-ECN flags change. In data centres, this offload hardware has been pretty lucky ๐, because DCTCP-style feedback changes less often when there are long sequences of CE marks. That's more common with a step marking threshold, though it's less likely the more short flows are in the mix. The ACE counter approach was designed so coalescing can keep going over arbitrary patterns of marking, and it only needs to stop when the counter wraps ๐ฆ. Still, until the particular offload hardware in use implements this more efficient approach, it's likely more efficient for AccECN connections to do this counter-style logic using software segmentation offload ๐.
ECN encodes a varying signal in the ACK stream, so it's inevitable that offload hardware will eventually need to handle any form of ECN feedback exceptionally ๐ซถ. The ACE field is designed as a counter, so it's easy for offload hardware to pass on the highest counter and push a segment from its cache before the counter wraps. The goal of standardized TCP-ECN feedback is to reduce the risk for hardware developers, who would otherwise have to guess which scheme is likely to become dominant ๐ฎ.
This whole process is built to enable a continuing incremental deployment path toward more highly dynamic congestion control ๐. Once offload hardware supports AccECN, it will be able to coalesce efficiently for any sequence of marks, instead of relying on the long marking sequences from step marking for efficiency โจ. In the next stage, marking can evolve from a step to a ramp function. That in turn lets host congestion control algorithms respond faster to dynamics, while staying backwards compatible with existing host algorithms ๐.
4. Updates to RFC 3168 ๐
This section clarifies which parts of RFC 3168 get updated, and maps them to the relevant updated sections of the present AccECN specification ๐บ๏ธ.
- The whole of Section 6.1.1 (TCP Initialization) of [RFC3168] is updated by Section 3.1 of the present specification.
- In Section 6.1.2 (The TCP Sender) of [RFC3168], all mentions of a congestion response to an ECN-Echo (ECE) ACK packet are updated by Section 3.2 of the present specification to mean an increment to the sender's count of CE-marked packets,
s.cep. The requirements to set the CWR flag no longer apply, as specified in Section 3.1.5 of the present specification. Otherwise, the remaining requirements in Section 6.1.2 (The TCP Sender) of [RFC3168] still stand ๐.
Note that [RFC8311] already updates a number of the requirements in Section 6.1.2 (The TCP Sender) of [RFC3168]. Section 6.1.2 of [RFC3168] extended standard TCP congestion control [RFC5681] to cover ECN marking as well as packet drop. Whereas, [RFC8311] enables experimentation with alternative responses to ECN marking, if specified for instance by an Experimental RFC produced by the IETF Stream. [RFC8311] also strengthened the statement that "ECT(0) SHOULD be used" to a "MUST" (see [RFC8311] for the details) ๐ .
- The whole of Section 6.1.3 (The TCP Receiver) of [RFC3168] is updated by Section 3.2 of the present specification, with the exception of the last paragraph (about congestion response to drop and ECN in the same round trip), which still stands. Incidentally, this last paragraph is in the wrong section, because it relates to "TCP Sender" behaviour ๐.
- The following text within Section 6.1.5 (Retransmitted TCP packets) of [RFC3168]:
the TCP data receiver SHOULD ignore the ECN field on arriving
data packets that are outside of the receiver's current window.
is updated by more stringent acceptability tests for any packet (not just data packets) in the present specification. Specifically, in the normative specification of AccECN (Section 3), only 'Acceptable' packets contribute to the ECN counters at the AccECN receiver, and Section 1.3 defines an Acceptable packet as one that passes acceptability tests equivalent in strength to those in both [RFC9293] and [RFC5961] ๐.
- Sections 5.2 (Dropped or Corrupted Packets), 6.1.1 (TCP Initialization), 6.1.4 (Congestion on the ACK-path), 6.1.5 (Retransmitted TCP packets), and 6.1.6 (TCP Window Probes) of [RFC3168] prohibit use of ECN on TCP control packets and retransmissions. The present specification does not update that aspect of [RFC3168], but it does say what feedback an AccECN Data Receiver ought to provide if it receives an ECN-capable control packet or retransmission. This ensures AccECN is forward compatible with any future scheme that allows ECN on these packets, as provided for in Section 4.3 of [RFC8311] and as proposed in [ECN++] ๐งโโ๏ธ.
5. Interaction with TCP Variants ๐ธ
This section is informative, not normative.
5.1. Compatibility with SYN Cookies ๐ช
A TCP Server can use SYN Cookies (see Appendix A of [RFC4987]) to protect itself from SYN flooding attacks. It places minimal, commonly used connection state in the SYN/ACK, and deliberately does not hold any state while waiting for the subsequent ACK (for example, it closes the thread). Therefore, it cannot record the fact that it entered AccECN mode for both half-connections. Honestly, it can't even remember whether it negotiated the use of Classic ECN [RFC3168] ๐ต.
Nonetheless, such a Server can still figure out that it negotiated AccECN, as follows ๐ต๏ธโโ๏ธ. If a TCP Server using SYN Cookies supports AccECN, and it receives a pure ACK that acknowledges an ISN that is a valid SYN cookie, and the ACK contains an ACE field with the value 0b010 to 0b111 (decimal 2 to 7), the Server can infer the first two stages of the handshake:
- the TCP Client has to have requested AccECN support on the SYN;
- then, even though the Server kept no state, it has to have confirmed that it supported AccECN.
So the Server can switch itself into AccECN mode, and continue as if it had never forgotten that it switched itself into AccECN mode earlier ๐.
If the pure ACK that acknowledges a SYN cookie contains an ACE field with the value 0b000 or 0b001, these values mean the TCP Client did not request support for AccECN. So the Server does not enter AccECN mode for this connection. Also, 0b001 on the ACK implies that the Server sent an ECN-capable SYN/ACK, which was marked CE in the network, and the non-AccECN TCP Client fed this back by setting ECE on the ACK of the SYN/ACK ๐ซ.
5.2. Compatibility with TCP Experiments and Common TCP Options ๐ง
AccECN is compatible (at least on paper) with the most commonly used TCP Options: MSS, timestamp, window scaling, SACK, and TCP-AO ๐ฅฐ. It's also compatible with Multipath TCP (MPTCP [RFC8684]) and the experimental TCP Option TCP Fast Open (TFO [RFC7413]). AccECN is friendly to all of these protocols, because space for TCP Options is particularly scarce on the SYN, and AccECN consumes zero additional header space there ๐.
Because option space is limited, Section 3.2.3.3 specifies which AccECN Option fields are more important to include, and provides guidance on the relative importance of AccECN Options against other TCP Options ๐.
Implementers of TFO need to take careful note of the recommendation in Section 3.2.2.1 ๐ค. That section recommends that, if the TCP Client has successfully negotiated AccECN, then when acknowledging the SYN/ACK, even if it has data to send, it sends a pure ACK immediately before the data. Then it can reflect the IP-ECN field of the SYN/ACK on this pure ACK, which allows the Server to detect ECN mangling. Note that, as specified in Section 3.2, any data on the SYN (SYN=1, ACK=0) is not included in any of the byte counters held locally for each ECN marking, nor in the AccECN Option on the wire โ ๏ธ.
AccECN feedback is compatible with the ECN++ experiment [ECN++], which allows TCP control packets and retransmissions to be ECN-capable ([RFC3168] was updated by [RFC8311] to permit such experiments) ๐งช. AccECN is likely to inherently support any experiment with ECN-capable packets, because it feeds back the contents of the ECN field mechanistically, without judging whether or not a packet ought to use the ECN capability (Section 2.5) ๐ค. This specification does not discuss implementing AccECN alongside [RFC5562], which was an earlier experimental protocol with narrower scope than ECN++ and a 5-way handshake ๐ฐ๏ธ.
5.3. Compatibility with Feedback Integrity Mechanisms ๐
okay so there are three different ways to make sure ECN and/or loss signals haven't been messed with, and AccECN plays nice with all of them โจ
- Sender-side spot checks: the Data Sender can test the integrity of the Data Receiver's ECN (or loss) feedback by occasionally setting the IP-ECN field to a value that normally only the network sets (and/or deliberately leaving a sequence number gap) ๐ . Then it checks whether the feedback faithfully reports what it expects (kinda like paragraph 2 of Section 20.2 of [RFC3168], but make it iconic). Unlike the ECN-nonce [RFC3540], this one doesn't waste the ECT(1) codepoint in the IP header, doesn't need standardization, and doesn't depend on misbehaving receivers volunteering feedback that gets them caught ๐. BUT, setting the CE mark as the sender can hide real congestion feedback from the network, so it ought to only be done sparingly ๐ฅบ.
- Network-side enforcement: networks generate congestion signals when they're getting congested, so they're way more likely than Data Senders to care whether the receiver's feedback of those signals is legit ๐. A network can enforce a congestion response to its ECN markings (or packet losses) using congestion exposure (ConEx) audit [RFC7713]. Whether the receiver or a downstream network is suppressing congestion feedback, or the sender is ignoring the feedback, or both, ConEx audit can cancel out any advantage any of those three parties would otherwise get ๐ฆ.
ConEx is an experimental change to the Data Sender that's most useful when combined with AccECN ๐งช. Without AccECN, the ConEx behaviour of a Data Sender would have to be more conservative than necessary, since it wouldn't have AccECN's accurate feedback ๐ข.
- TCP-AO protection: the Standards Track TCP authentication option (TCP-AO [RFC5925]) can detect any tampering with AccECN feedback between the Data Receiver and the Data Sender, whether malicious or accidental ๐. The AccECN fields are immutable end to end, so they're a perfect fit for TCP-AO protection, which covers TCP Options by default โจ. Lowkey though, TCP-AO is often too brittle for many end-to-end paths, because middleboxes can make verification fail while trying to improve performance or security, like Network Address Translation (NAT) and Network Address Port Translation (NAPT), resegmentation, or shifting the sequence space ๐.
6. Summary: Protocol Properties โจ
This section is informative, not normative ๐. It describes how well the protocol satisfies the agreed requirements for a more Accurate ECN feedback protocol [RFC7560] ๐.
- Accuracy: From each ACK, the Data Sender can infer the number of new CE-marked segments since the previous ACK. That's better CE feedback accuracy than Classic ECN ๐. Plus, if an AccECN Option is present (and the network path doesn't block it), the number of bytes marked with CE, ECT(1), and ECT(0) come along for the ride ๐.
- Overhead: The AccECN scheme is split into two parts. The essential feedback part reuses the three flags already assigned to ECN in the TCP header ๐ฉ. The supplementary feedback part adds an extra TCP Option that consumes up to 11 bytes. But no TCP Option space gets eaten in the SYN โจ.
- Ordering: The order in which marks arrive at the Data Receiver is preserved in AccECN feedback, because the Data Receiver is expected to send an ACK immediately whenever a different mark arrives ๐.
- Timeliness: While the same ECN markings keep arriving, the Data Receiver can defer ACKs as TCP normally does, but it will send an ACK right away as soon as a different ECN marking shows up โฐ.
- Timeliness vs Overhead: Change-Triggered ACKs are meant to enable latency-sensitive uses of ECN feedback by capturing the timing of transitions without wasting resources while the signalling system is stable ๐ง. Within the change-triggered ACK rules, the receiver can control how often it sends AccECN TCP Options, so to some extent it can control the overhead AccECN induces ๐.
- Resilience: All information is provided based on counters. So if ACKs are lost, the counters on the first ACK after the losses let the Data Sender instantly recover the number of ECN markings it missed ๐. If data or ACKs are reordered, stale congestion information can be identified and ignored ๐ .
- Resilience against Bias: Because feedback is based on repetition of counters, random losses don't remove any information, they only delay it ๐ซถ. So even though some ACKs are change-triggered, random losses won't alter the proportions of the different ECN markings in the feedback ๐.
- Resilience vs Overhead: If space is limited in some segments (e.g., because more options are needed on some segments, such as the SACK option after loss), the Data Receiver can send AccECN Options less frequently or truncate fields that haven't changed, usually down to as little as 5 bytes โ๏ธ.
- Resilience vs Timeliness and Ordering: Ordering information and the timing of transitions cannot be communicated in three cases: i) during ACK loss; ii) if something on the path strips AccECN Options; or iii) if the Data Receiver is unable to support Change-Triggered ACKs ๐ฑ. Following ACK reordering, the Data Sender can reconstruct the order in which feedback was sent, but not until all the missing feedback has arrived ๐งฉ.
- Complexity: An AccECN implementation solely involves simple counter increments, some modulo arithmetic to communicate the least significant bits and allow for wrap, and some heuristics for safety against fields cycling due to prolonged periods of ACK loss ๐ข. Each host needs to maintain eight additional counters. The hosts have to apply some additional tests to detect tampering by middleboxes, but in general the protocol is simple to understand and implement and requires few cycles per packet ๐ง .
- Integrity: AccECN is compatible with at least three approaches that can assure the integrity of ECN feedback ๐. If AccECN Options are stripped, the resolution of the feedback is degraded, but the integrity of this degraded feedback can still be assured ๐ก๏ธ.
- Backward Compatibility: If only one endpoint supports the AccECN scheme, it falls back to the most advanced ECN feedback scheme supported by the other end ๐.
If AccECN Options are stripped by a middlebox, AccECN still provides basic congestion feedback in the ACE field ๐. Further, AccECN can detect mangling of the IP-ECN field; mangling of the TCP-ECN flags; blocking of ECT-marked segments; and blocking of segments carrying an AccECN Option ๐ต๏ธ. It can detect these conditions during TCP's three-way handshake so that it can fall back to operation without ECN and/or operation without AccECN Options ๐ค.
- Forward Compatibility: The behaviour of endpoints and middleboxes is carefully defined for all reserved or currently unused codepoints in the scheme ๐ฎ. Then, the designers of security devices can understand which currently unused values might appear in the future. So, even if they choose to treat such values as anomalous while they aren't widely used, any blocking will at least be under policy control, not hard-coded ๐๏ธ. Then, if previously unused values start to appear on the Internet (or in standards), such policies could be quickly reversed ๐.
7. IANA Considerations ๐ธ
This document reassigns the TCP header flag at bit offset 7 to the AccECN protocol. This bit was previously called the Nonce Sum (NS) flag [RFC3540], but RFC 3540 has been reclassified as Historic [RFC8311]. The flag is now defined as the following in the "TCP Header Flags" registry in the "Transmission Control Protocol (TCP) Parameters" registry group:
+=====+==============+===========+==============================+
| Bit | Name | Reference | Assignment Notes |
+=====+==============+===========+==============================+
| 7 | AE (Accurate | RFC 9768 | Previously used as NS (Nonce |
| | ECN) | | Sum) by [RFC3540], which is |
| | | | now Historic [RFC8311] |
+-----+--------------+-----------+------------------------------+
Table 6: TCP Header Flag Reassignment
This document also defines two new TCP Options for AccECN from the TCP Option space. These values are defined as the following in the "TCP Option Kind Numbers" registry in the "Transmission Control Protocol (TCP) Parameters" registry group:
+======+========+================================+===========+
| Kind | Length | Meaning | Reference |
+======+========+================================+===========+
| 172 | N | Accurate ECN Order 0 (AccECN0) | RFC 9768 |
+------+--------+--------------------------------+-----------+
| 174 | N | Accurate ECN Order 1 (AccECN1) | RFC 9768 |
+------+--------+--------------------------------+-----------+
Table 7: New TCP Option Assignments
Early experimental implementations of the two AccECN Options used experimental option 254 per [RFC6994] with the 16-bit magic numbers 0xACC0 and 0xACC1, respectively, for Order 0 and 1, as allocated in the IANA "TCP/UDP Experimental Option Experiment Identifiers (TCP/UDP ExIDs)" registry. Even earlier experimental implementations used the single magic number 0xACCE (16 bits). Uses of these experimental options SHOULD migrate to use the new option kinds (172 and 174) ๐.
8. Security and Privacy Considerations โจ
Okay bestie, this section is SERIOUS but also iconic, so let's get into it ๐ ๐
If the supplementary feedback part of AccECN that's based on one of the new AccECN TCP Options ever becomes unusable (say, because a middlebox is messing with it ๐), the essential feedback part of AccECN's congestion feedback only has limited resilience to long runs of ACK loss (see Section 3.2.2.5). Honestly, these problems probably aren't malicious ๐ซ because if an attacker could strip a TCP Option or throw away a long run of ACKs, they could wreak all kinds of other havoc anyway. BUT, it would be a real concern if AccECN's resilience could be indirectly compromised during a flooding attack ๐ญ Still, AccECN is considered safe, okay? Because if AccECN Options aren't present, the AccECN Data Sender is required to switch to more conservative assumptions about wrap of congestion indication counters (see Section 3.2.2.5 and Appendix A.2). That's a whole safety net, periodt ๐ง
Section 5.1 explains how a TCP Server can negotiate AccECN and use the SYN cookie method to mitigate SYN flooding attacks ๐ก๏ธ๐ธ
There's concern that ECN feedback could be altered or suppressed, especially because a misbehaving Data Receiver could boost its own throughput at everyone else's expense ๐ AccECN is compatible with the three schemes known to assure the integrity of ECN feedback (see Section 5.3 for details) ๐๐ If an incorrectly implemented middlebox strips AccECN Options, the resolution of the feedback gets degraded, but the integrity of that degraded information can still be assured โจ Making sure Data Senders respond appropriately to ECN feedback is possible, but the scope of this document is confined to the feedback protocol and excludes the response to that feedback. Not my problem, it's a different doc ๐
In Section 3.2.3, a Data Sender is allowed to ignore an unrecognized TCP AccECN Option length and read as many whole 3-octet fields from it as possible, up to a maximum of 3, treating the remainder as padding. This opens up a potential covert channel of up to 29B (40 - (2+3*3)) ๐ซฃ BUT it's really an overt channel (not hidden), and it's no different from using unknown TCP Options with unknown option lengths in general. So where this is a concern, regular TCP normalizer technology can already mitigate it adequately (see Section 3.3.2) ๐งนโจ
There's a potential concern that a Data Receiver could deliberately omit AccECN Options and pretend they were stripped by a middlebox ๐ Right now, there's no known way for a receiver to take advantage of this, and it seems to always degrade its own performance ๐คทโโ๏ธ We're mentioning it here for completeness, bestie.
The AccECN protocol isn't believed to introduce any new privacy concerns, because it just counts and feeds back signals at the transport layer that were already visible at the IP layer ๐๏ธ A covert channel can be used to compromise privacy, but as explained above, undefined TCP Options in general open up such channels, and common techniques exist to close them off ๐๐งผ
A generic privacy concern with any new protocol is that for a while it'll be used by a small population of hosts, so those hosts could be more easily identified ๐ฅบ However, AccECN is expected to become available in more operating systems over time and to eventually be turned on by default ๐ So identifying one particular user is less of a worry than fingerprinting specific versions of operating systems. Though that latter one can be done through different means that have nothing to do with Accurate ECN, so ๐คทโโ๏ธ๐
9. References
9.1. Normative References
- [RFC2018] Mathis, M., Mahdavi, J., Floyd, S., and A. Romanow, "TCP Selective Acknowledgment Options", RFC 2018, DOI 10.17487/RFC2018, October 1996, <https://www.rfc-editor.org/info/rfc2018>.
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.
- [RFC2883] Floyd, S., Mahdavi, J., Mathis, M., and M. Podolsky, "An Extension to the Selective Acknowledgement (SACK) Option for TCP", RFC 2883, DOI 10.17487/RFC2883, July 2000, <https://www.rfc-editor.org/info/rfc2883>.
- [RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition of Explicit Congestion Notification (ECN) to IP", RFC 3168, DOI 10.17487/RFC3168, September 2001, <https://www.rfc-editor.org/info/rfc3168>.
- [RFC5961] Ramaiah, A., Stewart, R., and M. Dalal, "Improving TCP's Robustness to Blind In-Window Attacks", RFC 5961, DOI 10.17487/RFC5961, August 2010, <https://www.rfc-editor.org/info/rfc5961>.
- [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.
- [RFC9293] Eddy, W., Ed., "Transmission Control Protocol (TCP)", STD 7, RFC 9293, DOI 10.17487/RFC9293, August 2022, <https://www.rfc-editor.org/info/rfc9293>.
9.2. Informative References
- [ECN++] Bagnulo, M. and B. Briscoe, "ECN++: Adding Explicit Congestion Notification (ECN) to TCP Control Packets", Work in Progress, Internet-Draft, draft-ietf-tcpm-generalized-ecn-17, 21 April 2025, <https://datatracker.ietf.org/doc/html/draft-ietf-tcpm-generalized-ecn-17>.
- [Mandalari18] Mandalari, A., Lutu, A., Briscoe, B., Bagnulo, M., and ร. Alay, "Measuring ECN++: Good News for ++, Bad News for ECN over Mobile", IEEE Communications Magazine, March 2018, <http://www.it.uc3m.es/amandala/ecn++/ecn_commag_2018.html>.
- [RFC3449] Balakrishnan, H., Padmanabhan, V., Fairhurst, G., and M. Sooriyabandara, "TCP Performance Implications of Network Path Asymmetry", BCP 69, RFC 3449, DOI 10.17487/RFC3449, December 2002, <https://www.rfc-editor.org/info/rfc3449>.
- [RFC3540] Spring, N., Wetherall, D., and D. Ely, "Robust Explicit Congestion Notification (ECN) Signaling with Nonces", RFC 3540, DOI 10.17487/RFC3540, June 2003, <https://www.rfc-editor.org/info/rfc3540>.
- [RFC4987] Eddy, W., "TCP SYN Flooding Attacks and Common Mitigations", RFC 4987, DOI 10.17487/RFC4987, August 2007, <https://www.rfc-editor.org/info/rfc4987>.
- [RFC5562] Kuzmanovic, A., Mondal, A., Floyd, S., and K. Ramakrishnan, "Adding Explicit Congestion Notification (ECN) Capability to TCP's SYN/ACK Packets", RFC 5562, DOI 10.17487/RFC5562, June 2009, <https://www.rfc-editor.org/info/rfc5562>.
- [RFC5681] Allman, M., Paxson, V., and E. Blanton, "TCP Congestion Control", RFC 5681, DOI 10.17487/RFC5681, September 2009, <https://www.rfc-editor.org/info/rfc5681>.
- [RFC5690] Floyd, S., Arcia, A., Ros, D., and J. Iyengar, "Adding Acknowledgement Congestion Control to TCP", RFC 5690, DOI 10.17487/RFC5690, February 2010, <https://www.rfc-editor.org/info/rfc5690>.
- [RFC5925] Touch, J., Mankin, A., and R. Bonica, "The TCP Authentication Option", RFC 5925, DOI 10.17487/RFC5925, June 2010, <https://www.rfc-editor.org/info/rfc5925>.
- [RFC6679] Westerlund, M., Johansson, I., Perkins, C., O'Hanlon, P., and K. Carlberg, "Explicit Congestion Notification (ECN) for RTP over UDP", RFC 6679, DOI 10.17487/RFC6679, August 2012, <https://www.rfc-editor.org/info/rfc6679>.
- [RFC6994] Touch, J., "Shared Use of Experimental TCP Options", RFC 6994, DOI 10.17487/RFC6994, August 2013, <https://www.rfc-editor.org/info/rfc6994>.
- [RFC7141] Briscoe, B. and J. Manner, "Byte and Packet Congestion Notification", BCP 41, RFC 7141, DOI 10.17487/RFC7141, February 2014, <https://www.rfc-editor.org/info/rfc7141>.
- [RFC7323] Borman, D., Braden, B., Jacobson, V., and R. Scheffenegger, Ed., "TCP Extensions for High Performance", RFC 7323, DOI 10.17487/RFC7323, September 2014, <https://www.rfc-editor.org/info/rfc7323>.
- [RFC7413] Cheng, Y., Chu, J., Radhakrishnan, S., and A. Jain, "TCP Fast Open", RFC 7413, DOI 10.17487/RFC7413, December 2014, <https://www.rfc-editor.org/info/rfc7413>.
- [RFC7560] Kuehlewind, M., Ed., Scheffenegger, R., and B. Briscoe, "Problem Statement and Requirements for Increased Accuracy in Explicit Congestion Notification (ECN) Feedback", RFC 7560, DOI 10.17487/RFC7560, August 2015, <https://www.rfc-editor.org/info/rfc7560>.
- [RFC7713] Mathis, M. and B. Briscoe, "Congestion Exposure (ConEx) Concepts, Abstract Mechanism, and Requirements", RFC 7713, DOI 10.17487/RFC7713, December 2015, <https://www.rfc-editor.org/info/rfc7713>.
- [RFC8257] Bensley, S., Thaler, D., Balasubramanian, P., Eggert, L., and G. Judd, "Data Center TCP (DCTCP): TCP Congestion Control for Data Centers", RFC 8257, DOI 10.17487/RFC8257, October 2017, <https://www.rfc-editor.org/info/rfc8257>.
- [RFC8311] Black, D., "Relaxing Restrictions on Explicit Congestion Notification (ECN) Experimentation", RFC 8311, DOI 10.17487/RFC8311, January 2018, <https://www.rfc-editor.org/info/rfc8311>.
- [RFC8511] Khademi, N., Welzl, M., Armitage, G., and G. Fairhurst, "TCP Alternative Backoff with ECN (ABE)", RFC 8511, DOI 10.17487/RFC8511, December 2018, <https://www.rfc-editor.org/info/rfc8511>.
- [RFC8684] Ford, A., Raiciu, C., Handley, M., Bonaventure, O., and C. Paasch, "TCP Extensions for Multipath Operation with Multiple Addresses", RFC 8684, DOI 10.17487/RFC8684, March 2020, <https://www.rfc-editor.org/info/rfc8684>.
- [RFC9000] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, May 2021, <https://www.rfc-editor.org/info/rfc9000>.
- [RFC9040] Touch, J., Welzl, M., and S. Islam, "TCP Control Block Interdependence", RFC 9040, DOI 10.17487/RFC9040, July 2021, <https://www.rfc-editor.org/info/rfc9040>.
- [RFC9260] Stewart, R., Tรผxen, M., and K. Nielsen, "Stream Control Transmission Protocol", RFC 9260, DOI 10.17487/RFC9260, June 2022, <https://www.rfc-editor.org/info/rfc9260>.
- [RFC9330] Briscoe, B., Ed., De Schepper, K., Bagnulo, M., and G. White, "Low Latency, Low Loss, and Scalable Throughput (L4S) Internet Service: Architecture", RFC 9330, DOI 10.17487/RFC9330, January 2023, <https://www.rfc-editor.org/info/rfc9330>.
- [RFC9438] Xu, L., Ha, S., Rhee, I., Goel, V., and L. Eggert, Ed., "CUBIC for Fast and Long-Distance Networks", RFC 9438, DOI 10.17487/RFC9438, August 2023, <https://www.rfc-editor.org/info/rfc9438>.
- [RoCEv2] InfiniBand Trade Association, "InfiniBand Architecture Specification", Volume 1, Release 1.4, 2020, <https://www.infinibandta.org/ibta-specification/>.
Appendix A. Example Algorithms โจ
Okay, bestie, this appendix is informative, not normative ๐ซถ It gives example algorithms that would satisfy the normative requirements of the AccECN protocol. But implementers are totally free to pick other ways to get there. Main character energy, no rules ๐
A.1. Example Algorithm to Encode/Decode the AccECN Option
So this is how a Data Receiver in AccECN mode can squish its CE byte counter r.ceb into the ECEB field of an AccECN TCP Option ๐ And then how a Data Sender in AccECN mode unsquishes that ECEB field back into its own byte counter s.ceb. The counters for bytes marked ECT(0) and ECT(1) in an AccECN Option get encoded and decoded the exact same way ๐ฆ
We're assuming each local byte counter is an unsigned integer bigger than 24b (probably 32b), and that this constant has been assigned:
DIVOPT = 2^24
Every single time a CE-marked data segment shows up, the Data Receiver bumps its local r.ceb up by the size of the TCP Data. Then whenever it sends an ACK with an AccECN Option, the value it writes into the ECEB field is:
ECEB = r.ceb % DIVOPT
(where % is the remainder operator, so it's just the leftover after dividing ๐)
When an AccECN Option arrives, the Data Sender first double-checks that the ACK hasn't been superseded, because we do NOT want to wind s.ceb backwards ๐ญ It uses the TCP acknowledgement number and any SACK options [RFC2018] to figure out newlyAckedB, which is how much new data the ACK acknowledges in bytes. newlyAckedB can be zero but never negative ๐
If newlyAckedB is zero, then either the ACK got superseded or some CE-marked packet(s) without data might have shown up. To break that tie, the Data Sender could use timestamps [RFC7323] (if they're present) to work out newlyAckedT, which is how much new time the ACK acknowledges. If the Data Sender decides the ACK has been superseded, it just ignores the AccECN Option ๐ Otherwise, it calculates the minimum non-negative difference d.ceb between the ECEB field and its local s.ceb counter, using modulo arithmetic like this:
if ((newlyAckedB > 0) || (newlyAckedT > 0)) {
d.ceb = (ECEB + DIVOPT - (s.ceb % DIVOPT)) % DIVOPT
s.ceb += d.ceb
}
Let's do an example, because this is where it clicks โจ Say s.ceb is 33,554,433 and ECEB is 1461 (both decimal). Then:
s.ceb % DIVOPT = 1
d.ceb = (1461 + 2^24 - 1) % 2^24
= 1460
s.ceb = 33,554,433 + 1460
= 33,555,893
Real talk, an implementation might use heuristics to guess the feedback in ACKs that went missing ๐ค And then when it gets the real feedback later, it might realise it needs to correct those earlier guesses as part of decoding. The decoding process above doesn't include any of that heuristic stuff, so it's a clean, simple version ๐ง
A.2. Example Algorithm for Safety Against Long Sequences of ACK Loss
This part shows how a Data Receiver in AccECN mode can encode its CE packet counter r.cep into the ACE field, and how the Data Sender in AccECN mode decodes the ACE field back into its s.cep counter ๐ The Data Sender's algorithm also has code to heuristically spot a long enough unbroken run of ACK losses that could have hidden a full cycle of the congestion counter in the ACE field of the next ACK to arrive. Iykyk, it's kind of a nail-biter ๐ญ
There are two variants of the algorithm:
- i) a more conservative variant for a Data Sender to use if it detects that AccECN Options are not available (see Section 3.2.2.5 and Section 3.2.3.2); and
- ii) a less conservative variant that works when complementary information is available from AccECN Options.
A.2.1. Safety Algorithm Without the AccECN Option
We're assuming each local packet counter is a sufficiently sized unsigned integer (probably 32b), and that this constant has been assigned:
DIVACE = 2^3
Every time an Acceptable CE-marked packet arrives (Section 3.2.2.2), the Data Receiver bumps its local r.cep up by 1. It repeats the same value of ACE in every subsequent ACK until the next CE marking shows up, where:
ACE = r.cep % DIVACE
Here's the tea โ If the Data Sender got an earlier value of the counter that was delayed because ACKs got reordered, it might wrongly calculate that the ACE field had wrapped around. So on every ACK that arrives, the Data Sender makes sure the ACK hasn't been superseded, using the TCP acknowledgement number, any SACK options, and timestamps (if available) to calculate newlyAckedB, same as in Appendix A.1. If the ACK hasn't been superseded, the Data Sender calculates the minimum difference d.cep between the ACE field and its local s.cep counter, using modulo arithmetic like so:
if ((newlyAckedB > 0) || (newlyAckedT > 0))
d.cep = (ACE + DIVACE - (s.cep % DIVACE)) % DIVACE
Section 3.2.2.5 expects the Data Sender to assume the ACE field cycled if that's the safest likely case under the prevailing conditions ๐ค The 3-bit ACE field in an arriving ACK could have cycled and become ambiguous to the Data Sender if a sequence of ACKs goes missing and covers a stream of data long enough to contain 8 or more CE marks. We say 'missing' rather than 'lost', because some or all of the missing ACKs might still arrive eventually, just out of order ๐ฆ Even if some of the missing ACKs were piggybacked on data (i.e., not pure ACKs), retransmissions won't repair the lost AccECN information, because AccECN requires retransmissions to carry the latest AccECN counters, not the original ones.
The phrase 'under prevailing conditions' leaves room for implementation-dependent interpretation ๐ A Data Sender might take into account the prevailing size of data segments and the prevailing CE marking rate just before that sequence of missing ACKs. But we're going to start with the simplest algorithm, which assumes segments are all full-sized. And ultra-conservatively, it assumes ECN marking was 100% on the forward path when ACKs on the reverse path started to all get dropped ๐ Specifically, if newlyAckedB is the amount of data an ACK acknowledges since the previous ACK, then the Data Sender could assume this acknowledges newlyAckedPkt full-sized segments, where:
newlyAckedPkt = newlyAckedB/MSS
Then it could assume the ACE field incremented by:
dSafer.cep = newlyAckedPkt - ((newlyAckedPkt - d.cep) % DIVACE)
Okay, example time ๐ง Imagine an ACK acknowledges newlyAckedPkt=9 more full-size segments than any previous ACK, and ACE increments by a minimum of 2 CE marks (d.cep=2). The formula says it would still be safe to assume 2 CE marks, because 9 - ((9-2) % 8) = 2. But if ACE goes up by a minimum of 2 and the ACK acknowledges 10 full-sized segments, then it would be necessary to assume there could have been 10 CE marks, because 10 - ((10-2) % 8) = 10. Wild, right? ๐ญ
Note that checks would need to be added to the pseudocode above for (d.cep > newlyAckedPkt), which could happen if newlyAckedPkt had been wrongly estimated using an inappropriate packet size ๐
ACKs that acknowledge a big stretch of packets might be common in data centres to get a high packet rate, or might be due to ACK thinning by a middlebox โจ In those cases, cycling of the ACE field would often look possible, so the algorithm above would be overly conservative, leading to a false high marking rate and poor performance. So it would be reasonable to only use dSafer.cep rather than d.cep if the moving average of newlyAckedPkt was well below 8 ๐
Implementers could build in more heuristics to estimate a prevailing average segment size and prevailing ECN marking. For instance, newlyAckedPkt in the formula above could be replaced with newlyAckedPktHeur = newlyAckedPkt*p*MSS/s, where s is the prevailing segment size and p is the prevailing ECN marking probability ๐ค However, ultimately, if TCP's ECN feedback becomes inaccurate, it still has loss detection to fall back on. So it would seem safe to implement a simple algorithm, rather than a perfect one ๐
The simple algorithm for dSafer.cep above requires no monitoring of prevailing conditions. It would still be safe if, for example, segments were on average at least 5% of a full-sized segment, as long as ECN marking was 5% or less ๐ธ Assuming it's used, the Data Sender would increment its packet counter like this:
s.cep += dSafer.cep
If missing acknowledgement numbers arrive later (due to reordering), Section 3.2.2.5.2 says "the Data Sender MAY attempt to neutralize the effect of any action it took based on a conservative assumption that it later found to be incorrect". To do that, the Data Sender would have to store the values of all the relevant variables whenever it made assumptions, so it could re-evaluate them later ๐ง Given this could get complex and it is not required, we don't attempt to give an example of how to do it. Boundaries, babes ๐ซถ
A.2.2. Safety Algorithm With the AccECN Option โจ
okay so, when AccECN Options are available on the ACKs both before AND after a possible run of ACK losses ๐, the Data Sender only needs CE-marked bytes? then it already has enough info from the AccECN Options and doesn't have to process the ACE field at all ๐
. but if for some reason it needs CE-marked packets ๐, then if dSafer.cep is different from d.cep, it can check whether d.cep is likely a safe enough estimate by looking at whether the average marked segment size (s = d.ceb/d.cep) is less than the MSS. (here d.ceb is the amount of newly CE-marked bytes -- see Appendix A.1.) specifically, it could use this algorithm:
SAFETY_FACTOR = 2
if (dSafer.cep > d.cep) {
if (d.ceb <= MSS * d.cep) { % Same as (s <= MSS), but no DBZ
sSafer = d.ceb/dSafer.cep
if (sSafer < MSS/SAFETY_FACTOR)
dSafer.cep = d.cep % d.cep is a safe enough estimate
} % else
% No need for else; dSafer.cep is already correct,
% because d.cep must have been too small
}
the chart below shows when the above algorithm swaps dSafer.cep for d.cep as a safe enough estimate of the number of CE-marked packets ๐:
^
sSafer|
|
MSS+
|
| dSafer.cep
| is
MSS/SAFETY_FACTOR+--------------+ safest
| |
| d.cep is safe|
| enough |
+-------------------->
MSS s
the following examples give the reasoning behind the algorithm, assuming MSS=1460 ๐ง:
- if
d.cep=0,dSafer.cep=8, andd.ceb=1460, thens=infinityandsSafer=182.5.- Therefore, even though the average size of 8 data segments is unlikely to have been as small as MSS/8,
d.cepcannot have been correct, because it would imply an average segment size greater than the MSS. ๐
- Therefore, even though the average size of 8 data segments is unlikely to have been as small as MSS/8,
- if
d.cep=2,dSafer.cep=10, andd.ceb=1460, thens=730andsSafer=146.- Therefore
d.cepis safe enough, because the average size of 10 data segments is unlikely to have been as small as MSS/10. โจ
- Therefore
- if
d.cep=7,dSafer.cep=15, andd.ceb=10200, thens=1457andsSafer=680.- Therefore
d.cepis safe enough, because the average data segment size is more likely to have been just less than one MSS, rather than below MSS/2. ๐
- Therefore
if pure ACKs were allowed to be ECN-capable, missing ACKs would be far less likely ๐. however, because [RFC3168] currently precludes this, the above algorithm assumes that pure ACKs are not ECN-capable.
A.3. Example Algorithm to Estimate Marked Bytes from Marked Packets ๐
if AccECN Options are not available, the Data Sender can only decode the ACE field as a number of marked packets ๐ฅฒ. every time an ACK arrives, to convert the number of CE markings into an estimate of CE-marked bytes, it needs an average of the segment size, s_ave. then it can add or subtract s_ave from the value of d.ceb as the value of d.cep increments or decrements. there are some possible ways to calculate s_ave that are outlined below. the precise details will depend on why an estimate of marked bytes is needed.
the implementation could keep a record of the byte numbers of all the boundaries between packets in flight (including control packets), and recalculate s_ave on every ACK. however, it would be simpler to merely maintain a counter packets_in_flight for the number of packets in flight (including control packets), which is reset once per RTT. either way, it would estimate s_ave as:
s_ave ~= flightsize / packets_in_flight,
where flightsize is the variable that TCP already maintains for the number of bytes in flight and '~=' means 'approximately equal to'. to avoid floating point arithmetic, it could right-bit-shift by lg(packets_in_flight), where lg() means log base 2. ๐งฎ
an alternative would be to maintain an exponentially weighted moving average (EWMA) of the segment size:
s_ave = a * s + (1-a) * s_ave,
where a is the decay constant for the EWMA. however, then it is necessary to choose a good value for this constant, which ought to depend on the number of packets in flight. also the decay constant needs to be power of two to avoid floating point arithmetic. ๐ฆ
A.4. Example Algorithm to Count Not-ECT Bytes ๐ธ
a Data Sender in AccECN mode can infer the amount of TCP payload data arriving at the receiver marked Not-ECT from the difference between the amount of newly ACKed data and the sum of the bytes with the other three markings, d.ceb, d.e0b, and d.e1b. ๐
for this approach to be precise, it has to be assumed that spurious (unnecessary) retransmissions do not lead to double counting. this assumption is currently correct, given that RFC 3168 requires that the Data Sender mark retransmitted segments as Not-ECT. however, the converse is not true; necessary retransmissions will result in undercounting. ๐ฌ
however, such precision is unlikely to be necessary. the only known use of a count of Not-ECT marked bytes is to test whether equipment on the path is clearing the ECN field (perhaps due to an outdated attempt to clear, or bleach, what used to be the IPv4 ToS byte or the IPv6 Traffic Class field). to detect bleaching, it will be sufficient to detect whether nearly all bytes arrive marked as Not-ECT. therefore, there ought to be no need to keep track of the details of retransmissions. ๐ซถ
Appendix B. Rationale for Usage of TCP Header Flags ๐
B.1. Three TCP Header Flags in the SYN-SYN/ACK Handshake โจ
AccECN uses a rather unorthodox approach to negotiate the highest version TCP-ECN feedback scheme that both ends support, as justified below. it follows from the original TCP-ECN capability negotiation [RFC3168], in which the Client set the 2 least significant of the original reserved flags in the TCP header, and fell back to no support for ECN if the Server responded with the 2 flags cleared, which had previously been the default. ๐ง
Classic ECN used header flags rather than a TCP Option because it was considered more efficient to use a header flag for 1 bit of feedback per ACK, and this bit could be overloaded to indicate support for Classic ECN during the handshake. during the development of ECN, 1 bit crept up to 2, in order to deliver the feedback reliably and to work round some broken hosts that reflected the reserved flags during the handshake. ๐ญ
in order to be backward compatible with RFC 3168, AccECN continues this approach, using the 3rd least significant TCP header flag that had previously been allocated for the ECN-nonce (now Historic). then, whatever form of Server an AccECN Client encounters, the connection can fall back to the highest version of feedback protocol that both ends support, as explained in Section 3.1. ๐
if AccECN capability negotiation had used the more orthodox approach of a TCP Option, it would still have had to set the two ECN flags in the main TCP header to be able to fall back to Classic ECN [RFC3168], or to disable ECN support, without another round of negotiation. then AccECN would also have had to handle all the different ways that Servers currently respond to settings of the ECN flags in the main TCP header, including all of the conflicting cases where a Server might have said it supported one approach in the flags and another approach in a new TCP Option. and AccECN would have had to deal with all of the additional possibilities where a middlebox might have mangled the ECN flags, or removed TCP Options. thus, usage of the 3rd reserved TCP header flag simplified the protocol. ๐
the third flag was used in a way that could be distinguished from the ECN-nonce, in case any nonce deployment was encountered. previous usage of this flag for the ECN-nonce was integrated into the original ECN negotiation. this further justified the third flag's use for AccECN, because a non-ECN usage of this flag would have had to use it as a separate single bit, rather than in combination with the other 2 ECN flags. ๐งฉ
indeed, having overloaded the original uses of these three flags for its handshake, AccECN overloads all three bits again as a 3-bit counter. ๐๐
B.2. Four Codepoints in the SYN/ACK ๐ฆ
of the eight possible codepoints that the three TCP-ECN header flags can indicate on the SYN/ACK, four already indicated earlier (or broken) versions of ECN support, one now being Historic. in the early design of AccECN, an AccECN Server could use only 2 of the 4 remaining codepoints. they both indicated AccECN support, but one fed back that the SYN had arrived marked as CE. even though ECN support on a SYN is not yet on the Standards Track, the idea is for either end to act as a mechanistic reflector, so that future capabilities can be unilaterally deployed without requiring 2-ended deployment (justified in Section 2.5). ๐ช
during traversal testing, it was discovered that the IP-ECN field in the SYN was mangled on a non-negligible proportion of paths. therefore, it was necessary to allow the SYN/ACK to feed all four IP-ECN codepoints that the SYN could arrive with back to the Client. without this, the Client could not know whether to disable ECN for the connection due to mangling of the IP-ECN field (also explained in Section 2.5). this development consumed the remaining two codepoints on the SYN/ACK that had been reserved for future use by AccECN in earlier draft versions of this document. ๐ฅน๐
B.3. Space for Future Evolution
Okay so, TCP header space is extremely scarce, like, nobody is handing out extra real estate ๐ญ But AccECN has really gone out of its way to leave room for the future ๐ฆ Whether we need a variant of AccECN, or a completely different ECN feedback approach altogether, the door is left open ๐ชโจ
Future AccECN variants: Okay so when AccECN gets negotiated during TCP's three-way handshake, the rows in Table 2 tagged as 'Nonce' and 'Broken' in the column for node B's capability are unused by any current protocol in the RFC Series ๐ Servers could grab those in the future to signal a variant of AccECN ๐ In recent measurement studies where tons of Servers got tested with an AccECN SYN, e.g., [Mandalari18], a super tiny number of SYN/ACKs came back with the 'Nonce' pattern, and a small but more noticeable number came back with the 'Broken' pattern ๐ The 'Nonce' pattern might mean a few Servers implemented the ECN-nonce [RFC3540], which is now Historic [RFC8311] (bye bye ๐), or it could just be a random result of some unknown middlebox behaviour ๐คทโโ๏ธ The 'Broken' pattern showing up more is kinda sus, and it suggests some broken code that reflects the reserved flags on the SYN is still out there ๐
The requirement not to reject unexpected initial values of the ACE counter (in the main TCP header) from the last paragraph of Section 3.2.2.4 is what makes sure that three unused codepoints on the ACK of the SYN/ACK, six unused values on the first SYN=0 data packet from the Client, and seven unused values on the first SYN=0 data packet from the Server can be used to declare future variants of AccECN ๐ We say 'declare' instead of 'negotiate' on purpose, because by this late point in the three-way handshake, there's no time left for the endpoints to actually finish a negotiation ๐ซถ A similar rule not to reject unexpected initial values in AccECN TCP Options (Section 3.2.3.2.4) is there for the same reason ๐ If traversal of AccECN TCP Options were reliable, this would have unlocked a way wider range of future variation for the whole AccECN protocol ๐ญ Still, it could be used to reliably negotiate a wide range of variation in the semantics of the AccECN Option โจ
Future non-AccECN variants: Out of the eight possible combinations in the three TCP header flags used by AccECN, five are unused on the initial SYN (in the order (AE,CWR,ECE)) ๐
(0,0,1), (0,1,0), (1,0,0), (1,0,1), (1,1,0)
Section 3.1.3 makes sure that the installed base of AccECN Servers will all treat these as equivalent to AccECN negotiation with (1,1,1) on the SYN ๐ฅ These codepoints would not allow fall-back to Classic ECN support for a Server that didn't understand them, but this approach keeps them available for the future, maybe for uses other than ECN alongside the AccECN scheme ๐ง All possible combinations of SYN/ACK could be used in response, except either (0,0,0) or reflecting back the same values that were sent on the SYN ๐ โโ๏ธ
In order to extend AccECN or ECN in the future, other ways could be tried, although their traversal properties are likely to be inferior ๐ฌ These include a new TCP Option; using the remaining reserved flags in the main TCP header (preferably extending the 3-bit combinations used by AccECN to 4-bit combinations, rather than burning one bit for just one state) ๐; a non-zero urgent pointer in combination with the URG flag cleared ๐; or some other unexpected combination of fields that hasn't been invented yet ๐ธ
Acknowledgements โจ
We want to thank Koen De Schepper, Praveen Balasubramanian, Michael Welzl, Gorry Fairhurst, David Black, Spencer Dawkins, Michael Scharf, Michael Tรผxen, Yuchung Cheng, Kenjiro Cho, Olivier Tilmans, Ilpo Jรคrvinen, Neal Cardwell, Yoshifumi Nishida, Martin Duke, Jonathan Morton, Vidhi Goel, Alex Burr, Markku Kojo, Grenville Armitage and Wes Eddy for their input and discussion ๐ซถ๐ The idea of using the three ECN-related TCP flags as one field for more accurate TCP-ECN feedback was first introduced in the re-ECN protocol, which was the ancestor of ConEx ๐
The following contributed implementations of AccECN that validated and helped to improve this specification ๐
- Linux: Mirja Kรผhlewind, Ilpo Jรคrvinen, Neal Cardwell, and Chia-Yu Chang
- FreeBSD: Richard Scheffenegger
- Apple OSs: Vidhi Goel
Bob Briscoe was part-funded by Apple Inc, the Comcast Innovation Fund, the European Community under its Seventh Framework Programme through the Reducing Internet Transport Latency (RITE) project (ICT-317700) and through the Trilogy 2 project (ICT-317756), and the Research Council of Norway through the TimeIn project ๐ธ The views expressed here are solely those of the authors.
Mirja Kรผhlewind was partly supported by the European Commission under Horizon 2020 grant agreement no. 688421 Measurement and Architecture for a Middleboxed Internet (MAMI), and by the Swiss State Secretariat for Education, Research, and Innovation under contract no. 15.0268. This support does not imply endorsement ๐
Authors' Addresses โจ
Bob Briscoe Independent United Kingdom Email: ietf@bobbriscoe.net URI: http://bobbriscoe.net/
Mirja Kรผhlewind Ericsson Germany Email: ietf@kuehlewind.net
Richard Scheffenegger NetApp Vienna Austria Email: Richard.Scheffenegger@netapp.com
๐ฆ where this page comes from
- ietf: rfc9768 2026-04
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms