• Wireshark TS | 消失的 TCP DUP ACK


    问题背景

    某天在技术交流群里有群友咨询一个 TCP ACK 问题,说正常三次 ACK 就会快速重传,但是他看到的为什么有的包很多 ACK 而没有进行快速重传。

    说实话,第一时间看到此消息的,我觉得是不太可能,甚至说我进一步看到问题图片的时候,一下子我也没反应过来。。。还是之后自己动手研究了原始数据包跟踪文件,才真正搞清楚是怎么一回事。

    DUP-01


    问题信息

    回到说群友的问题,其实从他的原话和截图上来说,都是带有一定迷惑性的。首先他一直描述的是 ACK,包括图片显示的也确实有很多 Ack=110033 的信息,然后又提到了为什么没有快速重传。

    这一个快速重传让我反应过来,截图上没有 DUP ACK?!! !

    DUP-02

    为啥会没有显示 DUP ACK 呢? 立马想到两个可能,

    1. 对方的 Wireshark 版本问题;
    2. 对方修改了 Wireshark 的某些默认配置,使得专家信息没有显示。

    但随着和这位群友进一步的沟通得知,他的版本已经是当时最新的 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
    
    λ
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    1. 数据包跟踪文件为 tcpdump 捕获;
    2. 文件显示数据大小 136 MB ,但实际跟踪文件只有 13 MB,因为捕获时做了截断 snaplen 为 74 字节;
    3. 捕获时长 962 秒左右;
    4. 平均速率 1133 kbps;
    5. 数据包数量约为 158232 个。

    专家信息如下,存在很多的乱序、重传、快速重传以及疑似重传等现象,数据包初步看起来问题多多。

    DUP-03


    问题分析

    首先还是来研究第一个问题,为啥会没有显示 DUP ACK ? 等我打开数据包具体信息时,却发现了同样的一个现象,一样不显示 DUP ACK,而我的 Wireshark 也是当时最新版本 Version 3.6.3 ,基于对自己 Wireshark 工具的打造,我肯定自己是没有改动相关配置的,那么有意思的问题来了,啥情况~

    DUP-04

    在 No.133 提示 TCP Previous segment not captured 之前,从 No.127 - No.132 是几次正常的数据交互:

    1. server 发送的两个分段 No.127-128 ,client No.129 ACK 确认了,并希望收到下一个数据包的 Seq 为 107257 ;
    2. server 继续发送的两个分段 No.130-131,client No.132 ACK 确认了,并希望收到下一个数据包的 Seq 为 110033 ;
    3. 理应看到的应该是 server 再继续发送的两个分段,但实际上跟踪文件却显示了有一个分段没有捕获到,就是 No.133 所提示的 TCP 先前一个分段未被捕获到,也就是 Seq 110033 开头的分段;因此 client 会回复 No.134 ACK,希望收到下一个数据包的 Seq 仍为 110033,此处 No.134 正常应该为第一个 DUP ACK
    4. 之后的 server 和 client 的交互都是这样,server 因为一直未发送 Seq 110033 的分段,所以 client 会一直回复 ACK 需要 Seq 110033 的分段,正常这些 ACK 应该均为 DUP ACK

    带着这些疑问,我对数据包仔细对比分析了下,发现了一个问题,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-05

    本来以为这个问题就结束了,没想到还有说同样的数据包跟踪文件能正常显示出 DUP ACK,版本是 Version 3.2.1,如下图。

    DUP-06

    好吧,继续研究,这个问题就比较好琢磨了,应该就是 Wireshark 的版本差异导致,通过几个不同绿色版本的 Wireshark 研究对比,得到了以下答案:

    1. Wireshark 在 3.6.0 大版本之后,在上述缺少 TCP Option SACK 的条件下,确实不会显示 DUP ACK;
    2. WIreshark 在 3.4 或者 3.2 的大版本,虽然缺少某些判断条件,但仍旧会显示 DUP ACK;
    3. 通过对比版本,个人感觉这个变化可能更多应该是 Wireshark 自身关于 TCP ACK 的设计,而非 BUG 之类的问题。

    以上就是 消失的 TCP DUP ACK 真正的原因,至于再具体的原因,可能需要追溯到不同版本的代码差异了,此处就未再继续深究了。

    可能还会有同学记到那位群友想问的问题,为什么有如此多的 DUP ACK 而没有进行快速重传?实际上这个问题就比较好解答了。

    注意看时间,客户端 ACK 数据分段的间隔时间极短,可以判断出数据包跟踪文件就是在客户端上或是在靠近客户端上所捕获。那么就会有这样一种场景,服务器和客户端之间存在一定距离,也就是假设 RTT 有几十 ms ,当服务器一次性传输多个数据分段到客户端时,如果有某一个分段丢失,那么在客户端本地看,自然会因为连续收到很多数据分段,而产生出很多个 DUP ACK,而起初的三个 DUP ACK 这时候还在发送给服务器的途中呢,直到服务器真正接收再到触发快速重传出来,这个快速重传数据包再到客户端上被捕获到,也已经是 1 个 RTT 左右之后的事情了。

    DUP-07

    以 No. 138 第三个 DUP ACK 数据包为参考时间,真正的 Seq 110033 的快速重传数据包出现在 No.201,间隔时间约为 35 ms,也就是 1 个 RTT 左右。

    -08

    问题总结

    有些问题说简单却并不简单,时刻保持一颗好奇心,从不一样的角度看问题,你会发现有些事情很有趣。

  • 相关阅读:
    硅树脂油漆申请美国标准UL 790 Class A 合适吗?
    CSS3之转换(2D转换,动画,3D转换)
    Open suse 15.4 Leep 服务环境部署过程及避坑
    Express 3 快速入门 - Express 应用程序生成器
    java-net-php-python-jsp无锡尚客优酒店客房管理信息系统mp4计算机毕业设计程序
    基于51单片机的超声波测距仿真倒车雷达系统设计
    【iOS】—— 对象的底层结构和继承者链(isa、class)
    SNP应邀参加2023中国企业数字化转型峰会暨赛意用户大会
    OpenHarmony 3.1 Beta版本关键特性解析——分布式DeviceProfile
    Dart-C、Dart-Kotlin/Java/Swift/Object-C、Kotlin-C数据类型对照表
  • 原文地址:https://blog.csdn.net/weixin_47627078/article/details/127707481