tcp

名词

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

  1. retransmission
    tcp对发送的数据会启动一个timer,如果指定时间内没有收到发送数据对应的ACK,tcp会重新发送数据。timer根据RTT和重传的次数动态调整超时时间
  2. delay ACK
    tcp收到对方的数据后,可以延迟一段时间再回复接收数据的ACK,如果这段时间内有发送的数据,可以和数据一同发送
  3. keep alive
    tcp如果长时间空闲的话,要定时发送keep alive的数据包,防止对方关闭连接
  4. persist probe
    数据量大的时候,接收方可能会出现接收窗口为0的情况,这时如果发送方还有等待发送的数据,就要使用timer不停的探测对方的窗口信息,以便对方接收窗口可用后继续发送数据
  5. FINWAIT-2
    tcp进入此状态后,要打开一个timer,在对方始终不发送FIN的情况下,超时后关闭连接
  6. TIME WAIT
    这个timer用于关闭连接
  7. connection
    tcp接到SYN连接请求回复SYN/ACK后,linux并没有为这些没完成三次握手的请求建立完整的tcp_sock,而是以request_sock放在处于listen状态的父tcp_sock的队列中,而且有一个timer会定期扫描这些request_sock,并清除一些长时间没有收到ACK的sock

TIME_WAIT

tcp进入TIME_WAIT状态后,需要等待2MSL的时间才能关闭,主要有两个原因:

  1. 最后的ACK有可能丢失,这时对方可能会重新发送FIN,当收到新的FIN后,tcp要回复ACK,并重新启动timer
  2. 如果不等待直接关闭,这时有可能开启一个使用相同端口的新服务,而如果新tcp收到FIN,会发送RST,这样会给对方造成困扰

Congestion Control

Congestion Control主要用于通信路径的网络流量控制,不同于Flow Control需要考虑接收方的Buffer及处理速度,它控制的是通信路径中整个网络的流量,算法通过cwnd与ssthresh两个变量实现,目前主要有四种算法:

  1. Slow Start
    tcp启动时,为了避免过多的流量对网络造成拥塞,cwnd有一个初始的限定值,通常为一个SMSS,此后每收到一个ACK,cwnd会增加一个SMSS,直到cwnd>=ssthresh。Slow Start不止在启动时使用,当有重传发生时,cwnd会降到初始值,重新启动Slow Start
  2. Congestion Avoidance
    当cwnd>ssthresh时,tcp会启用Congestion Avoidance算法,这时cwnd增加的速率会降低,通常为SMSS*SMSS/cwnd
  3. Fast Retransmit
    当收到重复的ACK但是RTO还没有超时,这时tcp进入Fast Retransmit状态,重传丢失的报文,并重新设定cwnd与ssthresh的值
  4. 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