TCP retransmission mechanism 1

The TCP retransmission mechanism is an important mechanism to ensure the correctness of TCP transmission, and it is also an error-prone place in network transmission. Therefore, for how Linux implements TCP retransmission, it is necessary to carefully analyze its code implementation and working mechanism.

1 TCP retransmission classification

TCP retransmission can be divided into two categories: retransmission over time (RTO) and fast retransmission (Fast Recovery). Fast retransmission can also be divided into two categories: reno retransmission without sack and sack retransmission. So we can divide retransmission into three categories: 1) Reno retransmission, 2) Sack retransmission and 3) RTO retransmission

This article mainly introduces retransmission types 1 and 2.

2 TCP function call process

Retransmission occurs in the case of packet loss. Before entering retransmission, it is necessary to determine whether the received ACK meets the expectations. When the ACK (dup ACK) of the apparent packet loss is received, TCP still works according to its function call flow. Therefore, let's first review the overall calling relationship of TCP functions, as shown in the following figure:

The work flow of the congestion control algorithm is not reflected in the figure, so I will briefly talk about it here.

In tcp_ack( ), tcp_may_raise_cwnd( ) is used to determine whether to execute tcp_cong_avoid( ) to grow the window.

After entering the judgment execution, the tcp_cong_avoid function of the register will be used to set the window growth.

When it is about to exit tcp_ack( ), tcp_update_pacing_rate( ) will be executed to update the packet sending rate.

3 Quick recovery

For retransmission types 1 and 2, it will call tcp_fastretrans_alert( ) in the tcp_ack( ) function to process suspicious ack messages (including dup acks), and whether to enter fast recovery requires tcp_fastretrans_alert( ) to call time_tcp_time_to_recover( ) to judge .

In the original TCP protocol stack, it is divided into the following six cases to determine whether to quickly enter the retransmission (recovery) stage.

  1. Confirmed as lost packets ( tp->lost_out )
  2. The number of Duplicate ACKs is greater than the threshold ( tcp_dupack_heuristics( tp ) > tp->reordering )
  3. If RFC2988 is used, determine whether the head of the queue has timed out
  4. If the above conditions are not met, but there are too many sacked_out, and there is no message that can be sent
  5. If it is a thin stream, then retransmit as long as there is a duplicate ack (only for sack)
  6. Judgment of early retransmission based on RFC5827

The revised protocol stack has made new arrangements, as follows:

  1. Delete the judgment of condition 3, the original code is
  2. Add the judgment condition for early retransmission, the code is as follows:


    The added code handles the case where the packet_out is greater than the threshold: after delaying the period_rtt time, determine whether to perform early retransmission.

The above are the judgment conditions for entering the recovery stage in tcp_fastretrans_alert.

When the judgment is satisfied, execute the tcp_enter_recovery( ) function, which will first initialize the window reduction ( tcp_init_cwnd_reduction ), and then set tcp_ca_state ( open:0, disorder:1, cwr:2, recovery:3, loss:4) to TCP_CA_Recovery. Finally exit the function and return to tcp_ack( ).

In tcp_ack( ), the next function tcp_xmit_recovery( ) is executed, which calls tcp_xmit_retransmit_queue( ) to retransmit lost packets.

The lost message found is stored in sk_buff skb. If the skb to be retransmitted is tcp_send_head, then the message is sent directly in the tcp_write_xmit( ) function; if not, then call tcp_retransmit_skb( ) -> __tcp_retransmit_skb( ) -> tcp_transmit_skb( ) to send the retransmitted message.

The above is how to enter the process of fast recovery and retransmission of lost packets, involving retransmission types 1 and 2. Summarizing the above content, the following function call relationship can be obtained:

Through code comparison, there is not much difference between sack and reno ack in the processing of entering fast recovery, except that after identifying the thin stream, sack can perform recovery faster. Here are some additional working mechanisms:

1 In addition to retransmitting the message, TCP also needs to reset the window value. After executing tcp_fastretrans_alert( ), tcp_cong_control will be executed, which will execute tcp_cwnd_reduction( ) according to tcp_ca_state to reduce the sending window (this section is based on the process above kernel 4.0, and is suitable for BBR analysis).

  1. In addition to retransmitting the message, TCP also needs to reset the window value. Before executing tcp_fastretrans_alert( ), tcp will first execute tcp_cong_avoid( ) to set the window. If retransmission is entered, tcp_init_cwnd_reduction( ) will be executed to reduce ssthresh.
  2. After entering fast recovery, the setting of the sending window is calculated according to the function tcp_cwnd_reduction( ), which will set the window size according to the accepted dup ack and the reduced ssthresh.
  3. To exit fast recovery, it is still judged to exit in tcp_fastretrans_alert( ), and execute tcp_end_cwnd_reduction( ), and set tcp_ca_event (passed to the congestion control interface) to CA_EVENT_COMPLETE_CWR .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325988067&siteId=291194637