如果服务器收到现有连接的重复 SYN,会发生什么?

网络工程 通讯协议 协议理论 联网 传输协议 第4层
2021-07-30 13:37:53

如果服务器收到一个新的 SYN 数据包,它是一个已经建立的连接,它应该怎么做?

我已经看到如果从同一个客户端应用程序收到 2 个 SYN 数据包,服务器端会发生什么?. 那里的示例涵盖了不同的情况:服务器在“正确”SYN 之前接收到重复的先前会话 SYN。在这种情况下,服务器 SYNACK 将错误的会话返回给客户端,然后客户端对错误的会话进行 RST。

答案确实简要提到了这个替代案例,但没有涵盖细节:

如果第 6 行的 SYN 在 RST 之前到达,则在两个方向发送 RST 时可能会发生更复杂的交换。

在那个更复杂的情况下到底发生了什么服务器是立即回复 RST,还是重新确认现有会话,或者其他什么?

更具体地说,这里发生了什么:

    TCP A                                                TCP B

1.  CLOSED                                               LISTEN

2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

3.  SYN-SENT    <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

4.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> ESTABLISHED

5.              ... <SEQ=200><CTL=SYN>               --> ???

                              ???
2个回答

我做了更多的阅读,我发现了一个等效的案例,在 RFC 的其他地方,在“半开放连接和其他异常”下有更详细的介绍。

TCP A 崩溃后,用户尝试重新打开连接。同时,TCP B 认为连接是打开的:


      TCP A                                           TCP B

  1.  (CRASH)                               (send 300,receive 100)

  2.  CLOSED                                           ESTABLISHED

  3.  SYN-SENT --> <SEQ=400><CTL=SYN>              --> (??)

  4.  (!!)     <-- <SEQ=300><ACK=100><CTL=ACK>     <-- ESTABLISHED

  5.  SYN-SENT --> <SEQ=100><CTL=RST>              --> (Abort!!)

  6.  SYN-SENT                                         CLOSED

  7.  SYN-SENT --> <SEQ=400><CTL=SYN>              -->

                     Half-Open Connection Discovery

                               Figure 10.

当 SYN 到达第 3 行时,处于同步状态的 TCP B 和窗口外的传入段以确认响应,指示它接下来希望听到的序列(ACK 100)。TCP A 发现该段不确认它发送的任何内容,并且由于检测到半开连接而未同步,因此发送重置 (RST)。TCP B 在第 5 行中止。

导致这种情况的规则将在后面更详细地描述:

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

因此,为了明确回答我的原始问题:当意外的 SYN 到达时,其序列号将在连接窗口之外,并且它将缺少现有连接的适当确认号,因此服务器应(重新)发送确认现有连接的 ACK连接状态,根本不确认或处理意外的数据包。

这种情况一直发生,以便一台主机与另一台主机建立多个连接(请记住,TCP 没有客户端或服务器;客户端/服务器是一个应用层概念,这里是题外话)。作为RFC 793,传输控制协议解释了:

这些信息(包括套接字、序列号和窗口大小)的组合称为连接。

因为您有一个具有不同序列号的新 SYN,所以您正在创建一个新连接。诸如网络浏览器之类的东西经常这样做,以便同时加载网页的不同部分。

您的示例所做的所有操作都是尝试创建第二个连接。


根据您的评论和答案进行编辑:

您问题中的事件序列不能在同一个连接中,因为您有不同的初始序列号。正如我在上面的 RFC 引用中在我的回答中所解释的那样,序列号是连接的关键部分,并且您正在更改初始序列号,因此它不能成为同一连接的一部分。唯一可能的解释是,这是一个常见的新连接,或者主机的 TCP 实现不好,或者主机上的某些编程故意弄乱 TCP,这些都不是主题或部分TCP协议理论。

如果下一个 SYN 是同一连接的一部分,则它必须具有相同的初始序列号,这意味着您的问题将与您链接的问题相同。不同的初始序列号意味着它是不同的连接,并且几乎每次加载网页时都会发生这种情况。

您的回答实际上涉及一个不同的问题,即关于半开连接的问题。根据其事件顺序,您的问题实际上是关于完全打开的连接,以及主机开始新的连接。

TCP 协议理论在这里是主题,但提出一个超理论问题的问题是题外话。有问题的特定于主机的实现(正确的 TCP 实现不会对同一连接具有不同的初始序列号),或者有目的地尝试破坏 TCP,对于不同的 SE 站点(主机操作系统特定的站点)所做的事情或信息安全)。