名词
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