RST的TCP握手含义

网络工程 tcp 联网 传输协议 第 4 层 流媒体
2022-02-07 12:47:27

我正在尝试实现 TCP 握手但接收 RST 而不是 ACK:

No.     Time           Source                Destination           Protocol Length Info
     62 24.622012890   192.168.0.147         192.168.0.41          TCP      76     51486 → 8888 [SYN] Seq=1240744644 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=2095798637 TSecr=0 WS=128

Frame 62: 76 bytes on wire (608 bits), 76 bytes captured (608 bits) on interface 0
Linux cooked capture
Internet Protocol Version 4, Src: 192.168.0.147, Dst: 192.168.0.41
Transmission Control Protocol, Src Port: 51486, Dst Port: 8888, Seq: 1240744644, Len: 0

No.     Time           Source                Destination           Protocol Length Info
     63 24.627320274   192.168.0.41          192.168.0.147         TCP      62     8888 → 51486 [SYN, ACK] Seq=4039242319 Ack=0 Win=64240 Len=0

Frame 63: 62 bytes on wire (496 bits), 62 bytes captured (496 bits) on interface 0
Linux cooked capture
Internet Protocol Version 4, Src: 192.168.0.41, Dst: 192.168.0.147
Transmission Control Protocol, Src Port: 8888, Dst Port: 51486, Seq: 4039242319, Ack: 0, Len: 0
VSS-Monitoring ethernet trailer, Source Port: 0

No.     Time           Source                Destination           Protocol Length Info
     64 24.627364199   192.168.0.147         192.168.0.41          TCP      56     51486 → 8888 [RST] Seq=0 Win=0 Len=0

Frame 64: 56 bytes on wire (448 bits), 56 bytes captured (448 bits) on interface 0
Linux cooked capture
Internet Protocol Version 4, Src: 192.168.0.147, Dst: 192.168.0.41
Transmission Control Protocol, Src Port: 51486, Dst Port: 8888, Seq: 0, Len: 0

我将 enc28j60 以太网控制器设置为服务器,并有脚本作为客户端。我尝试使用我自己的 TCP/IP 堆栈从 enc28j60(以太网控制器)发送一个 SYN、ACK 数据包,以响应来自客户端的 SYN,但我总是收到 RST 而不是 ACK。

根据 Wireshark,我的 SYN,ACK 中的校验和是正确的。我已经设置了ARP。

客户发送 RST 的一些原因是什么?

1个回答

发送 RST 的原因有多种。我们不知道您获得 RST 的具体原因,并且您的 TCP 主机实现正在做的事情在这里是题外话。

RFC 793,传输控制协议是 TCP 的定义,如果您尝试按照您的描述进行操作,您应该真正熟悉其中的所有内容。它有一个一般性的解释,但还有很多其他的事情你应该理解:

重置生成

作为一般规则,每当一个显然不是用于当前连接的段到达时,必须发送重置 (RST)。如果不清楚是这种情况,则不得发送复位。

状态分为三组:

  1. 如果连接不存在(CLOSED),则发送复位以响应除另一个复位之外的任何传入段。特别是,寻址到不存在的连接的 SYN 会通过这种方式被拒绝。

    如果传入的段有一个 ACK​​ 字段,则重置从段的 ACK 字段中获取其序列号,否则重置的序列号为零,并且 ACK 字段设置为传入段的序列号和段长度之和. 连接保持在 CLOSED 状态。

  2. 如果连接处于任何非同步状态(LISTEN、SYN-SENT、SYN-RECEIVED),并且传入段确认尚未发送的内容(段携带不可接受的 ACK),或者传入段具有安全级别或如果隔间与连接请求的级别和隔间不完全匹配,则会发送重置。

    如果我们的 SYN 未被确认并且传入段的优先级高于请求的优先级,则提高本地优先级(如果用户和系统允许)或发送重置;或者如果传入段的优先级低于请求的优先级,则继续,就好像优先级完全匹配(如果远程 TCP 不能提高优先级以匹配我们的优先级,这将在它发送的下一个段中检测到,并且连接将被终止)。如果我们的 SYN 已被确认(可能在此传入段中),则传入段的优先级必须与本地优先级完全匹配,否则必须发送重置。

    如果传入的段有一个 ACK​​ 字段,则重置从段的 ACK 字段中获取其序列号,否则重置的序列号为零,并且 ACK 字段设置为传入段的序列号和段长度之和. 连接保持相同状态。

  3. 如果连接处于同步状态(ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT),任何不可接受的段(超出窗口序列号或不可接受的确认) number) 必须只引出一个空的确认段,其中包含当前的发送序列号和一个指示预期接收的下一个序列号的确认,并且连接保持在相同的状态。

    如果传入段的安全级别、隔离区或优先级与连接请求的级别、隔离区和优先级不完全匹配,则发送重置并且连接进入关闭状态。重置从传入段的 ACK 字段中获取其序列号。

重置处理

在除 SYN-SENT 之外的所有状态下,所有重置 (RST) 段都通过检查其 SEQ 字段来验证。如果其序列号在窗口中,则重置有效。在 SYN-SENT 状态(响应初始 SYN 接收到的 RST),如果 ACK 字段确认 SYN,则 RST 是可接受的。

RST 的接收者首先验证它,然后改变状态。如果接收器处于 LISTEN 状态,它会忽略它。如果接收器处于 SYN-RECEIVED 状态并且之前一直处于 LISTEN 状态,则接收器返回 LISTEN 状态,否则接收器中止连接并进入 CLOSED 状态。如果接收器处于任何其他状态,它会中止连接并通知用户并进入 CLOSED 状态。