RFC 2018
CURRENTTCP Selective Acknowledgment Options
M. Mathis, J. Mahdavi, S. Floyd, A. Romanow · October 1996 · original status: Proposed Standard · current status: Proposed Standard (current)
Current and universally deployed — SACK never needed replacing. RFC 2883 added duplicate-SACK reporting and RFC 6675 the modern SACK-based recovery algorithm on top of it.
This module teaches CURRENT behaviour
This document
- RFC 2018 §2 — SACK-Permitted option (kind 4, SYN-only)
- RFC 2018 §3 — SACK option format (kind 5, left/right edges)
- RFC 2018 §4 — data receiver behaviour
- RFC 2018 §5 — data sender behaviour
Where the current rules live
- RFC 2018 (still the definition); RFC 6675 builds the loss-recovery algorithm on it
Selective Acknowledgement (SACK)
New to these ideas? Switch to the beginner level for a from-zero concept primer.
The problem this document answered
The cumulative ACK is a single boundary; it cannot describe holes. With one loss per window, duplicate ACKs plus fast retransmit cope well. With multiple losses the sender is blind past the first gap: it either goes back N (wasting the network) or waits for repeated RTOs (wasting time). SACK blocks report up to four received ranges beyond the cumulative point, making targeted repair possible.
Historical context
Proposed in RFC 1072 (1988) alongside window scaling, then removed from RFC 1323 because the design wasn't settled. RFC 2018 (October 1996, Mathis/Mahdavi/Floyd/Romanow) got it right and it has never needed replacing — the loss-recovery half of the story that began with Jacobson's 1988 congestion work.
Current practice
Current and effectively universal: nearly every SYN offers SACK-Permitted. RFC 2883 added D-SACK (reporting duplicate arrivals, which reveals spurious retransmissions) and RFC 6675 specifies the modern conservative loss-recovery algorithm built on SACK information.
Interactive laboratory
Watch it on the wire
Eight segments; two non-adjacent ones vanish. The receiver can only repeat one number — 'I still need byte X' — so the sender resends far more than was lost.
Identical losses, but SACK-Permitted was negotiated: the receiver now reports exactly which ranges arrived, and the sender retransmits only the two missing segments.
Compare correct vs historic / naive behaviour
Common misconceptions
- ✗“SACK replaces the cumulative ACK” — it never does. Blocks are extra detail on an ordinary ACK; the cumulative number still governs what is irrevocably delivered.
- ✗“A SACKed range is guaranteed delivered” — no. Receivers may renege (drop buffered out-of-order data) under memory pressure, which is exactly why the sender keeps the data until the CUMULATIVE ack passes it.
- ✗“SACK prevents loss” — it changes only how efficiently loss is REPAIRED; the packets still vanish.
- ✗“With SACK you can retransmit everything the receiver hasn't SACKed” — data above the highest SACKed byte may still be in flight; treating it as lost recreates the waste SACK was invented to remove.
- ✗“Offering SACK-Permitted is enough” — both SYNs must carry it, exactly like window scaling.
Glossary terms used here
Knowledge check
1/4 · In the no-SACK trace, segments 2 and 6 are lost. Why can the receiver's ACKs not simply say so?
2/4 · A SACK block reads left=439044022, right=439048402. What exactly does it assert?
3/4 · The sender has SACKed ranges up to byte 12000 and unacknowledged segments starting at 5000, 9000 and 15000. Which does a correct SACK sender retransmit?
4/4 · Why must a sender keep its copy of data that has been SACKed but not cumulatively acknowledged?