Wireshark TS | 虚假的 TCP Spurious Retransmission
前言
在写《TCP Analysis Flags 系列》文章时梳理出不少有趣的案例,当然过程当中也有很多的疑问,嗯,自得其乐。考虑到不同的系列偏重不太一样,因此在 TroubleShooting
系列中我再把有些案例单独展开说说。
问题背景
TCP Spurious Retransmission
,Wireshark TCP 分析标志位的一种,文档定义如下:
Checks for a retransmission based on analysis data in the reverse direction. Set when all of the following are true:
The SYN or FIN flag is set.
This is not a keepalive packet.
The segment length is greater than zero.
Data for this flow has been acknowledged. That is, the last-seen acknowledgment number has been set.
The next sequence number is less than or equal to the last-seen acknowledgment number.
Supersedes “Fast Retransmission”, “Out-Of-Order”, and “Retransmission”.
简单来说,是在数据包跟踪文件中已经被 ACK 确认过的数据分段,又再一次被重传发送,那么这个重传的数据分段会被标记为 [TCP Spurious Retransmission]
。
但本案例既然说是虚假的 [TCP Spurious Retransmission]
,那么就意味着说是 Wireshark 判断错误。
问题信息
数据包跟踪文件基本信息如下:
λ capinfos SR.pcapng
File name: SR.pcapng
File type: Wireshark/... - pcapng
File encapsulation: Ethernet
File timestamp precision: nanoseconds (9)
Packet size limit: file hdr: (not set)
Packet size limit: inferred: 70 bytes
Number of packets: 12
File size: 1508 bytes
Data size: 14 kB
Capture duration: 0.000377780 seconds
First packet time: 2023-09-16 00:28:34.816367514
Last packet time: 2023-09-16 00:28:34.816745294
Data byte rate: 39 MBps
Data bit rate: 314 Mbps
Average packet size: 1235.67 bytes
Average packet rate: 31 kpackets/s
SHA256: 810ebb5fde479c47dbd25bd9ea624d0ca49060910429345d8db72d8d583b0ca3
SHA1: e1f022d06e0ef1b3b13ebeee886e998adc2f33d0
Strict time order: True
Capture comment: Sanitized by TraceWrangler v0.6.8 build 949
Number of interfaces in file: 1
Interface #0 info:
Encapsulation = Ethernet (1 - ether)
Capture length = 2048
Time precision = nanoseconds (9)
Time ticks per second = 1000000000
Time resolution = 0x09
Number of stat entries = 0
Number of packets = 12
数据包文件通过 NPM 回溯分析下载,并根据 IP 通讯对做过特定过滤,且经过 TraceWrangler 匿名化软件处理。由于是截取数据包原因,所以捕获总时长为 0.00037778 秒,数据包数量 12 个 。
关于 TraceWrangler 匿名化软件简介,可以查看之前的文章《Wireshark 提示和技巧 | 如何匿名化数据包》
专家信息如下,因为数据包特定截取且数量较少,所以仅有虚假重传、重传、先前分段未被捕获等几个常见问题。
问题分析
展开数据包跟踪文件实际信息如下:
首先 172.23.159.205 为发送端,172.30.201.159 为接收端,No.5-6 发送端所发送的数据分段,因个别未捕获到,标识为 [TCP Previous segment not caputred]
,但接收端 No.9 的 ACK Num 9881 说明已确认接收了序号 9881 之前的数据段,但在 No.11 发送端又重新发送了 Seq Num 4940 + Len 1368 的数据分段,因此符合条件,标识为 [TCP Spurious Retransmission]
。
一切看起来挺合理,但为什么说是判断错误呢?凡事深想一层,干活多做一步,再瞅瞅 ip.id ,你会发现有些问题。发送端 No.11 的 ip.id 为 29559,这不是应该是在 No.4 和 No.5 之间的一个数据包嘛,所以呢,No.11 不是重传,它是原本的数据分段,也因此它应该被标识成 [TCP Out-Of-Order]
。
但是为什么会出现这样的情况,乱序的数据段出现在了 ACK 确认之后,虽然不是完全确认抓包的环境,但基本上可以猜测是交换机镜像或者 TAP 出了问题,更有可能是后者造成的乱序。
问题延伸
那么再说说 Wireshark 为什么没考虑到这类场景,或者说是没有考虑 ip.id,也就是 ip identification 起到的作用。
我个人对这的理解是考虑到 TCP 乱序、重传场景的复杂性,对于 TCP Spurious Retransmission
是与 TCP Out-Of-Order
、TCP Fast Retransmission
、TCP Retransmission
等在一起综合判断,并标记乱序或重传类型的,复杂场景下确实可能出现判断错误的情况,这一方面我觉得可以适时的提交 Issue,与官方开发者讨论看是否能增加相关的判断逻辑。
其次 ip.id 问题,事实是在于 RFC 对于 identification 标准的定义和作用:Identification,An Internet Protocol field. This identifying value assigned by the sender aids in assembling the fragments of a datagram。主要是用于分片场景,而 IP 数据包中的 ip.id 递增,这个规律可以辅助于数据包分析,但是严格意义下的 Wireshark 是没有相关分析代码的,更何况有的数据包传输时的 ip.id 会是全 0 。
当然不能说 Wireshark 完全没考虑到这类场景,它提供了手动修改的选项,用于修正乱序或者重传的类型。
点选该重传数据包,右键 Protocol Preferences
-> Transmission Control Protocol
-> Force interpretation to selected packet(s)
,然后可以选择:
- 0 (none)
- 1 (Out-of-Order)
- 2 (Retransmission)
- 3 (Fast Retransmission)
- 4 (Spurious Retransmission)
调整完后的 No.11 数据包,由原来的 TCP Spurious Retransmission
变为 TCP Out-Of-Order
。
问题总结
如何高效的分析 TCP 乱序、重传,确实是一个很值得探讨的问题。