问题背景

用户反馈客户端应用程序无法收到 HTTP 响应的最后一个数据包,导致超时错误。从数据包捕获来看,服务器已成功发送所有数据,也发送了 FIN/ACK ,但是客户端接收并确认数据,但从不发送 FIN/ACK 或 RST 结束连接。

比较奇怪的现象,什么情况会导致客户端不响应 FIN ?



案例取自 Wireshark 官方问答论坛



问题分析

该用户对此问题估计也是做了一定功课,直接放上了三个数据包供分析,包括客户端故障时的抓包、客户端成功时的抓包以及服务器端故障时的抓包,🤣 妥妥 IT 人士。对于这种情况,如果数据包不是太复杂的话,对比法可能就能得到结果了。



客户端故障时的抓包

wireshark爆红 wireshark fin_wireshark


直接转到用户所说的结束连接阶段,服务器 10.22.193.39 在帧 67 发送了 FIN/ACK(携带有PSH),Seq 61321 + Len 403 + FIN 1 = NextSeq 61725,但是客户端 10.196.131.236 在帧 68 仅仅 ACK 确认了 61724 之前的数据(长度 403),很明显忽略了服务器的 FIN 。因为在随后的帧 69 中,客户端 10.196.131.236 一没有数据发送,二不发出 FIN/ACK,仅仅只是发送了一个窗口更新的 ACK ,进一步证明了客户端无视了服务器的 FIN。此后服务器进入了 FIN 包的重传阶段,客户端因为继续无视 FIN,不断的产生 TCP Dup ACK 错误。最终服务器在尝试重传 5 次后,直接 RST 了此连接。


服务器故障时的抓包

wireshark爆红 wireshark fin_wireshark_02


服务器端的抓包结果分析下来,完全匹配客户端侧结果以及分析。对应帧 24 、35 、36 ,以及之后重传、RST 连接等等。


客户端正常时的抓包

wireshark爆红 wireshark fin_wireshark爆红_03


对比分析正常时的抓包,一眼看过去确实干净很多。服务器端 192.168.116.160 在帧 64 发送了同样的 FIN/ACK,Seq 61321 + Len 402 + FIN 1 = NextSeq 61724,客户端 172.19.206.213 在帧69 时ACK 确认了 61724 之前的数据,包含了对 FIN 1字节的确认。客户端同样发送了一个窗口更新的 ACK,之后通过 RST 直接关闭了连接。


服务器和客户端 IP 的不同,是由于用户对数据包做了随机匿名化处理。



问题总结

综合上述分析,结论比较明确定位是客户端的问题,因为客户端忽略或无视了服务器端的 FIN,导致了最后 RST 连接。📖 Wireshark 可以检测到很多网络问题,但是它很可能不能告诉你是什么导致了这些问题。而最终的原因也由该用户回复得知,客户端的防病毒程序 Trend Micro Officescan 的 Web 信誉是问题的原因。

在某些故障场景中,来自于安全应用软件的问题还是或多或少存在的,数据包显现的异常行为,可以通过排除法,尝试关闭安全应用软件再观察现象。

参考

https://osqa-ask.wireshark.org/questions/55683/client-doesnt-respond-to-fin-ack/