TCP为每条连接先后设置9个定时器,分别为:SYN-ACK定时器、重传定时器、丢失探测(LOSS_PROBE)定时器、ER(Early 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_timer、icsk_retransmit_timer、icsk_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_timer,icsk_retransmit_timer对应的超时函数是tcp_write_timer,icsk_delack_timer对应的超时函数是tcp_delack_timer。tcp_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
超时的时候定时器做了什么