9.1 定时器初始化

  TCP为每条连接先后设置9个定时器,分别为:SYN-ACK定时器、重传定时器、丢失探测LOSS_PROBE定时器、EREarly Retransmit定时器、延迟ACK定时器坚持定时器、保活定时器、FIN_WAIT2定时器、TIME_WAIT定时器。由于一些定时器不能同时设置,故TCP使用了5个定时器结构完成全部9个定时器的功能。相关数据结构如下:

 285 struct sock {
...
381     struct timer_list   sk_timer;//用于保活定时器、SYN-ACK定时器、FIN_WAIT2定时器
...
include/net/inet_connection_sock.h
 87 struct inet_connection_sock {
...
 93     struct timer_list     icsk_retransmit_timer;//用于重传定时器、丢失探测定时器、ER定时器、坚持定时器
 94     struct timer_list     icsk_delack_timer;//用于延迟ACK定时器
...
include/net/inet_timewait_sock.h
 66 struct inet_timewait_death_row {
...
 70     struct timer_list   twcal_timer;//用于TIME_WAIT定时器
...
 78     struct timer_list   tw_timer;//用于TIME_WAIT定时器
...
   sk_timericsk_retransmit_timericsk_delack_timer的初始化在tcp_init_xmit_timers中完成:

643 void tcp_init_xmit_timers(struct sock *sk)
644 {
645     inet_csk_init_xmit_timers(sk, &tcp_write_timer, &tcp_delack_timer,
646                   &tcp_keepalive_timer);
647 }
   inet_csk_init_xmit_timers函数:
370 void inet_csk_init_xmit_timers(struct sock *sk,
371                    void (*retransmit_handler)(unsigned long),
372                    void (*delack_handler)(unsigned long),
373                    void (*keepalive_handler)(unsigned long))
374 {       
375     struct inet_connection_sock *icsk = inet_csk(sk);
376
377     setup_timer(&icsk->icsk_retransmit_timer, retransmit_handler,
378             (unsigned long)sk);
379     setup_timer(&icsk->icsk_delack_timer, delack_handler,
380             (unsigned long)sk);
381     setup_timer(&sk->sk_timer, keepalive_handler, (unsigned long)sk);
382     icsk->icsk_pending = icsk->icsk_ack.pending = 0;
383 }   
   sk_timer对应的超时函数是tcp_keepalive_timericsk_retransmit_timer对应的超时函数是tcp_write_timericsk_delack_timer对应的超时函数是tcp_delack_timertcp_init_xmit_timers会在每个socket初始化时被调用。

  TIME_WAIT相关定时器的初始化在全局变量tcp_death_row的定义时完成:

 35 struct inet_timewait_death_row tcp_death_row = {
...  
 40     .tw_timer   = TIMER_INITIALIZER(inet_twdr_hangman, 0,
 41                         (unsigned long)&tcp_death_row),
...
 47     .twcal_timer    = TIMER_INITIALIZER(inet_twdr_twcal_tick, 0,
 48                         (unsigned long)&tcp_death_row),
 49 };
       即tw_timer对应的超时函数是inet_twdr_hangman,twcal_timer对应的超时函数是inet_twdr_twcal_tick。

  所有的TCP定时器数的执行上下文都是软中断。

  关于定时器的分析会按照以下结构展开:

(1)Why

  为什么要有这个定时器

(2)When

  何时设置、清除定时器,以及定时器何时超时‘

(3)What

  超时的时候定时器做了什么

你可能感兴趣的:(网络,tcp,linux内核)