为什么我看到的是 RST、ACK 数据包而不是 RST 数据包?

网络工程 线鲨
2021-07-07 13:24:17

在 Wireshark 中,我经常看到 TCP Streams 以 RST、ACK 数据包而不是 RST 数据包结束。有谁知道这是为什么?

我看到的一个例子:

SYN SYN, ACK ...数据... RST, ACK

Wireshark 没有在 RST、ACK 数据包之前拾取 RST 数据包。

2个回答

RST/ACK 不是 RST 的确认,与 SYN/ACK 不完全是 SYN 的确认相同。TCP 建立实际上是一个四路过程:发起主机向接收主机发送一个 SYN,接收主机为该 SYN 发送一个 ACK​​。接收主机向发起主机发送 SYN,发起主机发送回 ACK。这将建立有状态的通信。

SYN --> 
    <-- ACK
    <-- SYN
ACK -->

为了使这更有效,接收主机可以确认 SYN,并在同一个数据包中发送自己的 SYN,创建我们习惯看到的三路过程。

SYN -->
    <-- SYN/ACK
ACK -->

在 RST/ACK 的情况下,设备使用 ACK 确认在序列中的前一个数据包中发送的任何数据,然后通知发送方连接已通过 RST 关闭。设备只是将两个数据包合并为一个,就像 SYN/ACK 一样。RST/ACK 通常不是关闭 TCP 会话的正常响应,但也不一定表示存在问题。

建立连接后,所有数据包都需要设置 ACK 并匹配接收到的数据包的序列号,以实现可靠的传输/安全。不接受没有 ACK 的 RST。当一方发送RST时,套接字立即关闭,接收方在收到有效的RST后也立即关闭套接字。它不需要也不能被承认。

TCP握手后

A --->B Syn=x, Ack=y, len=z, ACK 标志

B --->A Syn=y, Ack=x+z, len=o, ACK 标志

A --->B Syn=x+z, Ack=y+o, len=p, ACK 标志

B --->A Syn=y+o, ACK=x+z+p,len=q, RST, ACK 标志

B 在发送最后一个数据包后关闭套接字,A 在收到它后关闭套接字。

(这里不考虑TCP窗口,否则在确认之前可能会有更多的数据包来自一端)

ACK Flag、确认号和确认的过程是相关的但不是一回事。

根据 RFC793

RFC793

确认编号:32 位

If the ACK control bit is set this field contains the value of the
next sequence number the sender of the segment is expecting to
receive.  Once a connection is established this is always sent.

重置处理

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

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