名词
RTO: retransmission timeout
RTT: round-trip time
SRTT: smoothed round-trip time
RTTVAR: round-trip time variation
MSL: maximum segment lifetime
SMSS: Sender Maximum Segment Size
Header
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
状态图
+---------+ ---------\ active OPEN | CLOSED | \ ----------- +---------+<---------\ \ create TCB | ^ \ \ snd SYN passive OPEN | | CLOSE \ \ ------------ | | ---------- \ \ create TCB | | delete TCB \ \ V | \ \ +---------+ CLOSE | \ | LISTEN | ---------- | | +---------+ delete TCB | | rcv SYN | | SEND | | ----------- | | ------- | V +---------+ snd SYN,ACK / \ snd SYN +---------+ | |<----------------- ------------------>| | | SYN | rcv SYN | SYN | | RCVD |<-----------------------------------------------| SENT | | | snd ACK | | | |------------------ -------------------| | +---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+ | -------------- | | ----------- | x | | snd ACK | V V | CLOSE +---------+ | ------- | ESTAB | | snd FIN +---------+ | CLOSE | | rcv FIN V ------- | | ------- +---------+ snd FIN / \ snd ACK +---------+ | FIN |<----------------- ------------------>| CLOSE | | WAIT-1 |------------------ | WAIT | +---------+ rcv FIN \ +---------+ | rcv ACK of FIN ------- | CLOSE | | -------------- snd ACK | ------- | V x V snd FIN V +---------+ +---------+ +---------+ |FINWAIT-2| | CLOSING | | LAST-ACK| +---------+ +---------+ +---------+ | rcv ACK of FIN | rcv ACK of FIN | | rcv FIN -------------- | Timeout=2MSL -------------- | | ------- x V ------------ x V \ snd ACK +---------+delete TCB +---------+ ------------------------>|TIME WAIT|------------------>| CLOSED | +---------+ +---------+
Timer
- retransmission
tcp对发送的数据会启动一个timer,如果指定时间内没有收到发送数据对应的ACK,tcp会重新发送数据。timer根据RTT和重传的次数动态调整超时时间 - delay ACK
tcp收到对方的数据后,可以延迟一段时间再回复接收数据的ACK,如果这段时间内有发送的数据,可以和数据一同发送 - keep alive
tcp如果长时间空闲的话,要定时发送keep alive的数据包,防止对方关闭连接 - persist probe
数据量大的时候,接收方可能会出现接收窗口为0的情况,这时如果发送方还有等待发送的数据,就要使用timer不停的探测对方的窗口信息,以便对方接收窗口可用后继续发送数据 - FINWAIT-2
tcp进入此状态后,要打开一个timer,在对方始终不发送FIN的情况下,超时后关闭连接 - TIME WAIT
这个timer用于关闭连接 - connection
tcp接到SYN连接请求回复SYN/ACK后,linux并没有为这些没完成三次握手的请求建立完整的tcp_sock,而是以request_sock放在处于listen状态的父tcp_sock的队列中,而且有一个timer会定期扫描这些request_sock,并清除一些长时间没有收到ACK的sock
TIME_WAIT
tcp进入TIME_WAIT状态后,需要等待2MSL的时间才能关闭,主要有两个原因:
- 最后的ACK有可能丢失,这时对方可能会重新发送FIN,当收到新的FIN后,tcp要回复ACK,并重新启动timer
- 如果不等待直接关闭,这时有可能开启一个使用相同端口的新服务,而如果新tcp收到FIN,会发送RST,这样会给对方造成困扰
Congestion Control
Congestion Control主要用于通信路径的网络流量控制,不同于Flow Control需要考虑接收方的Buffer及处理速度,它控制的是通信路径中整个网络的流量,算法通过cwnd与ssthresh两个变量实现,目前主要有四种算法:
- Slow Start
tcp启动时,为了避免过多的流量对网络造成拥塞,cwnd有一个初始的限定值,通常为一个SMSS,此后每收到一个ACK,cwnd会增加一个SMSS,直到cwnd>=ssthresh。Slow Start不止在启动时使用,当有重传发生时,cwnd会降到初始值,重新启动Slow Start - Congestion Avoidance
当cwnd>ssthresh时,tcp会启用Congestion Avoidance算法,这时cwnd增加的速率会降低,通常为SMSS*SMSS/cwnd - Fast Retransmit
当收到重复的ACK但是RTO还没有超时,这时tcp进入Fast Retransmit状态,重传丢失的报文,并重新设定cwnd与ssthresh的值 - Fast Recovery
在tcp进入Fast Retransmit状态并重传报文后,tcp进入Fast Recovery状态,直至收到重传报文的ACK为止
参考文档:
rfc793: Transmission Control Protocol
rfc1122: Requirements for Internet Hosts – Communication Layers
rfc5681: TCP Congestion Control
rfc6298: Computing TCP’s Retransmission Timer