Example
The first line of Figure 14-7 (number 40) indicates the first time ACK 23801 is received
The window update at time 0.853 is an ACK with a duplicate sequence number (because no data is being carried) but contains a change to the TCP flow control window.
Thus, it is not counted toward the three-duplicate-ACK threshold required to initiate a fast retransmit.
The packets arriving at times 0.890, 0.926, and 0.964 are all duplicate ACKs for sequence number 23801.
The arrival of the third of these duplicate ACKs triggers the fast retransmit of segment 23801 at time 0.993.
The second retransmission(at 1.326s) is somewhat different from the first.
When the first retransmission takes place, the sending TCP notes the highest sequence num- ber it had sent just before it performed the retransmission
(43401 + 1400 = 44801). This is called the recovery point.
TCP is considered to be recovering from loss after a retransmission until it receives an ACK that matches or exceeds the sequence number of the recovery point.
In this example, the ACKs at times 1.322 and 1.321 are not for 44801, but instead for 26601.
This number is larger than the previous highest ACK value seen (23801), but not enough to meet or exceed the recovery point (44801).
This type of ACK is called a partial ACK for this reason.
When par- tial ACKs arrive, the sending TCP immediately sends the segment that appears to be missing (26601 in this case) and
continues this way until the recovery point is matched or exceeded by an arriving ACK.
If permitted by congestion control pro- cedures (see Chapter 16), it may also send new data it has not yet sent.
Retransmission with Selective Acknowledgments
Data with sequence numbers beyond the holes are called out-of-sequence data because that data is not contiguous,
in terms of its sequence numbers, with the other data the receiver has already received.
In many circumstances, the properly operating SACK sender is able to fill these holes more quickly and with fewer unnecessary retransmissions than
a comparable non-SACK sender because it does not have to wait an entire RTT to learn about additional holes.
With three distinct blocks, up to three holes can be reported to the sender.
If not limited by congestion control (see Chapter 16), all three could be filled within one round-trip time using a SACK-capable sender.
SACK Receiver Behavior
The receiver places in the first SACK block the sequence number range con- tained in the segment it has most recently received.
Because the space in a SACK option is limited, it is best to ensure that the most recent information is always provided to the sending TCP, if possible.
Other SACK blocks are listed in the order in which they appeared as first blocks in previous SACK options.
That is, they are filled in by repeating the most recently sent SACK blocks (in other segments) that are not subsets of another block about to be placed in the option being constructed.
The purpose of including more than one SACK block in a SACK option and repeating these blocks across multiple SACKs is to provide some redundancy in the case where SACKs are lost.
...Unfortunately, SACKs and regular ACKs are sometimes lost and are not retrans- mitted by TCP unless they contain data (or the SYN or FIN control bit fields are turned on).
SACK Sender Behavior
One way it can do this is to keep a “SACKed” indication for each segment in its retransmission buffer
that is set whenever a corresponding range of sequence numbers arrives in a SACK.
The simplest approach is to have the sender first fill the holes at the receiver and then move on to send more new data [RFC3517]
if the congestion control pro- cedures allow. This is the most common approach.
There is one exception to this behavior.
In [RFC2018], the current specification for SACK options, SACK blocks are considered advisory.
This means that a receiver could provide a SACK to the sender indicating that some sequence numbers have been received successfully and then change its mind later (“renege”).
Because of this, the SACK sender is not able to free its retransmission buffer of data it has received only a SACK for;
it is permitted to free a block of data only once the regu- lar TCP ACK number of the receiver has passed by the highest sequence number of this data.
Example
These options(SACK-Permitted option)are present only at connection setup, and thus they only ever appear in segments with the SYN bit field set.
Here we see that the ACK for 23801 contains a SACK block of [25201,26601](this is the out-of-order block), indicating a hole at the receiver.
The receiver is missing the sequence number range [23801,25200], which corresponds to the single 1400-byte packet starting with sequence number 23801.
Note that this SACK is a window update and is not counted as a duplicate ACK for the reasons discussed earlier(?).
It does not trigger fast retransmit.
The SACK arriving at time 0.967 contains two SACK blocks: [28001,29401] and [25201,26601].
Recall that the first SACK blocks from previous SACKs are repeated in later positions in subsequent SACKs for robustness against ACK loss.
This SACK is a duplicate ACK for sequence number 23801 and suggests that the receiver now requires two full-size segments starting with sequence numbers 23801 and 26601.
The sender reacts immediately by initiating fast retransmit, but because of conges- tion control procedures (see Chapter 16), the sender sends only one retransmis- sion, for segment 23801.
With the arrival of two additional ACKs, the sender is permitted to send its second retransmission, for segment 26601.
A TCP SACK sender uses the recovery point idea introduced with NewReno.
In this example, the highest sequence number sent prior to the retransmission is 43400, which is lower than in the NewReno example from Figure 14-5.
For this implementation of SACK fast retransmit, three duplicate ACKs are not required;
the TCP initiates its retransmission earlier. The recovery exit is essentially the same, though.
Once the ACK for sequence number 43401 is received at time 1.3958, recovery is complete.
The benefits of SACKs are more pronounced when the RTT is large and packet loss is severe.
Under such circumstances, the benefits of being able to fill more than one hole per RTT are likely to be more significant.