What does selective acknowledgment add on top of cumulative ACKs?
Show the answer
Say this first
A cumulative ACK only says "everything up to here". With several losses in one window the sender learns about one hole per round trip. SACK (RFC 2018), agreed with SACK-permitted in the handshake, lets the receiver list up to three or four blocks of data it holds beyond the hole. The sender resends only the gaps and can repair several losses in about one RTT.
Go deeper
What it looks like
10.2.20.30.5201 > 10.1.10.20.51544: Flags [.], ack 1001, win 501, options [nop,nop,TS val 2154883120 ecr 1209364471,nop,nop,sack 1 {2461:5381}], length 0The receiver has everything up to byte 1000 and also bytes 2461 to 5380. Bytes 1001 to 2460, one 1,460-byte segment, are missing.
Details that come up
- SACK blocks are advisory. The receiver may discard SACKed data, so the sender keeps it until it is cumulatively acknowledged.
- D-SACK (RFC 2883) reports data received twice, which lets the sender detect spurious retransmissions.
- Any device that rewrites sequence numbers, for example a firewall that randomises ISNs, must rewrite SACK edges as well. When one did not, SACK-based recovery stalled.
They will ask next
Why only three or four blocks?
TCP options are limited to 40 bytes. Each block is 8 bytes plus 2 for the option header, so 4 blocks fit, or 3 when the timestamp option takes its 12 bytes.
Is SACK enabled by default?
On every mainstream OS, yes. On Linux it is
net.ipv4.tcp_sack=1. It is only used when both sides offer SACK-permitted in the handshake.
Traps
- Thinking a SACKed segment can be forgotten by the sender. Only the cumulative ACK releases data.