TCP定时器 之 FIN_WAIT_2定时器

当TCP主动关闭一端调用了close()来执行连接的完全关闭时会执行以下流程,本端发送FIN给对端,对端回复ACK,本端进入FIN_WAIT_2状态,此时只有对端发送了FIN,本端才会进入TIME_WAIT状态,为了防止对端不发送关闭连接的FIN包给本端,将会在进入FIN_WAIT_2状态时,设置一个FIN_WAIT_2定时器,如果该连接超过一定时限,则进入CLOSE状态;

注意:上述是针对close调用完全关闭连接的情况,shutdown执行半关闭不会启动FIN_WAIT_2定时器;

启动定时器:

close系统调用关闭连接最终会调用到tcp_close函数,其中当状态为TCP_FIN_WAIT2时,如果有设置该状态等待时间linger2,且等待时间大于TCP_TIMEWAIT_LEN则启动FIN_WAIT_2定时器;

 1 void tcp_close(struct sock *sk, long timeout)
 2 {
 3     if (sk->sk_state == TCP_FIN_WAIT2) {
 4         struct tcp_sock *tp = tcp_sk(sk);
 5         if (tp->linger2 < 0) {
 6             tcp_set_state(sk, TCP_CLOSE);
 7             tcp_send_active_reset(sk, GFP_ATOMIC);
 8             __NET_INC_STATS(sock_net(sk),
 9                     LINUX_MIB_TCPABORTONLINGER);
10         } else {
11             const int tmo = tcp_fin_time(sk);
12 
13             if (tmo > TCP_TIMEWAIT_LEN) {
14                 inet_csk_reset_keepalive_timer(sk,
15                         tmo - TCP_TIMEWAIT_LEN);
16             } else {
17                 tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
18                 goto out;
19             }
20         }
21     }
22 }

 

定时器回调函数:

定时器超时会调用tcp_keepalive_timer处理函数,当连接处于FIN_WAIT_2状态,且socket即将关闭,则继续判断FIN等待时间,若有剩余时间,则进入tcp_time_wait函数处理;否则发送rst,并关闭连接;

注:因函数是保活定时器和WAIT_2共用的,我们省略了部分WAIT_2无关代码;

 1 static void tcp_keepalive_timer (unsigned long data)
 2 {
 3     /* 省略部分代码 */
 4 
 5     /* 处于fin_wait2且socket即将关闭,用作FIN_WAIT_2定时器 */
 6     if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) {
 7 
 8         /* 停留在FIN_WAIT_2的停留时间>=0 */
 9         if (tp->linger2 >= 0) {
10             /* 获取在FIN_WAIT_2时间与TIMEWAIT时间差 */
11             const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN;
12 
13             /* 时间差>0,则进入TIME_WAIT状态 */
14             if (tmo > 0) {
15                 tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
16                 goto out;
17             }
18         }
19 
20         /* 发送rst */
21         tcp_send_active_reset(sk, GFP_ATOMIC);
22         goto death;
23     }
24 
25     /* 省略部分代码 */
26 }

 

tcp_time_wait后续补充;

 

posted @ 2019-10-27 22:19  AlexAlex  阅读(914)  评论(0编辑  收藏  举报