某天在技术交流群里有群友咨询一个 TCP ACK 问题,说正常三次 ACK 就会快速重传,但是他看到的为什么有的包很多 ACK 而没有进行快速重传。
说实话,第一时间看到此消息的,我觉得是不太可能,甚至说我进一步看到问题图片的时候,一下子我也没反应过来。。。还是之后自己动手研究了原始数据包跟踪文件,才真正搞清楚是怎么一回事。
回到说群友的问题,其实从他的原话和截图上来说,都是带有一定迷惑性的。首先他一直描述的是 ACK,包括图片显示的也确实有很多 Ack=110033 的信息,然后又提到了为什么没有快速重传。
这一个快速重传让我反应过来,截图上没有 DUP ACK?!! !
为啥会没有显示 DUP ACK 呢? 立马想到两个可能,
但随着和这位群友进一步的沟通得知,他的版本已经是当时最新的 Version 3.6.3 了,而且并没有改动任何特殊的配置。那么只有自己动手下载该数据包跟踪文件,亲自验证下了。
数据包跟踪文件基本信息如下:
λ capinfos scp_client_stream1.pcap
File name: scp_client_stream1.pcap
File type: Wireshark/tcpdump/... - pcap
File encapsulation: Ethernet
File timestamp precision: microseconds (6)
Packet size limit: file hdr: 65535 bytes
Packet size limit: inferred: 74 bytes
Number of packets: 158 k
File size: 13 MB
Data size: 136 MB
Capture duration: 962.546364 seconds
First packet time: 2016-12-09 16:08:26.208551
Last packet time: 2016-12-09 16:24:28.754915
Data byte rate: 141 kBps
Data bit rate: 1133 kbps
Average packet size: 862.03 bytes
Average packet rate: 164 packets/s
SHA256: cf4037505f5cdfb434f5186c6de36195f64b1025f4e5136602d4656f00f5584d
RIPEMD160: 5c4de2a8620914b4961e88b5e099a497f765bf4c
SHA1: ced52359b86d900c83569d5bbfda693735758011
Strict time order: True
Number of interfaces in file: 1
Interface #0 info:
Encapsulation = Ethernet (1 - ether)
Capture length = 65535
Time precision = microseconds (6)
Time ticks per second = 1000000
Number of stat entries = 0
Number of packets = 158232
λ
专家信息如下,存在很多的乱序、重传、快速重传以及疑似重传等现象,数据包初步看起来问题多多。
首先还是来研究第一个问题,为啥会没有显示 DUP ACK ? 等我打开数据包具体信息时,却发现了同样的一个现象,一样不显示 DUP ACK,而我的 Wireshark 也是当时最新版本 Version 3.6.3 ,基于对自己 Wireshark 工具的打造,我肯定自己是没有改动相关配置的,那么有意思的问题来了,啥情况~
在 No.133 提示 TCP Previous segment not captured
之前,从 No.127 - No.132 是几次正常的数据交互:
带着这些疑问,我对数据包仔细对比分析了下,发现了一个问题,Wireshark 在这些地方没把 ACK 标识成 DUP ACK ,是由于数据包跟踪文件按 74 字节做了切割,导致 TCP Option 中 SACK 少了 4 字节的 Right edge 部分。也就是在这样的情况下,Wireshark 缺少对 SACK 的完整分析,造成分析逻辑错误,无法标识出正常的 DUP ACK。
14 Ethernet II 首部+ 20 IPv4 首部+ 40 TCP 首部 (20 + 24 TCP Options)
本来以为这个问题就结束了,没想到还有说同样的数据包跟踪文件能正常显示出 DUP ACK,版本是 Version 3.2.1,如下图。
好吧,继续研究,这个问题就比较好琢磨了,应该就是 Wireshark 的版本差异导致,通过几个不同绿色版本的 Wireshark 研究对比,得到了以下答案:
以上就是 消失的 TCP DUP ACK
真正的原因,至于再具体的原因,可能需要追溯到不同版本的代码差异了,此处就未再继续深究了。
可能还会有同学记到那位群友想问的问题,为什么有如此多的 DUP ACK 而没有进行快速重传?实际上这个问题就比较好解答了。
注意看时间,客户端 ACK 数据分段的间隔时间极短,可以判断出数据包跟踪文件就是在客户端上或是在靠近客户端上所捕获。那么就会有这样一种场景,服务器和客户端之间存在一定距离,也就是假设 RTT 有几十 ms ,当服务器一次性传输多个数据分段到客户端时,如果有某一个分段丢失,那么在客户端本地看,自然会因为连续收到很多数据分段,而产生出很多个 DUP ACK,而起初的三个 DUP ACK 这时候还在发送给服务器的途中呢,直到服务器真正接收再到触发快速重传出来,这个快速重传数据包再到客户端上被捕获到,也已经是 1 个 RTT 左右之后的事情了。
以 No. 138 第三个 DUP ACK 数据包为参考时间,真正的 Seq 110033 的快速重传数据包出现在 No.201,间隔时间约为 35 ms,也就是 1 个 RTT 左右。
有些问题说简单却并不简单,时刻保持一颗好奇心,从不一样的角度看问题,你会发现有些事情很有趣。