TCP/IP卷一:69---TCP连接管理之(重置报文段RST(端口不存在、终止一条连接、半开连接、时间等待错误))
发布日期:2021-06-29 22:33:23 浏览次数:2 分类:技术文章

本文共 3272 字,大约阅读时间需要 10 分钟。

一、重置报文段(RST介绍)

  • 在上图TCP头部中,其有一个RST位字段。一个将该字段置位的报文段被称作“重置报文段”或简称为“重置” 
  • 一般来说,当发现一个到达的报文段对于相关连接而言是不正确的时,TCP就会发送一个重置报文段。(此处,相关连接是指由重置报文段的TCP与IP头部的4元组所指定的连接)。重置报文段通常会导致TCP连接的快速拆卸
  • 本文将构建一些场景来证明重置报文段的用途

二、针对不存在端口的连接请求

  • 通常情况下,当一个连接请求到达本地却没有相关进程在目的端口侦听时就会产生一个重置报文段。之前在“连接被拒绝”的错误消息中已经介绍过这种情况。这些均与TCP协议相关
  • 与UDP的不同:
    • UDP协议规定,当一个数据报到达一个不能使用的目的端口时就会生成一个ICMP目的地不可达(端口不可达)的消息
    • TCP协议则使用重置报文段来代完成相关工作

演示案例

  • 例如,我们可以使用Telnet客户端并指定一个在目的主机上尚未使用的端口号。这台目的主机也可以是本地的计算机:

  • Telnet客户端会快速地输出上述错误消息。下图显示了与此命令相关的数据包交换过程

  • 此图中需要查看的数值包括重置(第2个)报文段中的序列号字段与ACK号字段。 由于到达的SYN报文段未打开ACK位字段,重置报文段的序列号字段被设置为0,而ACK 号的大小则等于接收到的初始序列号加上该报文段中数据的字节数。虽然到达的报文段中并 不含有任何数据,SYN位在逻辑上仍会占用一个字节的序列号空间。因此,在这个例子中重置报文段中的ACK号等于初始序列号加上数据长度0,再加上SYN位的1字节
  • 对于一个被TCP端接收的重置报文段而言,它的ACK位字段必须被置位,并且ACK号字段的数值必须在正确窗口的范围内(见前面窗口介绍的文章)。这样有助于防止一种简单的攻击。 在这种攻击中任何人都能够生成一个与相应连接(4元组)匹配的重置报文段,从而扰乱这个连接[RFC5961]

三、终止一条连接

  • 有序释放、终止释放:
    • 从TCP断开连接的示意图可以知道,看出终止一条连接的正常方法是由通信一方发送一个FIN。这种方法有时也被称为有序释放。因为FIN是在之前所有排队数据都已发送后才被发送出去,通常不会出现丢失数据的情况
    • 然而在任何时刻,我们都可以通过发送一个重置报文段替代FIN来终止一条连接。这种方式有时被称作终止释放
  • 终止一条连接可以为应用程序提供两大特性:
    • 任何排队的数据都将被抛弃,一个重置报文段会被立即发送出去
    • 重置报文段的接收方会说明通信另一端采用了终止的方式而不是一次正常关闭
  • SO_LINGER套接字选项:
    • API必须提供一种实现上述终止行为的方式来取代正常的关闭操作。套接字API通过将“逗留于关闭”套接字选项(SO_LINGER)的数值设置为0来实现上述功能
    • 从本质上说,这意味着“不会在终止之前为了确定数据是否到达另一端而逗留任何时间”

演示案例

  • 下面的例子展示了当一个产生大量输出的远程命令被用户取消时所发生的状况:

  • 此处,用户决定终止这条命令的输出行为。由于单词文件中包含了45427个字,这个命令很可能是某种错误。当用户键人中断字符时,系统显示对应进程(此处为ssh程序)已经被2号信号终止。该信号被称作SIGIHT,常用于终止一些交付的程序
  • 下图显示了上述例子中tcpdump的相应输出结果(由于与本文的讨论无关,大量的中间数据包已被删除)

  • 报文段1 - 3显示了正常连接的建立过程。当中断字符被键入之后,连接被终止。重置报文段中包含了一个序列号与一个确认号。还需要注意的是重置报文段不会令通信另一端做出任何响应一它不会被确认。接收重置报文段的一端会终止连接并通知应用程序当前连接已被重置。这样通常会造成“连接被另一端重置”的错误提示或类似的消息

四、半开连接

  • 如果在未告知另一端的情况下通信的一端关闭或终止连接,那么就认为该条TCP连接 处于半开状态。这种情况发生在通信一方的主机崩溃的情况下。只要不尝试通过半开连接传 输数据,正常工作的一端将不会检测出另一端已经崩溃
  • 产生半开连接的另一个共同原因是某一台主机的电源被切断而不是被正常关机。这种情 况可能发生于下面的例子中:某些个人电脑运行了远程登录客户端,并且在一天结束时关闭。 如果在电源被切断时没有数据在传输,那么服务器永远也不会知道该客户端已经消失(它可能还一直会认为该连接处于ESTABLISHED状态)。当第二天早晨用户回来,启动电脑并开 始一个新的会话时,服务器会启动一个新的服务进程。这样会导致服务器上有很多半开的TCP连接(在后面TCP保活机制会介绍一种方法,使TCP连接的一端能够利用TCP的keepalive选项 发现另一端已经消失)

演示案例

  • 我们能够很容易地创建一个半开连接。在这种情况下,将在客户端而不是服务器做一些 尝试。我们在主机10.0.0.1上执行Telnet客户端程序,连接Sun公司提供远程过程调用服务(sunrpc,端口号111)的服务器
  • 如下图所示,该服务器的IP为10.0.0.70我们键人一 行输人,并利用tcpdump观察它们的交互过程,然后断开服务器主机的以太网连接并重新启动这台主机。这样就能模拟服务器崩溃的情况。(我们在重启服务器之前断开以太网连接是为了防止其通过已开启的连接发送一个FIN。一些TCP会在其关闭时完成上述操作。)在服务器重启之后,我们重新连接以太网并且尝试从客户端向服务器发送另一行命令。在重启之 后,服务器的TCP会丢失之前所有连接的记忆,因此它对数据段中指出的这条连接一无所 知。此时,TCP规定接收者将回复一个重置报文段作为响应

  • 下图显示了该例的tcpdump输出

  • 报文段1 - 3描述了正常的连接建立过程。报文段4将“foo”行发送至sunrpc服务器(包括回车符与换行符共需要5个字节)。报文段5则完成确认工作
  • 此时,我们断开服务器端(地址10.0.0.7)的以太网连接,然后重启服务器并重新接入以太网。上述操作大约花费90秒的时间。然后,我们在客户端键入一行新的输入(“bar”)。 当我们按下回车键后,这一行输入将会发送至服务器(在ARP流量之后的第一个TCP报文段中)。由于该服务器不再记得之前的这条连接,所以上述操作将引起服务器端的重置响应
  • 需要注意的是当主机重新启动时,它将使用免费的ARP协议来确定自已的IPv4地址是否已经被其他报文段使用,而这些报文段是属于其他主机的。它还会请求与IP地址10.0.0.1对应的MAC地址,因为这是它对于Internet的默认路由

五、时间等待错误

  • 如前文所述,设计TIME_WAIT状态的目的是允许任何受制于一条关闭连接的数据报被丢弃。在这段时期,等待的TCP通常不需要做任何操作,它只需要维持当前状态直到2MSL 的计时结束。然而,如果它在这段时期内接收到来自于这条连接的一些报文段,或是更加特 殊的重置报文段,它将会被破坏。这种情况被称作时间等待错误(TIME-WAIT Assassination TWA)

图示

  • 下图展示了数据包的交换过程
  • 在下图的例子中,服务器完成了其在连接中的角色所承担的工作并清除了所有状态。客户端依然保持TIME_WAIT状态。当完成FIN交换,客户端的下一个序列号为K,而服务器的下一个序列号为L。最近到达的报文段是由服务器发送至客户端,它使用的序列号为L一100,包含的ACK号为K-200。当客户端接收到这个报文段时,它认为序列号与 ACK号的数值都是“旧”的。当接收到旧报文段时,TCP会发送一个ACK作为响应,其中包含了最新的序列号与ACK号(分别是K与L)。然而,当服务器接收到这个报文段以后,它没有关于这条连接的任何信息,因此发送一个重置报文段作为响应。这并不是服务器的问题,但它却会使客户端过早地从TIME_WAIT状态转移至CLOSED状态。许多系统规定当处于TIME_WAIT状态时不对重置报文段做出反应,从而避免了上述问题

转载地址:https://dongshao.blog.csdn.net/article/details/104079442 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:TCP/IP卷一:70---TCP连接管理之(TCP服务器(TCP端口号、限制本地IP地址、限制外部节点、连接队列))
下一篇:C++(数据结构与算法):50---平衡搜索树之AVL树(AVL Tree)

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年05月01日 00时01分39秒