You are on page 1of 8

SACK

Have you ever been in the middle of a phone conversation when, suddenly, there is a loss of
signal and you can’t hear the person on the other end? What do you do next? Tell the speaker
the start and end of the part of the conversation that you didn’t hear?

Well, computers communicate the same way with a TCP acknowledgement option called
Selective Acknowledgement.

TCP protocol utilizes retransmissions when packets are lost or damaged. The original TCP
acknowledgement system can’t handle multiple segments that are lost; it only acknowledges the
last successfully received segment (before the loss), which then leads to the retransmission of
data that has been already received by the receiver. This is obviously unnecessary, as it is a
waste of time and causes network congestion that could’ve easily been avoided. This is where
Selective Acknowledgment, or SACK, is most beneficial.

Here is where Selective Acknowledgment, or SACK, is most beneficial.

SACK is the method of resending only the necessary packets that never reached the receiver. In
return, this improves the network’s performance, as fewer packets being retransmitted means a
more efficient use of bandwidth. This is especially noticeable for connections using large TCP
window sizes.

Without SACK, in the case of packet loss, the receiver would send a Duplicate
Acknowledgment (DUP ACK) saying that it has only received data up to a specific segment. The
sender would then resend all of the following segments of data, even if the receiver already
received most of them. This would cause the receiver to get duplicates of some of the data,
which is a waste of resources.

There are two types of SACK options. The first, the SACK-Permitted Option, is only present in
the SYN packet and informs the both sides of the connection that it can receive the SACK option,
which is a part of the initial connection.

Below is a graphic representation of SACK-permitted Option from RFC 2018; this shows the TCP
kind and length that is relative to SACK that is sent during initial connection.

The second type of SACK is the Option format. This is when the receiver gives the sender
detailed knowledge of which data has been received, which in return allows the sender to
retransmit the missing pieces of data. This will be sent when there is lost data during a packet
transfer.
Here we see a graphic representation of the Option format from RFC
Now take a look at this step-by-step explanation of the SACK process.

Step 1
Sender sends 10 segments of data, each containing 100 bytes of data, to a receiver starting with
a sequence number of 1000.

Step 2
The receiver receives segments 1 through 4 and 6 through 10.

Step 3
The receiver then realizes that it is missing some data and sends a TCP ACK segment back to
the sender, with a SACK option specifying a left edge of 1400 and a right edge of 1500.

Step 4
The sender then retransmits the 5th segment back to the receiver all by itself.

Step 5
The receiver receives the 5th segment and sends an acknowledgement packet to the sender
informing them that they have now received all of the segments.

Now, let’s dig deeper into the concept of SACK with a real world example captured by Wireshark.
Here’s an example of a SYN Packet showing the SACK Permitted Option with a Kind of 4 and a
Length of 2. See the last two lines of the capture below.
This shows that my computer, the source, was letting the server, the destination host, know that
it has SACK enabled. Therefore, the server knows that the source can ask for specific segments
of data. If the server support SACK, it needs to include the SACK Permitted Option in the SYN-
ACK.

Now, here’s a later packet from the source (computer) showing an actual SACK option with the
left edge of the block of data not received specified as 18225, and the right edge of the block of
data not received specified as 18620. See the last section of lines in the capture below:

As you can see, that informs the destination host of the specific bytes of data that were lost. With
SACK, the server now knows that it only has to resend the sequence numbers 18225 to 18620,
which saved time and resources as a result.

Some problems have arrived since the early adaptation of SACK. For example, it’s possible for a
receiver to receive packets out of order due to some unknown network connectivity problems.
This would result in the sender retransmitting the skipped packet out, which will slow down the
rate of data delivery.

Since then, there has been an extension implemented to SACK which has introduced duplicate
selective acknowledgment, or D-SACK, in RFC 2883. Some of these improvements include
proper reporting of duplicate and/or out-of-order segments. This allows the sender to figure out
the order of packets received by the receiver and in return understand when it has retransmitted
an unnecessary packet.

Unfortunately, the SACK option is not mandatory and is only used when both ends of the TCP
connection support it. Luckily, all major recent TCP stacks now support it.

SACK is important because it allows for a more robust packet retransmission, allowing the
sender to be notified of what pieces of data made it to the receiver when there is packet loss and
the retransmission of duplicate packets with D-SACK. This promotes less network congestion
and better handling of packets, thus allowing a faster rate of data deliver
Path MTU Discovery
When a host needs to transmit data out an interface, it references the interface's Maximum Transmission
Unit (MTU) to determine how much data it can put into each packet. Ethernet interfaces, for example,
have a default MTU of 1500 bytes, not including the Ethernet header or trailer. This means a host
needing to send a TCP data stream would typically use the first 20 of these 1500 bytes for the IP header,
the next 20 for the TCP header, and as much of the remaining 1460 bytes as necessary for the data
payload. Encapsulating data in maximum-size packets like this allows for the least possible consumption
of bandwidth by protocol overhead.

Unfortunately, not all links which compose the Internet have the same MTU. The MTU offered by a link
may vary depending on the physical media type or configured encapsulation (such as GRE tunneling or
IPsec encryption). When a router decides to forward an IPv4 packet out an interface, but determines that
the packet size exceeds the interface's MTU, the router must fragment the packet to transmit it as two (or
more) individual pieces, each within the link MTU. Fragmentation is expensive both in router resources
and in bandwidth utilization; new headers must be generated and attached to each fragment. (In fact, the
IPv6 specification removes transit packet fragmentation from router operation entirely, but this
discussion will be left for another time.)

To utilize a path in the most efficient manner possible, hosts must find the path MTU; this is the smallest
MTU of any link in the path to the distant end. For example, for two hosts communicating across three
routed links with independent MTUs of 1500, 800, and 1200 bytes, the smallest (800 bytes) must be
assumed by each end host to avoid fragmentation.
Of course, it's impossible to know the MTU of each link through which a packet might travel. RFC
1191 defines path MTU discovery, a simple process through which a host can detect a path MTU smaller
than its interface MTU. Two components are key to this process: the Don't Fragment (DF) bit of the IP
header, and a subcode of the ICMP Destination Unreachable message, Fragmentation Needed.

Setting the DF bit in an IP packet prevents a router from performing fragmentation when it encounters an
MTU less than the packet size. Instead, the packet is discarded and an ICMP Fragmentation Needed
message is sent to the originating host. Essentially, the router is indicating that it needs to fragment the
packet but the DF flag won't allow for it. Conveniently, RFC 1191 expands the Fragmentation Needed
message to include the MTU of the link necessitating fragmentation. A Fragmentation Needed message
can be seen in packet #6 of this packet capture.
Now that the actual path MTU has been learned, the host can cache this value and packetize future data
for the destination to the appropriate size. Note that path MTU discovery is an ongoing process; the host
continues to set the DF flag so that it can detect further decreases in MTU should dynamic routing
influence a new path to the destination. RFC 1191 also allows for periodic testing for an increased path
MTU, by occasionally attempting to pass a packet larger than the learned MTU. If the packet succeeds,
the path MTU will be raised to this higher value.

You can test path MTU discovery across a live network with a tool like tracepath (part of the Linux IPutils
package) or mturoute (Windows only). Here's a sample of tracepath output from the lab pictured above,
with the MTU of F0/1 reduced to 1400 bytes using the ip mtu command:

Host$ tracepath -n 192.168.1.2

1: 192.168.0.2 0.097ms pmtu 1500

1: 192.168.0.1 0.535ms

1: 192.168.0.1 0.355ms

2: 192.168.0.1 0.430ms pmtu 1400

2: 192.168.1.2 0.763ms reached

Resume: pmtu 1400 hops 2 back 254

You might also like