RST 序列号和窗口大小

RST 序列号和窗口大小

RFC793 对 RST 处理做出如下规定:

在除 SYN-SENT 之外的所有状态下,所有重置 (RST) 段都通过检查其 SEQ 字段进行验证。如果重置的序列号在窗口中,则重置有效。

但我不确定这句话到底是什么意思。假设我有以下场景:

图片 1

因此套接字 2 告诉套接字 1 其窗口大小为 6 KB,然后套接字 1 将 6 KB 的数据发送到套接字 2。

然后套接字 1 向套接字 2 发送一个 RST 数据包:

图片 2

那么,这种情况下会发生什么呢?RST 数据包会被套接字 2 接受吗?

答案1

Linux 仅在 RST 序列号是下一个预期序列号时才拆除 TCP 连接。应用此规则是为了避免盲目 TCP 重置攻击(请参阅RFC 5961 第 3.2 节)。因此适用以下规则:

  1. 如果设置了 RST 位并且序列号超出当前接收窗口,则静默丢弃该段。

  2. 如果设置了 RST 位并且序列号与下一个预期序列号 (RCV.NXT) 完全匹配,则 TCP 必须重置连接。

  3. 如果设置了 RST 位,并且序列号与下一个预期序列值不完全匹配,但在当前接收窗口内(RCV.NXT < SEG.SEQ < RCV.NXT+RCV.WND),则 TCP 必须发送确认(挑战 ACK):

    <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>

因此,如果您处于情况 1,您的 RST 段将被悄悄删除(至少在 Linux 上,这取决于实现,但应该得到尊重)。

答案2

一旦所有数据使用 MTU 值的片段机制从客户端传输到目的地,就会发起 FIN,而不是 RST。

  • FIN:数据传输已完成,没有剩余的数据包。(优雅关闭)
  • RST:我不在此端口上列出/我已超载。(强制关闭)

对于 RST 数据包,序列号是经过验证的,因为 src、dst 和中间设备应该终止会话和连接/状态表条目。

相关内容