TCP定时器 之 TIME_WAIT定时器

概述

在FIN_WAIT_2收到对端发来的FIN,并回复ACK之后,会进入TIME_WAIT状态,此时添加定时器,定时器超时会将tw控制块从ehash和bhash中删除,并且释放tw控制块;

启动定时器

TIME_WAIT定时器主要通过inet_twsk_schedule函数进行启动;

tcp_rcv_state_process函数中,在FIN_WAIT_2状态下,收到对端发来的FIN,并且向对端回复了ACK之后,会调用tcp_time_wait函数进入真正的TIME_WAIT状态,此时会创建TIME_WAIT控制块,创建之后调用inet_twsk_schedule启动定时器;

调用关系如下:

1 /**
2  * tcp_rcv_state_process
3  *    |-->tcp_time_wait
4  *           |-->inet_twsk_alloc
5  *           |      |-->setup_pinned_timer(&tw->tw_timer, tw_timer_handler,(unsigned long)tw);
6  *           |-->__inet_twsk_schedule(tw, timeo, false);
7  *                  |-->mod_timer(&tw->tw_timer, jiffies + timeo);
8  */
定时器回调函数

定时器超时会进入到tw_timer_handler处理函数,该函数在统计信息之后,调用inet_twsk_kill;

 1 static void tw_timer_handler(unsigned long data)
 2 {
 3     struct inet_timewait_sock *tw = (struct inet_timewait_sock *)data;
 4 
 5     if (tw->tw_kill)
 6         __NET_INC_STATS(twsk_net(tw), LINUX_MIB_TIMEWAITKILLED);
 7     else
 8         __NET_INC_STATS(twsk_net(tw), LINUX_MIB_TIMEWAITED);
 9     inet_twsk_kill(tw);
10 }

inet_twsk_kill从ehash和bhash中把tw控制块删除,并且释放之;

 1 static void inet_twsk_kill(struct inet_timewait_sock *tw)
 2 {
 3     struct inet_hashinfo *hashinfo = tw->tw_dr->hashinfo;
 4     spinlock_t *lock = inet_ehash_lockp(hashinfo, tw->tw_hash);
 5     struct inet_bind_hashbucket *bhead;
 6 
 7     spin_lock(lock);
 8     sk_nulls_del_node_init_rcu((struct sock *)tw);
 9     spin_unlock(lock);
10 
11     /* Disassociate with bind bucket. */
12     bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), tw->tw_num,
13             hashinfo->bhash_size)];
14 
15     spin_lock(&bhead->lock);
16     inet_twsk_bind_unhash(tw, hashinfo);
17     spin_unlock(&bhead->lock);
18 
19     atomic_dec(&tw->tw_dr->tw_count);
20     inet_twsk_put(tw);
21 }

猜你喜欢

转载自www.cnblogs.com/wanpengcoder/p/11749491.html