IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Wireshark TS | 当超时或快速重传遇到零窗口 -> 正文阅读

[网络协议]Wireshark TS | 当超时或快速重传遇到零窗口

问题背景

用户反馈 VNC 使用场景,在 VNC 客户端连接 VNC 服务器时,偶尔会出现客户端触摸点击的响应会延迟,延迟时间在 500ms 至 2s 之间。通过 Wireshark 捕获了数据包,看到了零窗口、乱序、重传等问题。用户对于服务器在 500ms 之后才发送重传而不是快速重传,表示疑问~

在分析该案例起初,我也认为是一个一般的故障,但随着深入分析,该案例展示出很不一样的异常现象,故分享下一段很烧脑的分析过程。

案例取自 Wireshark 官方问答论坛
https://osqa-ask.wireshark.org/questions/24275/tcp-retransmission-with-a-delay-time-of-two-seconds/


问题分析

基本信息

跟踪文件信息基本信息如下

$ capinfos 283-02-Capture2.pcapng
File name:           283-02-Capture2.pcapng
File type:           Wireshark/... - pcapng
File encapsulation:  Ethernet
File timestamp precision:  microseconds (6)
Packet size limit:   file hdr: (not set)
Number of packets:   352
File size:           205 kB
Data size:           194 kB
Capture duration:    2.402748 seconds
First packet time:   2013-09-02 14:55:19.372951
Last packet time:    2013-09-02 14:55:21.775699
Data byte rate:      80 kBps
Data bit rate:       646 kbps
Average packet size: 551.68 bytes
Average packet rate: 146 packets/s
SHA256:              4604d1adafb045024f33636bf269d4b82077a59ae53a78b0dd2e17db1693a30a
RIPEMD160:           24e50fff31cda5eace4150de0146346cc493e45a
SHA1:                c6f9b15dc2a532489a8fc56bbf465ee0b6497ce6
Strict time order:   True
Capture oper-sys:    64-bit Windows 7, build 7600
Capture application: Dumpcap 1.10.1 (SVN Rev 50926 from /trunk-1.10)
Number of interfaces in file: 1
Interface #0 info:
                     Name = \Device\NPF_{A9EF82F5-FA0D-49F4-AF52-1C2066D04340}
                     Encapsulation = Ethernet (1 - ether)
                     Capture length = 65535
                     Time precision = microseconds (6)
                     Time ticks per second = 1000000
                     Time resolution = 0x06
                     Operating system = 64-bit Windows 7, build 7600
                     Number of stat entries = 0
                     Number of packets = 352

用户很好的过滤了所需的数据包,非常清晰,仅有一条 TCP Stream 0,便于排障分析。专家信息显示也证明了用户反馈的问题现象,零窗口、乱序、重传等统计。
re-01
re-02

唯一美中不足的是该 TCP 会话不完整,tcp.completeness == 12 意味着仅包含有 Data 和 Ack,而没有三次握手等数据包。

TCP 会话完整性功能,可见之前文章《TCP 会话完整性分析》

re-03

深入分析

首先跟踪文件初始,客户端 192.168.0.66 即出现了零窗口现象,以 [TCP ZeroWindow] 标识,并通知了服务器 192.168.0.10 。

即便因跟踪文件缺少三次握手而无法识别 Win 窗口因子大小,此客户端的接收窗口确实已填充满。

re-04

客户端至服务器端方向

在此抓包点显示这个传输方向上可能有丢包以及随之带来的重传现象。根据提示少了一个 Seq Num为 2711 ,Len 为 6 的 TCP 分段,在 No.239 进行了 TCP 重传。
re-05
re-06

首先第一个问题是,No.239 真的是一个超时重传数据包嘛? 带着这个疑问先继续往下。同样的现象在之后也有反复出现,如下,No.245 提示丢失分段和 No.254 提示重传,并且伴随着客户端本身所不断告知的零窗口现象。
re-07

开始进入一段烧脑的推导分析过程,No.254 是否是 TCP 超时重传数据包?(暂不考虑问题1 No.239)

  1. 首先说为什么不是快速重传?虽然客户端和服务器端处于一个局域网内,RTT 仅有 1.x 毫秒,但由于应用协议交互的特殊性,客户端带数据字段的数据包传输很少,因此个别的丢包或乱序并没有带来连续的 DUP ACK 现象,所以无法触发客户端快速重传,所以并不会是快速重传。

  2. 但是真的是 TCP 超时重传数据包嘛?如果认为 No.254 是超时重传的数据包,那么理论初始包应该是在 No.238 数据包之后发出来,但是与 No.254 的时间间隔来说,仅仅只 3.6 ms ,并不满足 RTO 最小 200ms 的时间,所以 Wireshark 在此判断的并不准确。(可能是没有抓到 TCP 三次握手,无 IRTT 值的参考)

  3. 如果不是快速重传,也不是超时重传,那么 No.254 数据包是乱序包嘛?如果按照一般的异常现象,确实会如此判断,因为也只有乱序才会造成 Seq Num 小的数据分段反而出现在后面。

  4. 但是真实情况是这样嘛?首先看下现象,客户端 192.168.0.66 所有数据包的 IP ID,理论上在源端发来的时候应该是一个递增状态,所以 Seq Num 小的数据包 IP ID 也应该是小的。如果是 3 中所判断的乱序数据包,No.254 理论上的 IP ID 也应该是在 No.238 数据包 IP ID 之后,而在 No.248 数据包 IP ID 之前。但如下图的实际情况却并非如此,包括 No.254 在内的客户端 192.168.0.66 所有数据包的 IP ID 大小都是和数据包顺序一致,从上到下依次递增的。这说明了什么?
    re-08

  5. 如果是从 1-4 的分析结果,这样的现象说明可能在客户端 192.168.0.66 内核协议栈上出了问题,意味着在 TCP 层面数据分段是正常的,但是在 IP 层面乱序了,所以 TCP Seq Num 小的才会在 IP ID 上反而大了。但是这样的结论以一个系统内核协议栈实现来说,实在是太匪夷所思了。。。

综合以上,从个人理解也是自己能想到的场景(不排除任何可能性),可能有以下四种初步结论:
a. 客户端内核协议栈层面出现问题,IP 和 TCP 层面乱序;No.254 是乱序的原始数据包。
b. 仍是客户端系统内核协议栈层面,但是回到推导 2 ,客户端改小了 RTO 最小值 200ms 的设定,仍是触发了超时重传;No.254 是超时重传数据包。
c. 客户端和服务器通讯路径中存在中间设备,会修改重新分配数据包的 IP ID 字段,这样如果发生乱序,会出现上述情况;No.254 是修改过 IP ID 的乱序的原始数据包。
d. 客户端和服务器通讯路径中存在中间设备,会修改重新分配数据包的 IP ID 字段,这样如果发生丢包,也会出现上述情况;No.254 是修改过 IP ID 的超时重传数据包。

可能到此有的同学还会记得,对了,问题1 No.239 呢?和 No.254 是一个情况嘛 看起来差不多,但确实有一个细节不一样,不知道心细的同学在上面的图中是否有注意到 No.239 的 ACK Num,是的,它会小于前面数据包的 ACK Num,意味着这个数据包并不是超时重传数据包,而是原始数据包。但是由于 ACK Num 存在问题,No.239 和 No.254 不太一样的地方是, No.239 并没有被服务器端所正常接受。
re-09

在之后经由 DUP ACK 触发,在 No.277 上客户端进了一次真正的快速重传后,服务器端正常接收并确认。
re-10

结合 No.239 数据包所带来的线索,最后的结论缩小范围为两种:
a. 客户端内核协议栈层面出现问题,IP 和 TCP 层面乱序;No.254 和 No.239 是乱序的原始数据包。
b. 客户端和服务器通讯路径中存在中间设备,会修改重新分配数据包的 IP ID 字段,这样如果发生乱序,会出现上述情况;No.254 和 No.239 是修改过 IP ID 的乱序的原始数据包。

此处所得出的结论,主要以数据包实际现象,从个人理解并一步步推导,经过很长一段时间思考和论证之后才得出该结果,不知道是否一定正确,也因为是一个互联网案例,真实情况已无从考证。


服务器端至客户端方向

转到服务器传输方向,也有着很不一样的地方。在客户端 192.168.0.66 ACK 135753 后,服务器端 192.168.0.10 连续发送了 5 个 MSS 的数据包,但是客户端 192.168.0.66 并没有做出确认,而是回复以 4 个 TCP ZeroWindow , 因为客户端的接收窗口为 0 而无法确认数据。

紧接着服务器端 192.168.0.10 重新发送了这 5 个 MSS 的数据包,wireshark 在此处前 4 个标识为乱序,后 1 个标识为重传,而由于间隔时间太短,Wireshark 在此判断错误,这 5 个数据包理论应该都为重传数据包,但是具体是超时重传还是快速重传呢?
re-11

仍然是缺少原始环境的进一步考证,所以分析可能的结果主要如下:

  1. 在服务器端会首先有一个细节需要考虑,在接到客户端 TCP ZeroWindow 的通知,服务器仍然进行了重传(不论是超时重传还是快速重传)。在标准协议栈的层面上,应该不会在零窗口期间发送数据。所以带来一个思考,在这样的特殊环境下,服务器的协议栈是如何工作?是满足快速重传或超时重传的条件而不顾零窗口而继续发包,还是说会依照零窗口的通知而停止发包,不管是否已经满足快速重传或超时重传的条件。
  2. 从实际数据包的现象来说,在零窗口期间,服务器仍继续发包了,那么回到先前的问题,具体是超时重传还是快速重传呢?
  3. 如果是超时重传,那么和上面客户端的一个推导结果一样,如果是在系统内核协议栈层面,改小了 RTO 最小值 200ms 的设定,那么就会触发超时重传;
  4. 如果是快速重传,服务器端此时把 TCP ZeroWindow 的数据包当成是 DUP ACK,从而触发快速重传,也是一个比较奇特的行为。

继续往下分析, 由于客户端零窗口一直存在而无法确认数据包,所以服务器在 No.240 Seq Num 135753 第一次发出后,No.249 Seq Num 135753 进行了第一次重传,正常应该在 No.265 第二次重传 Seq Num 135753,但是唯独少了这个包,一直到 No.297 才出现,同时也一样存在 IP ID 正常递增的情形,而且注意此时的 ACK Num 4209 也是递增的。
re-12

结合客户端和服务器端的故障现象和推导分析,可能得出最终这样的分析结论:客户端和服务器通讯路径中存在中间设备,会重新分配并修改数据包的 IP ID 字段,如果同时发生奇怪的乱序,就会出现重传或是假重传现象。由于客户端同时存在零窗口无法确认数据的问题下,造成故障现象反复,一直到客户端窗口恢复正常后,问题才随之消失。


总结

没有实际环境加以佐证的情况下,部分故障案例分析真真真的是心累。。。



感谢阅读,更多技术文章可关注个人公众号:Echo Reply ,谢谢。
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:32:39  更:2022-05-24 18:34:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:43:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码