全部博文(41)
分类: LINUX
2009-08-13 14:46:36
tcp.c文件的tcp_write_timeout函数
978计划工作组
/*
* A write timeout has occurred. Process the after effects.
*/
static int tcp_write_timeout(struct sock *sk)
{
/*
* Look for a 'soft' timeout.
*/
if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
|| (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1))
{
/*
* Attempt to recover if arp has changed (unlikely!) or
* a route has shifted (not supported prior to 1.3).
*/
arp_destroy (sk->daddr, 0);
ip_route_check (sk->daddr);
}
/*
* Has it gone just too far ?
*/
if (sk->retransmits > TCP_RETR2)
{
sk->err = ETIMEDOUT;
sk->error_report(sk);
del_timer(&sk->retransmit_timer);
/*
* Time wait the socket
*/
if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING )
{
tcp_set_state(sk,TCP_TIME_WAIT);
reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
}
else
{
/*
* Clean up time.
*/
tcp_set_state(sk, TCP_CLOSE);
return 0;
}
}
return 1;
重传定时器发生超时时被调用,根据套接字当前状态以及超时次数对该套接字进行相应处理。
sk->state:套接字当前状态。
TCP_ESTABLISHED:连接建立状态,双方进行正常的数据传送所处的状态。
TCP_RETR1:是常数7,表示在丢弃本地数据包前尝试发送的次数。如果重传次数超过TCP_RETR1,则重新进行远端主机ARP请求,监测是否远端主机MAC 地址发生变换。
sk->retransmits:重传次数。
sk->daddr:远端地址。
0:如ATF_PERM标志位被设置表示这是一个用户设置的永久表项,那么此表项不能删除。
arp_destroy:删除一个arp_tables的一个表项,删除条件是与sk->daddr匹配。
ip_route_check:此函数未实现。
TCP_RETR2:是常数15,如果重传次数超出TCP_RETR2则直接丢弃发送的数据包,放弃发送。
sk->err:错误类型值。
ETIMEDOUT:错误码,值为110,过时了的连接,可能是中间路由器坏等导致。
error_report:回调函数,被初始化为def_callback1,def_callback1的功能是将相关进程状态重新设置为TASK_RUNNING,使得进程具备调度的资格。
retransmit_timer:TCP重传计时器。
del_timer:删除重传计时器。
TCP_FIN_WAIT1:本地发送FIN(用于结束连接的)数据包后即进入该状态,等待对方的应答,此时发送通道被关闭,但仍可以继续接收远端发送的数据包。在接收到远端发送的对于FIN 数据包的应答后,将进入TCP_FIN_WAIT_2 状态。
TCP_FIN_WAIT2:进入该状态表示本地已接收到远端发送的对于本地之前发送的FIN 数据包的应答。进入该状态后,本地仍然可以继续接收远端发送给本地的数据包。在接收到远端发送的FIN 数据包后(表示远端也已经发送完数据),本地将发送一个应答数据包,并进入TCP_TIME_WAIT 状态。
TCP_CLOSING:如果通信双方同时发送FIN 数据包,即同时进行关闭操作,则双方将同时进入TCP_CLOSING状态。具体的,本地发送一个FIN 数据包以结束本地数据包发送,如果在等待应答期间,接收到远端发送的FIN 数据包,则本地将状态设置为TCP_CLOSING 状态。在接收到应答后,再继续转入到TCP_CLOSE_WAIT 状态。
TCP_TIME_WAIT:该状态被称为2MSL 等待状态。如果在此期间接收到远端发送的FIN 数据包,则表示之前在TCP_FIN_WAIT_2 状态发送的ACK 应答数据包在传输中丢失或者长时间被延迟,从而造成远
端重新发送了FIN 数据包,此时重发ACK 应答数据包。一旦2MSL 时间到期,则将进入TCP_CLOSE 状态,即完成关闭操作。
TIME_CLOSE:此为定时类型,2MSL 定时,宏值为2,赋给sock的timeout域。
TCP_TIMEWAIT_LEN:超时的时间长度,此值小于0则系统会给个默认值3,通常是60秒。
tcp_set_state:设置TCP的当前状态。
reset_msl_timer:是一个宏函数,宏展开后是调用reset_timer函数,此函数将TCP_TIMEWAIT_LEN的值赋给计时器的expires,并把该sock结构的timer加到系统的计时器队列,如果在加入前已经在计时器队列那么需要先从队列中移出后再加入。
TCP_CLOSE:关闭状态,一个新建的TCP 套接字起始将处于该状态。