原文链接:http://packetlife.net/blog/2010/jun/17/tcp-selective-acknowledgments-sack/
TCP Selective Acknowledgments (SACK)
Bystretch|Thursday, June 17, 2010 at 2:34 a.m. UTCLast week, we examinedhowTCP uses sequence and acknowledgmentnumbersto keep track of data in bidirectionaltransit between two end hosts. However, we observed only an idealTCP stream, where all packets are delivered to either endsuccessfully, and in order. What happens if one goes missing?
Thediagram below illustrates a TCP connection taking place between aclient and server separated by a network. Time progressesvertically from top to bottom as packets are sent.
Theclient sends some request to the server, and the server formulatesa response broken into four TCP segments (packets). The servertransmits all four packets in response to the request. However, thesecond response packet is dropped somewhere on the network andnever reaches the host. Let's walk through what happens.
Step1
Response segment #2 is lost.
Step2
Theclient receives segment #3. Upon examining the segment's sequencenumber, the client realizes this segment is out of order; there isdata missing between the last segment received and this one. Theclient transmits a duplicate acknowledgment for packet #1 to alertthe server that it has not received any (reliable) data beyondpacket #1.
Step3
Asthe server is not yet aware that anything is wrong (because it hasnot yet received the client's duplicate acknowledgment), itcontinues by sending segment #4. The client realizes that it isstill missing data, and repeats its behavior in step three bysending another duplicate acknowledgment for packet #1.
Step4
Theserver receives the client's first duplicate acknowledgment forpacket #1. Because the client has only confirmed receipt of thefirst of the four segments, the server must retransmit all threeremaining segments in the response.
Thesecond duplicate acknowledgment received from the client isignored.
Step5
Theclient successfully receives and acknowledges the three remainingsegments.
Enter Selective Acknowledgments
You've probably noticed that this design is inefficient: althoughonly packet #2 was lost, the server was required to retransmitpackets #3 and #4 as well, because the client had no way to confirmthat it had received those packets.
This problem was originally addressed by RFC 1072, and morerecently byRFC2018, by introducing theselectiveacknowledgment(SACK) TCP option. SACKs workby appending to a duplicate acknowledgment packet a TCP optioncontaining a range of noncontiguous data received. In other words,it allows the client to say "I only have up to packet #1 in order,but I also have received packets #3 and #4". This allows the serverto retransmit only the packet(s) that were not received by theclient.
Support for SACK is negotiated at the beginning of a TCPconnection; if both hosts support it, it may be used. Let's look athow our earlier example plays out with SACK enabled:
Step1
Response segment #2 is lost.
Step2
Theclient realizes it is missing a segment between segments #1 and #3.It sends a duplicate acknowledgment for segment #1, and attaches aSACK option indicating that it has received segment #3.
Step3
Theclient receives segment #4 and sends another duplicateacknowledgment for segment #1, but this time expands the SACKoption to show that it has received segments #3 through #4.
Step4
Theserver receives the client's duplicate ACK for segment #1 and SACKfor segment #3 (both in the same TCP packet). From this, the serverdeduces that the client is missing segment #2, so segment #2 isretransmitted. The next SACK received by the server indicates thatthe client has also received segment #4 successfully, so no moresegments need to be transmitted.
Step 5
Theclient receives segment #2 and sends an acknowledgment to indicatethat it has received all data up to an including segment #4.
Enough Theory, Here's a Capture
This packet capturecontains a demonstrationof SACKs in action. We know that both end hosts support selectiveacknowledgments by the presence of theSACKpermittedoption in the two SYN packets, #1and #2.
Toward the end of the capture, we can see that packet #30 wasreceived out of order, and the client has sent a duplicateacknowledgment in packet #31. This packet includes a SACK optionindicating that the segment in packet #30 was received.
Ofcourse, the SACK option cannot simply specify which segment(s) werereceived. Rather, it specifies the left and right edges of datathat has been received beyond the packet's acknowledgment number. Asingle SACK option can specify multiple noncontiguous blocks ofdata (e.g. bytes 200-299 and 400-499).
Wecan see this duplicate acknowledgment repeated in packets #33, #35,and #37. In each, the SACK is expanded to include the noncontiguoussegments the server has continued sending. Finally, the serverretransmits the missing segment in packet #38, and the clientupdates its acknowledgment number appropriately in packet #39.
About the Author
Jeremy Stretch is a networking engineer and the maintainer ofPacketLife.net. He currently lives in the Raleigh-Durham metro areain North Carolina. Although primarily an R&S guy, he likes toget into everything, and runs afreenetwork training labout of his basement forfun. You can contact him byemailorfollow him onTwitter.