Sunday, October 26, 2025

💾 Don't Resend Everything! Understanding TCP Selective Acknowledgment (SACK)

Have you ever wondered what happens when a single packet gets lost during a large file transfer? Before modern TCP features, losing just one packet could slow things down dramatically. Thankfully, TCP Selective Acknowledgment (SACK) saves the day.

SACK is a crucial extension to the standard TCP protocol that dramatically improves performance, especially on networks with high latency and significant packet loss.

The Problem: Head-of-Line Blocking in Classic TCP

Before SACK, TCP relied on a basic cumulative acknowledgment (ACK) system. The receiver would send an ACK number indicating the sequence number of the next expected byte.

Consider a scenario where a sender transmits packets 1, 2, 3, 4, and 5, but Packet 3 is lost in transit.

  • The receiver successfully gets 1 and 2, and sends an ACK for 3 (saying "I expect byte X").
  • The receiver then receives 4 and 5, but since it's waiting for 3, it keeps sending Duplicate ACKs for 3.
  • The sender must wait for its Retransmission Timeout (RTO) or receive three Duplicate ACKs (triggering Fast Retransmit). When it retransmits, it often has to resend Packet 3 and all subsequent packets (4 and 5), because it doesn't know for sure that 4 and 5 were received.


This wasteful process, where correctly received data (4 and 5) is delayed behind the lost packet (3), is known as Head-of-Line (HOL) Blocking. 

The Solution: Selective Acknowledgment (SACK)

SACK, defined in RFC 2018, allows the TCP receiver to efficiently communicate to the sender exactly which segments of data it has received and buffered out-of-order. This prevents unnecessary retransmissions.

💡 Key Components of SACK

SACK data is included as a TCP Option inside the standard ACK packet. It contains one or more SACK Blocks, each defined by two critical values:

  • SLE (SACK Left Edge): The starting sequence number (first byte) of a contiguous block of successfully received, out-of-order data.
  • SRE (SACK Right Edge): The ending sequence number (one byte past the last byte) of that same contiguous block.

SACK in Action (Back to the Lost Packet 3)

  • Packet 3 is Lost. Packets 4 and 5 arrive out-of-order at the receiver.
  • The receiver sends a Duplicate ACK for Packet 3 (still requesting the missing byte X).
  • Critically, this Duplicate ACK now includes the SACK Option:
    • SACK Block: SLE=(Start of Packet 4),SRE=(End of Packet 5+1)
  • The sender reads the SACK Option and realizes: "The receiver is waiting for Packet 3, but already has everything from Packet 4 to 5."
  • The sender only retransmits the single, missing Packet 3.
  • Once Packet 3 arrives, the receiver reassembles the data stream (1, 2, 3, 4, 5) and sends a cumulative ACK for all data up to the end of Packet 5.
  • This process drastically reduces redundant data transmission, which is especially beneficial for high-speed connections that can sustain greater levels of out-of-order delivery. 

SACK in Your Wireshark Trace

When analyzing a packet capture (like a Wireshark trace), the presence of SLE and SRE is a clear sign that SACK is at work, actively mitigating packet loss.

If you expand the TCP layer of a packet labeled [TCP Dup ACK] and look at the Options field, you'll see the SACK Blocks. Multiple SACK blocks (multiple SLE/SRE pairs) indicate that the network experienced several non-contiguous sections of lost data.

The Role of SACK is to turn an expensive error recovery process into an efficient, targeted one. It's one of the cornerstones of modern, high-performance internet networking. 

  • Allows the receiver to inform the sender which segments were successfully received, even if some were lost.
  • Without SACK, TCP can only acknowledge the highest contiguous sequence number, leading to unnecessary retransmissions.
  • Option flag in SYN/SYN-ACK: SACK Permitted = 1 → OS supports selective acknowledgment.

SACK (Selective Acknowledgment) is a TCP feature that allows the receiver to inform the sender exactly which pieces of data (segments) have arrived successfully, even when some in between were lost.

It improves efficiency during packet loss — especially on high-latency or high-bandwidth networks — by avoiding retransmission of data that was already received.

  • Without SACK (Classic TCP)

    TCP uses a cumulative acknowledgment (ACK):

    • ACK number = “I’ve received all bytes up to this sequence number minus 1.”
    • If packet #3 is lost but #4 and #5 arrive, the receiver cannot say “I got 4 and 5”.
    • It must keep re-ACKing “I got up to #2” → causing duplicate ACKs → sender retransmits #3, #4, #5 unnecessarily.

            Result → Wasted bandwidth and slower recovery.

  • With SACK Enabled

    The receiver can now send a SACK block inside the ACK, like:

          

    • This tells the sender: “I got segments 3000–3500 and 4000–4500, but I’m missing 2000–3000.”
    • The sender only retransmits the missing part.

Negotiation: “SACK Permitted” Option

  • Appears only in SYN and SYN-ACK packets during connection setup.
  • Option Kind = 4, Length = 2  [04][02]
  • It doesn’t enable SACK by itself — it signals that both sides support it.
  • Once both ends advertise SACK Permitted, subsequent ACKs can carry SACK blocks. 

Scenario

Without SACK

With SACK

1 packet lost among 10

Retransmit all after loss

Retransmit only the missing one

Efficiency

Low

High

Throughput recovery

Slow

Fast

Bandwidth use

Wasteful

Optimal


 

The information about SLE and SRE is contained within the TCP Options field of a packet that has the ACK flag set, specifically in a Selective ACK (SACK) option.

  • Look at the "Info" Column: Your trace contains many packets with [TCP Dup ACK] and [TCP Fast Retransmission]. These are classic indicators of packet loss and the use of SACK.
    • Frame 52335 to Frame 52342 (and others) are Duplicate ACKs. These are the packets where the receiver is telling the sender that a packet is missing, but it has received later data. This is where the SACK option (containing SLE and SRE) would be found.
  • Inspect a Duplicate ACK Packet: If you were to click on one of the [TCP Dup ACK] packets (e.g., Frame 52336 or 52340) and look in the Packet Details pane:
    • You would expand the Transmission Control Protocol layer.
    • You would find and expand the Options section.
    • Inside the Options, you would see the Selective Acknowledgment (SACK) option.
    • The SACK option is where the one or more SACK Block(s) are listed, each consisting of an SLE and an SRE. 

The meaning in your trace is:

The numerous [TCP Dup ACK] entries indicate that the receiver (50.194.69.74) is trying to tell the sender (192.168.1.48) that certain data segments are missing, but it has successfully received data that came after the missing segment. The SLE and SRE values in those acknowledgments precisely mark the boundaries of the received, out-of-order data blocks. The subsequent [TCP Fast Retransmission] packets (e.g., Frame 52335, 52341, 52344) are the sender re-transmitting the segment that was reported missing by the Duplicate ACKs and SACK blocks

SACK Count: The line [TCP SACK Count: 3] confirms that the receiver has three separate, non-contiguous blocks of data that arrived out of order.

The Gaps: The missing data that the sender needs to retransmit is located in the sequence number ranges that are not covered by the main cumulative acknowledgment number (which is not in this snippet) and these three SACK blocks.

Packet Loss: The presence of multiple SACK blocks indicates significant packet loss or reordering in the network path, forcing the TCP session to use this advanced recovery mechanism. The sender will use these SACK blocks to know precisely which segments not to resend 

 
SACK BlockLeft Edge (SLE) (relative)Right Edge (SRE) (relative)
Block 121800142181382
Block 221198222178646
Block 320637342117086

No comments:

Post a Comment