2017年3月,内核主线将TCP Metrics
表项中的时间戳缓存,补丁详见patch---tcp: remove per-destination timestamp cachelinux
struct tcp_metrics_block { struct inetpeer_addr tcpm_saddr; struct inetpeer_addr tcpm_daddr; unsigned long tcpm_stamp; - u32 tcpm_ts; - u32 tcpm_ts_stamp; u32 tcpm_lock; u32 tcpm_vals[TCP_METRIC_MAX_KERNEL + 1];
与之一块儿修改的,还有tcp: remove tcp_tw_recycle。tcp_tw_recycle
机制是用于内核快速回收TIME_WAIT状态的套接字。可是当网络中存在NAT设备时,该机制反而可能会致使NAT设备背后的客户端难以链接上服务器。git
这样的问题实在太多了!网络上随便一搜就是
No response to some SYN packets when timestamps are enabled
Why would a server not send a SYN/ACK packet in response to a SYN packet
why-does-my-linux-box-fail-to-send-syn-ack-until-after-eight-syns-have-arrived?缓存
致使这些问题的缘由是服务器收到的SYN报文中携带的时间戳早于以前已经收到的FIN报文的时间戳,因而服务器认为该SYN报文是因为网络阻塞迟到的旧链接的SYN报文的重传,因而拒绝恢复SYN-ACK。出现这种状况的缘由是传输链路上存在NAT设备。而缓存FIN报文时间戳的TCP Metrics
是Per-Destination
的,在有NAT的环境中,服务器看到的Destination
是NAT设备,它看不到NAT设备背后还有多大的内部网络,内部网路的每台主机上没法保证SYN报文的时间戳递增。服务器
固然,若是和我同样,不能升级内核, 那么不打开tcp_tw_recycle
也是一个选择网络
tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4) Enable fast recycling of TIME_WAIT sockets. Enabling this option is not recommended for devices communicating with the general Internet or using NAT (Network Address Translation).Since some NAT gateways pass through IP timestamp values, one IP can appear to have non-increasing timestamps. See RFC 1323 (PAWS), RFC 6191.