删除服务器IP后客户端与服务器之间的TCP通信

删除服务器IP后客户端与服务器之间的TCP通信

我创建了一个监听 [IP1:PORT1] 的 tcp 服务器,并使用 [IP2] 通过客户端连接到它。在客户端和服务器上,SO_KEEPALIVE 和 TCP_USER_TIMEOUT 均使用以下配置值启用。

TCP_KEEPIDLE = 1
TCP_KEEPINTVL = 1
TCP_KEEPCNT = 4
TCP_USER_TIMEOUT = 5000

在我捕获的 TCPdump 中,我看到以下内容:

  1. 开始时客户端和服务器之间发生 3 次握手(syn-synack-ack)。
  2. 每 1 秒后,客户端和服务器都会生成 Keepalive 数据包,并且相应的对等方会发送 ack 作为响应。

一切都在按照我的预期发生。但是现在我使用以下命令删除了服务器IP(IP1):

/sbin/ip addr del IP1 dev DEV

删除 IP 后,我在跟踪中观察到以下内容:

  1. Keepalive 数据包继续从两个实体(客户端和服务器)发送。令人惊讶的是,即使底层 IP 已被删除,服务器仍然会发送 keepalive 数据包!

  2. 客户端通过确认来响应服务器发送的保活数据包。

  3. 服务器不会对客户端发送的任何保活数据包发送确认。

  4. 大约 4 秒后,服务器 IP(IP1) 向客户端发送 [RST,ACK],之后不再发生数据包交换。

所以我从上面不明白两件事:

  1. 为什么服务器 IP 被删除后,通信仍能持续一段时间?
  2. 为什么服务器能够向客户端发送 Keepalive 数据包,但无法向客户端发送 keepalive ack?

操作系统:红帽企业 Linux 版本 8.3

答案1

答案非常模糊,但它应该让您朝着正确的方向进行更多调查:

当建立 TCP 连接时,内核会设置有关该连接的数据结构。从接口中删除 IP 地址并不一定会完全删除此信息(因为我认为没有人会关心这种情况,通常在删除 IP 地址之前会关闭所有服务器,显然它确实会被清理掉)最终)。

因此,这些内部数据结构显然可以进行保活交换,ACK 数据包不会生成或通过,直到某些事件触发(可能是因为连接现在被认为已失效)并且整个连接状态被收集。

如果您想了解详细信息,请阅读内核代码,找出建立了哪些数据结构,找出删除 IP 地址时哪些结构被删除,哪些保留。

但整件事都是学术性的——你发现了一些没有实际后果的边缘案例行为。

相关内容