网络基本功(二十六):Wireshark抓包实例分析TCP窗口及reset

转载请在文首保留原文出处:EMC中文支持论坛https://community.emc.com/go/chinese image001.gif

介绍

TCP最重要的机制之一是滑动窗口机制,以及用以控制TCP终端节点愿意接收的数据总量的流控机制。

TCP reset可以在几种情况下被发送。有一些是协议的正常工作过程,有一些则表明可能有问题。本节中,我们查找问题以及分析解决问题的方法。

本章讨论以上两个问题。

更多信息

TCP窗口问题:

TCP零窗口,零窗口探测,零窗口违例

TCP零窗口发生于接收方在TCP头部的window字段广播接收窗口零字节的时候。这一事件告知发送方停止发送数据,因为接收方缓存已满。这也表明接收方可能发生以下问题:

  • 服务器无法为进程分配组后的内存
  • 应用碰到没有足够内存的问题,因此TCP需告知发送方停止发送数据
  • 应用消耗太多内存因此操作系统要限制应用资源

TCP零窗口探测由发送方发出,以查看接收方的零窗口是否依然存在。这一消息通过发送下一字节数据给接收方,如果接收方回复窗口大小仍然为零,则发送方的探测计时器加倍。

TCP窗口违例:发送方忽略接收方的零窗口大小并发送额外字节数据。TCP零窗口违例表明协议栈中有TCP错误。为了检查是何问题,检查是否有以下事件:

  • 某一终端设备(服务器或客户机)报出终端设备故障
  • 某一应用报出常规应用错误
  • 应用中执行某一操作时报错,例如,打开一个表格,发送一份文件至打印机,创建一个报告,或其他操作。这种情况下,是应用问题。

TCP窗口更新

TCP将窗口更新发送至连接的对端,以表明缓存大小更改,并且准备好接受更高或更低的数据速率(缓存大小决定了发送方被允许的发送速率)。这一情况发生于:

  • TCP接收方从零窗口中恢复,告知发送方重新发送速率。这一情况下,无需进行处理,只需检查第一次导致零窗口的问题。
  • TCP接收方频繁更改窗口大小。该情况下检查接收方被干扰的原因。可能是应用问题,内存问题,或终端设备上的其他问题。

看到这类现象无需担心,这就是TCP的工作机制。

TCP窗口已满

这一信息表明已发送的报文会完全填满接收方的接收缓存。发生于接收方没有对先前接收到的数据发出任何ACK确认信息,因此,这将会成为发送方从接收方收到ACK之前的最后一个报文数据。

这一事件的触发原因与触发零窗口的原因相同,是服务器或应用无响应的标志。典型实例如下图所示:

image002.jpg

上图中可以看到:

  1. 报文183816,192.168.2.138告知192.168.1.58发送窗口已满。
  2. 下一个报文,192.168.1.58发送一个信号至192.168.2.138,告知对方停止发送数据。这是一个零窗口信号。
  3. 双方继续发送零窗口以及零窗口探测。
  4. 连接的最后一个报文是192.168.2.138发送的RST报文,目的是断开连接。
  5. 某些情况下零窗口可以通过窗口更改信息来回复。某些情况下可通过reset来关闭(可以是应用零窗口从而没有收到任何数据导致)。

工作原理

TCP滑动窗口机制如下:

  1. 连接建立之后,发送方将数据发送至接收方,填入接收窗口。
  2. 若干报文之后,接收方发送ACK至发送方,确认接收到其发送的字节数。发送ACK将接收窗口清零。
  3. 这一过程持续下去,发送方向窗口中填入数据,接收方清空并发送确认信息。
  4. 扩大接收窗口大小告知发送方增加吞吐量,减小窗口告知对方减小吞吐量。这一机制按照WS/RTT规则(随着TCP版本不同而有所改变):

image003.jpg

也可以通过TCP吞吐量图表和IO图来查看问题。在TCP吞吐量图表中,使用TCP trace图表,上面一行显示了窗口大小,与下面一行的距离表明窗口的剩余大小。没有距离表示零窗口。

image004.jpg

两行之间的固定距离表明接收方工作良好。当两行渐渐靠近,表明发送方速度高于接收方。只要这两行没有重叠,TCP就会继续发送数据。

TCP reset及原因:

在可疑的链路或服务器两端连接Wireshark,开始抓包。观察抓包窗口的每一个窗口信息。TCP reset可以在几种情况下被发送。有一些是协议的正常工作过程,有一些则表明可能有问题。本节中,我们查找问题以及分析解决问题的方法。

reset是用以告知接收方断开连接的TCP信号,通过将RST标志位置1来发送。正常的操作过程中,TCP通过SYN信号打开连接,通过FIN信号关闭连接。TCP的一大特性在于有问题时,或只是为了更好的性能,它能够快速关闭连接。

无故障时发送reset

TCP关闭连接的标准方式是通过FIN和FIN-ACK信号。为了关闭连接,用户需要四个报文:来自一方的FIN/ACK和ACK,以及另一方的同样报文。当你打开一个网页,可能同时打开了数十个连接(主页,新闻,广告,定期更新的图片等),要关闭所有这些有时需要数百个FIN和FIN-ACK报文。为了防止其发生,web服务器在很多情况下会在发送请求数据之后用reset断开连接。这是标准的做法,并取决于应用程序。

有故障时发送reset

某些情况下reset表明有故障发生(并不一定是通信故障):

  • 防火墙发送的reset:当远端服务器尝试打开连接但没有结果时,也许会看到返回RST信号。这是防火墙阻隔连接的情况。下图中,可看到发送的每一个SYN都返回以RST。

image005.jpg

  • 由于收发一方有问题发送的reset:可能的原因如:
    • 五个连续没有收到ACK回复的重传。当发送方没有收到任何重传回复,它就会发送一个reset信号到对端,告知其断开连接。
    • 另一个原因是连接之上几分钟都没有任何数据(分钟数取决于系统默认)。打开连接的一方通常会发送reset(但并不总是会这样做,取决于实现方式)。

参考

Network Analysis Using Wireshark Cookbook