| ECN flags | Value | IRREGULAR | UNKNOWN |
| CWR flag | Value | IRREGULAR | UNKNOWN |
| ECE flag | Value | IRREGULAR | UNKNOWN |
| URG flag | Value | IRREGULAR | UNKNOWN |
| ACK flag | Value | SEMISTATIC | KNOWN |
| PSH flag | Value | IRREGULAR | UNKNOWN |
| RST flag | Value | IRREGULAR | UNKNOWN |
| SYN flag | Value | SEMISTATIC | KNOWN |
| FIN flag | Value | SEMISTATIC | KNOWN |
+------------------------+-------------+-------------+-------------+
| TCP Window | Value | ALTERNATING | KNOWN |
+------------------------+-------------+-------------+-------------+
| TCP Checksum | Value | IRREGULAR | UNKNOWN |
+------------------------+-------------+-------------+-------------+
| TCP Urgent Pointer | Value | IRREGULAR | KNOWN |
+------------------------+-------------+-------------+-------------+
| TCP Options | Value | IRREGULAR | UNKNOWN |
+------------------------+-------------+-------------+-------------+
Figure 11. Classification of CHANGING Fields
The following subsections discuss the various header fields in
detail. Note that Table 1 and the discussion below do not consider
changes caused by loss or reordering before the compression point.
4.1. IP Header
4.1.1. IP Traffic-Class / Type-Of-Service (TOS)
The Traffic-Class (IPv6) or Type-Of-Service/DSCP (IPv4) field might
be expected to change during the lifetime of a packet stream. This
analysis considers several RFCs that describe modifications to the
original RFC 791 [1].
The TOS byte was initially described in RFC 791 [1] as 3 bits of
precedence followed by 3 bits of TOS and 2 reserved bits (defined to
be zero). RFC 1122 [21] extended this to specify 5 bits of TOS,
although the meanings of the additional 2 bits were not defined. RFC
1349 [23] defined the 4th bit of TOS as ’minimize monetary cost’.
The next significant change was in RFC 2474 [14] (obsoleting RFC 1349
[23]). RFC 2474 reworked the TOS octet as 6 bits of DSCP (DiffServ
Code Point) plus 2 unused bits. Most recently, RFC 2780 [30]
identified the 2 reserved bits in the TOS or traffic class octet for
experimental use with ECN.
It is therefore proposed that the TOS (or traffic class) octet be
classified as 6 bits for the DSCP and 2 additional bits. These 2
bits may be expected to be zero or to contain ECN data. From a
future-proofing perspective, it is preferable to assume the use of
ECN, especially with respect to TCP.
It is also considered important that the profile work with legacy
stacks, since these will be in existence for some considerable time
to come. For simplicity, this will be considered as 6 bits of TOS
information and 2 bits of ECN data, so the fields are always
considered to be structured the same way.
The DSCP (as for TOS in ROHC RTP) is not expected to change
frequently (although it could change mid-flow, for example, as a
result of a route change).
4.1.2. ECN Flags
Initially, we describe the ECN flags as specified in RFC 2481 [15]
and RFC 3168 [18]. Subsequently, a suggested update is described
that would alter the behavior of the flags.
In RFC 2481 [15] there are 2 separate flags, the ECT (ECN Capable
Transport) flag and the CE (Congestion Experienced) flag. The ECT
flag, if negotiated by the TCP stack, will be ’1’ for all data
packets and ’0’ for all ’pure acknowledgement’ packets. This means
that the behavior of the ECT flag is linked to behavior in the TCP
stack. Whether this can be exploited for compression is not clear.
The CE flag is only used if ECT is set to ’1’. It is set to ’0’ by
the sender and can be set to ’1’ by an ECN-capable router in the
network to indicate congestion. Thus the CE flag is expected to be
randomly set to ’1’ with a probability dependent on the congestion
state of the network and the position of the compressor in the path.
Therefore, a compressor located close to the receiver in a congested
network will see the CE bit set frequently, but a compressor located
close to a sender will rarely, if ever, see the CE bit set to ’1’.
A recent experimental proposal [19] suggests an alternative view of
these 2 bits. This considers the two bits together to have 4
possible codepoints. Meanings are then assigned to the codepoints:
00 Not ECN capable
01 ECN capable, no congestion (known as ECT(0))
10 ECN capable, no congestion (known as ECT(1))
11 Congestion experienced
The use of 2 codepoints for signaling ECT allows the sender to detect
when a receiver is not reliably echoing congestion information.
For the purposes of compression, this update means that ECT(0) and
ECT(1) are equally likely (for an ECN capable flow) and that ’11’
will be seen relatively rarely. The probability of seeing a
congestion indication is discussed above in the description of the CE
flag.
It is suggested that, for the purposes of compression, ECN with
nonces be assumed as the baseline, although the compression scheme
must be able to compress the original ECN scheme transparently.
4.1.3. IP Identification
The Identification field (IP ID) of the IPv4 header identifies which
fragments constitute a datagram, when fragmented datagrams are
reassembled. The IPv4 specification does not specify exactly how
this field is to be assigned values, only that each packet should get
an IP ID that is unique for the source-destination pair and protocol
for the time during which the datagram (or any of its fragments)
could be alive in the network. This means that assignment of IP ID
values can be done in various ways, which we have separated into
three classes:
o Sequential jump
This is the most common assignment policy in today’s IP stacks. A
single IP ID counter is used for all packet streams. When the
sender is running more than one packet stream simultaneously, the
IP ID can increase by more than one between packets in a stream.
The IP ID values will be much more predictable and will require
fewer bits to transfer than random values, and the packet-to-
packet increment (determined by the number of active outgoing
packet streams and sending frequencies) will usually be limited.
o Random
Some IP stacks assign IP ID values by using a pseudo-random number
generator. There is thus no correlation between the ID values of
subsequent datagrams. Therefore, there is no way to predict the
IP ID value for the next datagram. For header compression
purposes, this means that the IP ID field needs to be sent
uncompressed with each datagram, resulting in two extra octets of
header. IP stacks in cellular terminals that need optimum header
compression efficiency should not use this IP ID assignment
policy.
o Sequential
This assignment policy keeps a separate counter for each outgoing
packet stream, and thus the IP ID value will increment by one for
each packet in the stream, except at wrap around. Therefore, the
delta value of the field is constant and well known a priori.
This assignment policy is the most desirable for header
compression purposes. However, its usage is not as common as it
perhaps should be.
In order to avoid violating RFC 791 [1], packets sharing the same
IP address pair and IP protocol number cannot use the same IP ID
values. Therefore, implementations of sequential policies must
make the ID number spaces disjoint for packet streams of the same
IP protocol going between the same pair of nodes. This can be
done in a number of ways, all of which introduce occasional jumps
and thus make the policy less than perfectly sequential. For
header compression purposes, less frequent jumps are preferred.
Note that the ID is an IPv4 mechanism and is therefore not a problem
for IPv6. For IPv4, the ID could be handled in three different ways.
First, we have the inefficient but reliable solution where the ID
field is sent as-is in all packets, increasing the compressed headers
by two octets. This is the best way to handle the ID field if the
sender uses random assignment of the ID field. Second, there can be
solutions with more flexible mechanisms that require fewer bits for
the ID handling as long as sequential jump assignment is used. Such
solutions will probably require even more bits if random assignment
is used by the sender. Knowledge about the sender’s assignment
policy could therefore be useful when choosing between the two
solutions above. Finally, even for IPv4, header compression could be
designed without any additional information for the ID field included
in compressed headers. To use such schemes, it must be known which
assignment policy for the ID field is being used by the sender. That
might not be possible to know, which implies that the applicability
of such solutions is very uncertain. However, designers of IPv4
stacks for cellular terminals should use an assignment policy close
to sequential.
With regard to TCP compression, the behavior of the IP ID field is
essentially the same. However, in RFC 3095 [31], the IP ID is
generally inferred from the RTP Sequence Number. There is no obvious
candidate in the TCP case for a field to offer this ’master sequence
number’ role.
Clearly, from a busy server, the observed behavior may well be quite
erratic. This is a case where the ability to share the IP
compression context between a number of flows (between the same end-
points) could offer potential benefits. However, this would only
have any real impact where there is a large number of flows between
one machine and the server. If context sharing is being considered,
then it is preferable to share the IP part of the context.
4.1.4. Don’t Fragment (DF) flag
Path-MTU discovery (RFC 1191 for IPv4 [6] and RFC 1981 for IPv6 [11])
is widely deployed for TCP, in contrast to little current use for UDP
packet streams. This employs the DF flag value of ’1’ to detect the
need for fragmentation in the end-to-end path and to probe the
minimum MTU along the network path. End hosts using this technique
may be expected to send all packets with DF set to ’1’, although a
host may end PMTU discovery by clearing the DF bit to ’0’. Thus, for
compression, we expect the field value to be stable.
4.1.5. IP Hop-Limit / Time-To-Live (TTL)
The Hop-Limit (IPv6) or Time-To-Live (IPv4) field is expected to be
constant during the lifetime of a packet stream or to alternate
between a limited number of values due to route changes.
4.2. TCP Header
Any discussion of compressability of TCP fields borrows heavily from
RFC 1144 [22]. However, the premise of how the compression is
performed is slightly different, and the protocol has evolved
slightly in the intervening time.
4.2.1. Sequence Number
Understanding the sequence and acknowledgement number behavior is
essential for a TCP compression scheme.
At the simplest level, the behavior of the sequence number can be
described relatively easily. However, there are a number of
complicating factors that also need to be considered.
For transferring in-sequence data packets, the sequence number will
increment for each packet by between 0 and an upper limit defined by
the MSS (Maximum Segment Size) and, if it is being used, by Path-MTU
discovery.
There are common MSS values, but these can be quite variable and
unpredictable for any given flow. Given this variability and the
range of window sizes, it is hard (compared with the RTP case, for
example) to select a ’one size fits all’ encoding for the sequence
number. (The same argument applies equally to the acknowledgement
number).
Note that the increment of the sequence number in a packet is the
size of the data payload of that packet (including the SYN and FIN
flags). This is, of course, exactly the relationship that RFC 1144
[22] exploits to compress the sequence number in the most efficient
case. This technique may not be directly applicable to a robust
solution, but it may be a useful relationship to consider.
However, at any point on the path (i.e., wherever a compressor might
be deployed), the sequence number can be anywhere within a range
defined by the TCP window. This is a combination of a number of
values (buffer space at the sender; advertised buffer size at the
receiver; and TCP congestion control algorithms). Missing packets or
retransmissions can cause the TCP sequence number to fluctuate within
the limits of this window.
It is desirable to be able to predict the sequence number with some
regularity. However, this also appears to be difficult to do. For
example, during bulk data transfer, the sequence number will tend to
go up by 1 MSS per packet (assuming no packet loss). Higher layer
values have been seen to have an impact as well, where sequence
number behavior has been observed with an 8 kbyte repeating pattern
-- 5 segments of 1460 bytes followed by 1 segment of 892 bytes. The
implementation of TCP and the management of buffers within a protocol
stack can affect the behavior of the sequence number.
It may be possible to track the TCP window by the compressor,
allowing it to bound the size of these jumps.
For interactive flows (for example, telnet), the sequence number will
change by small, irregular amounts. In this case, the Nagle
algorithm [3] commonly applies, coalescing small packets where
possible in order to reduce the basic header overhead. This may also
mean that predictable changes in the sequence number are less likely
to occur. The Nagle algorithm is an optimisation and is not required
to be used (applications can disable its use). However, it is turned
on by default in all common TCP implementations.
Note also that the SYN and FIN flags (which have to be acknowledged)
each consume 1 byte of sequence space.
4.2.2. Acknowledgement Number
Much of the information about the sequence number applies equally to
the acknowledgement number. However, there are some important
differences.
For bulk data transfers, there will tend to be 1 acknowledgement for
every 2 data segments. The algorithm is specified in RFC 2581 [16].
An ACK need not always be sent immediately on receipt of a data
segment, but it must be sent within 500ms and should be generated for
at least every second full-size segment (MSS) of received data. It
may be seen from this that the delta for the acknowledgement number
is roughly twice that of the sequence number. This is not always the
case, and the discussion about sequence number irregularity should be
applied.
As an aside, a common implementation bug is ’stretch ACKs’ [33]
(acknowledgements may be generated less frequently than every two
full-size data segments). This pattern can also occur following loss
on the return path.
Since the acknowledgement number is cumulative, dropped packets in
the forward path will result in the acknowledgement number remaining
constant for a time in the reverse direction. Retransmission of a
dropped segment can then cause a substantial jump in the
acknowledgement number. These jumps in acknowledgement number are
bounded by the TCP window, just as for the jumps in sequence number.
In the acknowledgement case, information about the advertised
received window gives a bound to the size of any ACK jump.
4.2.3. Reserved
This field is reserved, and it therefore might be expected to be
zero. This can no longer be assumed, due to future-proofing. It is
only a matter of time before a suggestion for using the flag is made.
4.2.4. Flags
o ECN-E (Explicit Congestion Notification)
’1’ to echo CE bit in IP header. It will be set in several
consecutive headers (until ’acknowledged’ by CWR). If ECN nonces
are used, then there will be a ’nonce-sum’ (NS) bit in the flags,
as well. Again, transparency of the reserved bits is crucial for
future-proofing this compression scheme. From an
efficiency/compression standpoint, the NS bit will either be
unused (always ’0’) or randomly changing. The nonce sum is the
1-bit sum of the ECT codepoints, as described in [19].
o CWR (Congestion Window Reduced)
’1’ to signal congestion window reduced on ECN. It will generally
be set in individual packets. The flag will be set once per loss
event. Thus, the probability of its being set is proportional to
the degree of congestion in the network, but it is less likely to
be set than the CE flag.
o ECE (Echo Congestion Experience)
If ’congestion experienced’ is signaled in a received IP header,
this is echoed through the ECE bit in segments sent by the
receiver until acknowledged by seeing the CWR bit set. Clearly,
in periods of high congestion and/or long RTT, this flag will
frequently be set to ’1’.
During connection open (SYN and SYN/ACK packets), the ECN bits
have special meaning:
* CWR and ECN-E are both set with SYN to indicate desire to use
ECN.
* CWR only is set in SYN-ACK, to agree to ECN.
(The difference in bit-patterns for the negotiation is such that
it will work with broken stacks that reflect the value of
reserved bits).
o URG (Urgent Flag)
’1’ to indicate urgent data (which is unlikely with any flag other
than ACK).
o ACK (Acknowledgement)
’1’ for all except the initial ’SYN’ packet.
o PSH (Push Function Field)
Generally accepted to be randomly ’0’ or ’1’. However, it may be
biased more to one value than the other (this is largely caused by
the implementation of the stack).
o RST (Reset Connection)
’1’ to reset a connection (unlikely with any flag other than ACK).
o SYN (Synchronize Sequence Number)
’1’ for the SYN/SYN-ACK, only at the start of a connection.
o FIN (End of Data: FINished)
’1’ to indicate ’no more data’ (unlikely with any flag other than
ACK).
4.2.5. Checksum
Carried as the end-to-end check for the TCP data. See RFC 1144 [22]
for a discussion of why this should be carried. A header compression
scheme should not rely upon the TCP checksum for robustness, though,
and should apply appropriate error-detection mechanisms of its own.
The TCP checksum has to be considered to be randomly changing.
4.2.6. Window
This may oscillate randomly between 0 and the receiver’s window limit
(for the connection).
In practice, the window will either not change or alternate between a
relatively small number of values. Particularly when the window is
closing (its value is getting smaller), the change in window is
likely to be related to the segment size, but it is not clear that
this necessarily offers any compression advantage. When the window
is opening, the effect of ’Silly-Window Syndrome’ avoidance should be
remembered. This prevents the window from opening by small amounts
that would encourage the sender to clock out small segments.
When thinking about what fields might change in a sequence of TCP
segments, one should note that the receiver can generate ’window
update’ segments in which only the window advertisement changes.
4.2.7. Urgent Pointer
From a compression point of view, the Urgent Pointer is interesting
because it offers an example where ’semantically identical’
compression is not the same as ’bitwise identical’. This is because
the value of the Urgent Pointer is only valid if the URG flag is set.
However, the TCP checksum must be passed transparently, in order to
maintain its end-to-end integrity checking property. Since the TCP
checksum includes the Urgent Pointer in its coverage, this enforces
bitwise transparency of the Urgent Pointer. Thus, the issue of
’semantic’ vs. ’bitwise’ identity is presented as a note: the Urgent
Pointer must be compressed in a way that preserves its value.
If the URG flag is set, then the Urgent Pointer indicates the end of
the urgent data and thus can point anywhere in the window. It may be
set (and changing) over several segments. Note that urgent data is
rarely used, since it is not a particularly clean way of managing
out-of-band data.
4.3. Options
Options occupy space at the end of the TCP header. All options are
included in the checksum. An option may begin on any byte boundary.
The TCP header must be padded with zeros to make the header length a
multiple of 32 bits.
Optional header fields are identified by an option kind field.
Options 0 and 1 are exactly one octet, which is their kind field.
All other options have their one-octet kind field, followed by a
one-octet length field, followed by length-2 octets of option data.
4.3.1. Options Overview
The IANA provides the authoritative list of TCP options. Figure 12
describes the current allocations at the time of publication. Any
new option would have a ’kind’ value assigned by IANA. The list is
available at [20]. Where applicable, the associated RFC is also
cited.
+----+-------+------------------------------------+----------+-----+
|Kind|Length | Meaning | RFC | Use |
| |octets | | | |
+----+-------+------------------------------------+----------+-----+
| 0 | - | End of Option List | RFC 793 | * |
| 1 | - | No-Operation | RFC 793 | * |
| 2 | 4 | Maximum Segment Size | RFC 793 | * |
| 3 | 3 | WSopt - Window Scale | RFC 1323 | * |
| 4 | 2 | SACK Permitted | RFC 2018 | * |
| 5 | N | SACK | RFC 2018 | * |
| 6 | 6 | Echo (obsoleted by option 8) | RFC 1072 | |
| 7 | 6 | Echo Reply (obsoleted by option 8) | RFC 1072 | |
| 8 | 10 | TSopt - Time Stamp Option | RFC 1323 | * |
| 9 | 2 | Partial Order Connection Permitted | RFC 1693 | |
| 10 | 3 | Partial Order Service Profile | RFC 1693 | |