问题总结
我们有一个设置,其中有很多(每秒800到2400)到Linux盒的传入连接,并且我们在客户端和服务器之间有一个NAT设备。所以系统中还有很多TIME_WAIT套接字。为了克服这个问题,我们将tcp_tw_recycle设置为1,但这会导致连接中断。在浏览了网络之后,我们确实找到了关于为什么使用tcp_tw_recycle和NAT设备会发生帧丢失的参考资料。
解析尝试
然后,我们尝试将tcp_tw_reuse设置为1,在相同的设置和配置下,它工作正常,没有任何问题。
但是文档中说,当通过TCP状态感知节点(如防火墙,NAT设备或负载均衡器)的连接可能会看到丢弃的帧时,不应使用tcp_tw_recycle和tcp_tw_reuse。连接越多,您就越有可能看到此问题。
查询
- tcp_tw_reuse可以用在这种情况下吗?
1.如果不是,linux代码的哪一部分阻止了tcp_tw_reuse用于这种情况? - tcp_tw_recycle和tcp_tw_reuse的区别是什么?
1条答案
按热度按时间u4dcyp6a1#
默认情况下,当
tcp_tw_reuse
和tcp_tw_recycle
都被禁用时,内核将确保处于TIME_WAIT
状态的套接字将保持足够长的时间--足够长的时间以确保属于未来连接的数据包不会被误认为是旧连接的迟到数据包。当您启用
tcp_tw_reuse
时,TIME_WAIT
状态的套接字可以在到期之前使用,内核将尝试确保TCP序列号没有冲突。如果启用tcp_timestamps
(即PAWS,用于防止 Package 序列号),它将确保这些冲突不会发生。然而,你需要在两端都启用TCP时间戳(至少,这是我的理解)。见definition of tcp_twsk_unique的血淋淋的细节。当启用
tcp_tw_recycle
时,内核会变得更加激进,并且会对远程主机使用的时间戳做出假设。它将跟踪在TIME_WAIT
状态下连接的每个远程主机使用的最后一个时间戳,如果时间戳正确增加,则允许重新使用套接字。然而,如果主机使用的时间戳改变(即,时间扭曲),SYN
数据包将被静默丢弃,并且连接不会建立(您将看到类似于“connect timeout”的错误)。如果您想深入了解内核代码,definition of tcp_timewait_state_process可能是一个很好的起点。现在,时间戳不应该回到过去;除非:
TIME_WAIT
套接字可能已经过期,所以这将是一个非问题);TIME_WAIT
连接将保留一点,但其他连接可能会被TCP RST
攻击,这将释放一些空间);*网络地址转换(或聪明的防火墙)在连接的中间。
在后一种情况下,您可以在同一个IP地址后面有多个主机,因此,不同的时间戳序列(或者,防火墙在每个连接处随机化所述时间戳)。在这种情况下,一些主机将随机无法连接,因为它们Map到服务器的
TIME_WAIT
存储桶具有较新时间戳的端口。这就是为什么文档告诉你“NAT设备或负载均衡器可能会因为设置而开始丢弃帧”。有些人建议不使用
tcp_tw_recycle
,但启用tcp_tw_reuse
和更低的tcp_fin_timeout
。I concur:-)