问题背景
首先解释下什么是选择性or针对性丢包,这只是我对某些问题场景的描述,并非专业术语,譬如 MTU 问题场景就算其中一种,超出固定大小限制的数据包无法正常传输等等。
本篇介绍的是某一个比较特殊的丢包场景,在开通新的国际线路后,应用开发人员发现无法连接到服务器,认为可能是有网络丢包现象,遂升级问题进行排查。
案例取自 SharkFest 2011《Packet Trace Whispering》
问题信息
数据包跟踪文件基本信息如下:
bash
λ capinfos Session-I1-Case1-HK.pcap
File name: Session-I1-Case1-HK.pcap
File type: Wireshark/tcpdump/... - pcap
File encapsulation: Ethernet
File timestamp precision: microseconds (6)
Packet size limit: file hdr: 1618 bytes
Packet size limit: inferred: 54 bytes
Number of packets: 133
File size: 11 kB
Data size: 28 kB
Capture duration: 741.679716 seconds
First packet time: 2011-03-16 17:53:09.318379
Last packet time: 2011-03-16 18:05:30.998095
Data byte rate: 39 bytes/s
Data bit rate: 312 bits/s
Average packet size: 218.00 bytes
Average packet rate: 0 packets/s
SHA256: 12e030a7c5abbe16991abf0817091d0d758ce60384cad3666c29a209b457dba8
RIPEMD160: 17f23fb2e4776b7670f3740c2ecfa82b49c0832e
SHA1: 5f645d95ac02c16c8cf31170376bfa4a077ebb59
Strict time order: True
Number of interfaces in file: 1
Interface #0 info:
Encapsulation = Ethernet (1 - ether)
Capture length = 1618
Time precision = microseconds (6)
Time ticks per second = 1000000
Number of stat entries = 0
Number of packets = 133
跟踪文件在 linux 上通过 tcpdump 所捕获,数据包数量并不多,只有 133 个,长度截断为 54 字节,文件数据大小 28k 字节,捕获时长相对较长 741.68 秒,平均速率仅 312 bps。
统计会话信息中,可以看 IP 地址信息,推断进行了匿名化处理,并存在 4 条 TCP 流。
专家信息如下,可以看到存在部分协议解析层面的 Error 问题、 TCP ACKed unseen segment 等 Warning 问题,以及比较普遍的(疑似)重传和 DUP ACK 现象,数量并不多,需要进一步实际分析。
问题分析
展开数据包跟踪文件数据包详情如下:
通过统计会话信息可知 TCP 流仅 4 条,快速过滤并浏览可知 TCP Steam 0-2 基本正常,无丢包重传现象。
bash
tcp.stream in {0,1,2}
或者通过点选黑色箭头标注位置,可直接快速跳转到问题所在,比较清晰的可见 TCP 重传和 DUP ACK 等问题现象,存在于 TCP Stream 3 中。
进行 TCP Stream 3 具体分析,首先是 TCP 三次握手信息,
- 服务器端口 22,之后也可知两端运行 SSH 协议 2.0 版本;
- IRTT 0.243327 秒,约 243 ms,可见客户端通过国际线路至服务器端确实很远;
- 客户端和服务器端的 MSS 均为 1460;
- 客户端支持 SACK,但服务器不支持;
- 另外 TTL ,客户端 122,服务器端 52,可判断抓包点在中间路径。
转至 TCP 重传信息位置,主要分析如下:
- 在收到 No.112 客户端的数据分段后,服务器以 No.113 ACK 确认了该数据,但在之后 No.114 一直到最后,均只有服务器单方向的数据包;
- 在 No.114 - No.120,服务器所发送的连续 7 个数据分段均没有得到客户端的确认,疑似产生了丢包行为,客户端并未收到相关数据包;
- 之后因为未收到客户端的确认,服务器发生了超时重传,可以看到 TCP 通过指数回退方式进行了 7 次重传,No.121-No.125、No.130、No.133,约 2.5s、5s、10s、20s、40s、64s 和 64s 间隔;另外还有一个很少见的现象是, TCP 在此处进行了聚合重传,并不是之前 7 个数据分段的单独超时重传,而是一次性通过一个 TCP 数据分段 928 字节发出;
a. 可以通过 TCP Seq Num 对应验证,2401 - 3329;
b. 也可以通过 TCP Len 验证,88+212+68+308+100+100+52=928,也就是 982 - 54(14 Ethernet II 头部+ 20 IP 头部 + 20 TCP 头部) 的结果;
c. 比较特别的超时重传行为,暂未明确是某种超时重传算法,又或者是某种内核版本下的特别行为,有清楚的同学麻烦告知下,谢谢。
- 理所当然,数据不会被无限、反复地重传。当达到一定重传次数后,如果仍然没有任何确认返回,就会判断为网络或对端服务器发生了异常,TCP 就会强制关闭连接,并且通知上层应用通信异常强行终止;
- 其中也夹杂着 TCP ACKed unseen segment ,通过 ACK Num 1313 ,对比 1312 ,疑似确认了一个客户端发出的 FIN ,之后的 DUP ACK 也是同样问题,数据包跟踪文件貌似未捕获到来自客户端的一些数据包。
那么丢包的实际原因到底是什么呢? 通过数据包的字段逐个对比,发现了以下根因:
- 服务器端 No.111 数据分段 DSCP 值为默认 0,No.113 ACK 数据包 DSCP 值同样为 0,包括 No.111 之前所有的服务器端数据包均如此,也正常双向交互;
- 但从 No.114 开始,服务器端的每一个数据包 DSCP 值变为了 4 ,Unknown 未定义 。
最终解释:
回到最开始的问题描述,因为端到端这些数据包是通过了国际线路,此处不论是源服务器端(个人猜测小概率)或者是中间运营商设备(大概率)修改了部分数据包 DSCP 值的缘故,在之后的传输路径上由于 DSCP 值无法匹配正常转发而造成丢包,不断重传仍无法解决后 FIN 连接,因此从客户端的现象来说就是无法连接服务器。
问题总结
不常见的问题,诡异的现象和最终原因,但一切皆有可能,不是嘛。