```
```

```
```

```
```

```
```
Simula
```
```

```
```

```
```

```
```
UC3M
```
```

```
```

```
```

```
```
Simula
```
```

```
```

```
```

```
```

```
```
(to appear)

```
```

```
```
This appendix is informative, not normative. It gives example
algorithms that would satisfy the normative requirements of the AccECN
protocol. However, implementers are free to choose other ways to
implement the requirements.
The
example algorithms below show how a Data Receiver in AccECN mode could
encode its CE byte counter r.ceb into the ECEB field within the AccECN
TCP Option, and how a Data Sender in AccECN mode could decode the ECEB
field into its byte counter s.ceb. The other counters for bytes marked
ECT(0) and ECT(1) in the AccECN Option would be similarly encoded and
decoded.
It is assumed that each local byte counter is an unsigned integer
greater than 24b (probably 32b), and that the following constant has
been assigned:
DIVOPT = 2^24

Every time a CE marked data segment arrives, the Data Receiver
increments its local value of r.ceb by the size of the TCP Data.
Whenever it sends an ACK with the AccECN Option, the value it writes
into the ECEB field is
ECEB = r.ceb % DIVOPT

where '%' is the modulo operator.
On the arrival of an AccECN Option, the Data Sender uses the TCP
acknowledgement number and any SACK options to calculate newlyAckedB,
the amount of new data that the ACK acknowledges in bytes. If
newlyAckedB is negative it means that a more up to date ACK has
already been processed, so this ACK has been superseded and the Data
Sender has to ignore the AccECN Option. Then the Data Sender
calculates the minimum difference d.ceb between the ECEB field and its
local s.ceb counter, using modulo arithmetic as follows:
For example, if s.ceb is 33,554,433 and ECEB is 1461 (both
decimal), then
The example algorithms below show how a Data Receiver in AccECN
mode could encode its CE packet counter r.cep into the ACE field, and
how the Data Sender in AccECN mode could decode the ACE field into its
s.cep counter. The Data Sender's algorithm includes code to
heuristically detect a long enough unbroken string of ACK losses that
could have concealed a cycle of the congestion counter in the ACE
field of the next ACK to arrive.
Two variants of the algorithm are given: i) a more conservative
variant for a Data Sender to use if it detects that the AccECN Option
is not available (see and ); and ii) a less conservative
variant that is feasible when complementary information is available
from the AccECN Option.
It is assumed that each local packet counter is a sufficiently
sized unsigned integer (probably 32b) and that the following
constant has been assigned:
DIVACE = 2^3

Every time a CE marked packet arrives, the Data Receiver
increments its local value of r.cep by 1. It repeats the same value
of ACE in every subsequent ACK until the next CE marking arrives,
where
ACE = r.cep % DIVACE.

If the Data Sender received an earlier value of the counter that
had been delayed due to ACK reordering, it might incorrectly
calculate that the ACE field had wrapped. Therefore, on the arrival
of every ACK, the Data Sender uses the TCP acknowledgement number
and any SACK options to calculate newlyAckedB, the amount of new
data that the ACK acknowledges. If newlyAckedB is negative it means
that a more up to date ACK has already been processed, so this ACK
has been superseded and the Data Sender has to ignore the AccECN
Option. If newlyAckedB is zero, to break the tie the Data Sender
could use timestamps (if present) to work out newlyAckedT, the
amount of new time that the ACK acknowledges. Then the Data Sender
calculates the minimum difference d.cep between the ACE field and
its local s.cep counter, using modulo arithmetic as follows:
requires the Data Sender to
assume that the ACE field did cycle if it could have cycled under
prevailing conditions. The 3-bit ACE field in an arriving ACK could
have cycled and become ambiguous to the Data Sender if a row of ACKs
goes missing that covers a stream of data long enough to contain 8
or more CE marks. We use the word `missing' rather than `lost',
because some or all the missing ACKs might arrive eventually, but
out of order. Even if some of the lost ACKs are piggy-backed on data
(i.e. not pure ACKs) retransmissions will not repair the lost AccECN
information, because AccECN requires retransmissions to carry the
latest AccECN counters, not the original ones.
The phrase `under prevailing conditions' allows the Data Sender
to take account of the prevailing size of data segments and the
prevailing CE marking rate just before the sequence of ACK losses.
However, we shall start with the simplest algorithm, which assumes
segments are all full-sized and ultra-conservatively it assumes that
ECN marking was 100% on the forward path when ACKs on the reverse
path started to all be dropped. Specifically, if newlyAckedB is the
amount of data that an ACK acknowledges since the previous ACK, then
the Data Sender could assume that this acknowledges newlyAckedPkt
full-sized segments, where newlyAckedPkt = newlyAckedB/MSS. Then it
could assume that the ACE field incremented by
For example, imagine an ACK acknowledges newlyAckedPkt=9 more
full-size segments than any previous ACK, and that ACE increments by
a minimum of 2 CE marks (d.cep=2). The above formula works out that
it would still be safe to assume 2 CE marks (because 9 - ((9-2) % 8)
= 2). However, if ACE increases by a minimum of 2 but acknowledges
10 full-sized segments, then it would be necessary to assume that
there could have been 10 CE marks (because 10 - ((10-2) % 8) =
10).
Implementers could build in more heuristics to estimate
prevailing average segment size and prevailing ECN marking. For
instance, newlyAckedPkt in the above formula 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. Therefore, 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 and it would still be safe if, for example,
segments were on average at least 5% of full-sized as long as ECN
marking was 5% or less. Assuming it was used, the Data Sender would
increment its packet counter as follows:
s.cep += dSafer.cep

If missing acknowledgement numbers arrive later (due to
reordering), says "the Data
Sender MAY attempt to neutralise the effect of any action it took
based on a conservative assumption that it later found to be
incorrect". To do this, the Data Sender would have to store the
values of all the relevant variables whenever it made assumptions,
so that it could re-evaluate them later. Given this could become
complex and it is not required, we do not attempt to provide an
example of how to do this.
When the AccECN Option is available on the ACKs before and after
the possible sequence of ACK losses, if the Data Sender only needs
CE-marked bytes, it will have sufficient information in the AccECN
Option without needing to process the ACE field. However, if for
some reason it needs CE-marked packets, if dSafer.cep is different
from d.cep, it can calculate the average marked segment size that
each implies to determine whether d.cep is likely to be a safe
enough estimate. Specifically, it could use the following algorithm,
where d.ceb is the amount of newly CE-marked bytes (see ):
The chart below shows when the above algorithm will consider
d.cep can replace dSafer.cep as a safe enough estimate of the number
of CE-marked packets:
The following examples give the reasoning behind the algorithm,
assuming MSS=1,460 [B]:
if d.cep=0, dSafer.cep=8 and d.ceb=1,460, then s=infinity and
sSafer=182.5.Therefore even though the
average size of 8 data segments is unlikely to have been as
small as MSS/8, d.cep cannot have been correct, because it would
imply an average segment size greater than the MSS.
if d.cep=2, dSafer.cep=10 and d.ceb=1,460, then s=730 and
sSafer=146.Therefore d.cep is safe
enough, because the average size of 10 data segments is unlikely
to have been as small as MSS/10.
if d.cep=7, dSafer.cep=15 and d.ceb=10,200, then s=1,457 and
sSafer=680.Therefore d.cep is safe
enough, because the average data segment size is more likely to
have been just less than one MSS, rather than below MSS/2.

If pure ACKs were allowed to be ECN-capable, missing ACKs would
be far less likely. However, because
currently precludes this, the above algorithm assumes that pure ACKs
are not ECN-capable.
If the AccECN Option is not available, the Data Sender can only
decode CE-marking from the ACE field in packets. Every time an ACK
arrives, to convert this 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.
To calculate s_ave, it 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 it could
update 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. 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.
requires a Data Receiver to
beacon a full-length AccECN Option at least 3 times per RTT. This
could be implemented by maintaining a variable to store the number of
ACKs (pure and data ACKs) since a full AccECN Option was last sent and
another for the approximate number of ACKs sent in the last round trip
time:
For optimised integer arithmetic, BEACON_FREQ = 4 could be used,
rather than 3, so that the division could be implemented as an integer
right bit-shift by lg(BEACON_FREQ).
In certain operating systems, it might be too complex to maintain
acks_in_round. In others it might be possible by tagging each data
segment in the retransmit buffer with the number of ACKs sent at the
point that segment was sent. This would not work well if the Data
Receiver was not sending data itself, in which case it might be
necessary to beacon based on time instead, as follows:
This time-based approach does not work well when all the ACKs are
sent early in each round trip, as is the case during slow-start. In
this case few options will be sent (evtl. even less than 3 per RTT).
However, when continuously sending data, data packets as well as ACKs
will spread out equally over the RTT and sufficient ACKs with the
AccECN option will be sent.
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. Note that, because
r.e0b is initialized to 1 and the other two counters are initialized
to 0, the initial sum will be 1, which matches the initial offset of
the TCP sequence number on completion of the 3WHS.
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 marks retransmitted segments as Not-ECT. However, the
converse is not true; necessary transmissions will result in
under-counting.
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 out-dated
attempt to clear, or bleach, what used to be the ToS field). To detect
bleaching it will be sufficient to detect whether nearly all bytes
arrive marked as Not-ECT. Therefore there should be no need to keep
track of the details of retransmissions.

```
```

```
```