TCP 之 FIN_WAIT_2状态处理流程

概述

在主动关闭方发送了FIN之后,进入FIN_WAIT_1状态,在此状态收到了ACK,则进入FIN_WAIT_2状态,而FIN_WAIT_2后续要做的工作是等待接收对端发过来的FIN包,并且发送ACK,进而进入到TIME_WAIT状态;本文主要关注从FIN_WAIT_1进入FIN_WAIT_2状态,以及在FIN_WAIT_2状态来包或者定时器触发后的处理流程;

进入FIN_WAIT_2

tcp_rcv_state_process函数中对于ack的处理步骤中,假如连接处于FIN_WAIT_1,且数据均已经被确认完,则进入TIME_WAIT_2状态;如果无需在该状态等待(linger2<0),或者收到了乱序数据段,则直接关闭连接;如果需要等待,则需要判断等待时间与TIMEWAIT时间的大小关系,若>TIMEWAIT_LEN,则添加TIME_WAIT_2定时器,否则直接进入TIME_WAIT接管(其子状态仍然是FIN_WAIT_2),接管之后会添加TIME_WAIT定时器;

另,tcp_close函数调用时,如果当前状态是FIN_WAIT_2也会用相似方式进入TIME_WAIT接管,不再单独介绍;

 

状态转换触发

FIN_WAIT_2状态的走向有以下几个流程触发点,(1)TIME_WAIT_2定时器未超时时间内,收到数据段触发; (2)TIME_WAIT_2定时器超时触发; (3)TIME_WAIT定时器未超时时间内,收到数据段触发; (4)TIME_WAIT定时器超时触发;

(1) TIME_WAIT_2定时器未超时时间内,收到数据段触发,如果设置FIN标记,则直接进入TIME_WAIT状态;

在函数tcp_rcv_state_process处理数据段的过程中,FIN_WAIT_2状态最终会调用tcp_data_queue来处理数据段;

 

tcp_data_queue在处理数据段的时候,有对FIN标记的检查,如果有该标记,则进入tcp_fin函数;

 

tcp_fin函数中,如果此时连接状态为FIN_WAIT_2,则发送ACK,并且直接进入TIME_WAIT状态;在tcp_time_wait函数处理中,会删除当前控制块,所以FIN_WAIT_2定时器也就不存在了;

 

(2)TIME_WAIT_2定时器超时触发,如果linger2<0,或者等待时间<=TIMEWAIT_LEN,直接发送reset关闭连接;如果linger2>=0,且等待时间>TIMEWAIT_LEN,则进入TIME_WAIT接管;

 

(3)TIME_WAIT定时器未超时时间内,收到数据段触发,若收到合法的FIN,则进入真正的TIME_WAIT状态;

tcp_v4_rcv收入数据段过程中,会对TIME_WAIT状态做特别处理,而对于TIME_WAIT子状态的处理在函数tcp_timewait_state_process中;

 

tcp_timewait_state_process函数处理流程中,如果TIME_WAIT的子状态为FIN_WAIT_2,并且收到了合法的FIN之后,会进入真正的TIME_WAIT状态,即子状态也为TIME_WAIT,并且设置TIME_WAIT定时器;

 

(4)TIME_WAIT定时器超时触发,定时器超时,将tw控制块从ehash和bhash中删除,在收到数据段会发送reset;

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

 

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

 

 

本文链接:TCP 之 FIN_WAIT_2状态处理流程

转载声明:转载请注明来源:Linux TCP/IP Stack,谢谢!


发表评论

电子邮件地址不会被公开。 必填项已用*标注