会不会断开,关键看 net.ipv4.tcp_rfc1337
这个内核参数(默认情况是为 0):
- 如果这个参数设置为 0, 收到 RST 报文会提前结束 TIME_WAIT 状态,释放连接。
- 如果这个参数设置为 1, 就会丢掉 RST 报文。
源码处理如下:
enum tcp_tw_status
tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb,
const struct tcphdr *th)
{
....
//rst报文的时间戳没有发生回绕
if (!paws_reject &&
(TCP_SKB_CB(skb)->seq == tcptw->tw_rcv_nxt &&
(TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq || th->rst))) {
//处理rst报文
if (th->rst) {
//不开启这个选项,当收到 RST 时会立即回收tw,但这样做是有风险的
if (twsk_net(tw)->ipv4.sysctl_tcp_rfc1337 == 0) {
kill:
//删除tw定时器,并释放tw
inet_twsk_deschedule_put(tw);
return TCP_TW_SUCCESS;
}
} else {
//将 TIMEWAIT 状态的持续时间重新延长
inet_twsk_reschedule(tw, TCP_TIMEWAIT_LEN);
}
...
return TCP_TW_SUCCESS;
}
}
TIME_WAIT 状态收到 RST 报文而释放连接,这样等于跳过 2MSL 时间,这么做还是有风险。