The TCP handshake that is asked every time a big factory interviews, I am stunned by the interviewer's answer, and I will understand it after reading it once.

In the TCP three-way handshake, the ack confirmation number received by the client in the second handshake is not what it expects, what will happen? Should it directly discard or return the RST message?
Under what circumstances will an incorrect ack (ack in the second handshake) be received?
Answer to the question
Don't make a fuss, just answer the question directly, and return the RST message. The process is as follows:

picture

Three-way handshake to avoid historical connections

When the client sends multiple SYN messages to establish a connection continuously, and then the network is congested, the client may receive an incorrect ack. The specific process is as follows:

The client first sent a SYN (seq = 90) message, but it was blocked by the network, and the server did not receive it. Then the client resent the SYN (seq = 100) message. Note that it is not a retransmission of the SYN, but a retransmission The serial number of the transmitted SYN is the same.
The "old SYN message" arrived at the server earlier than the "latest SYN" message, then the server will return a SYN + ACK message to the client at this time, and the confirmation number of this message is 91 (90+1 ).
After the client receives it, the confirmation number it expects to receive should be 100+1 instead of 90+1, so it will return a RST message.
After the server receives the RST message, it will terminate the connection.
After the latest SYN arrives at the server, the client and the server can normally complete the three-way handshake.
The "old SYN message" in the above is called a historical connection. The main reason why TCP uses a three-way handshake to establish a connection is to prevent the "historical connection" from initializing the connection.

We can also know from RFC 793 the primary reason why a TCP connection uses a three-way handshake:

The principle reason for the three-way handshake is to prevent old duplicate connection initiations from causing confusion.

In simple terms, the number one reason for the three-way handshake is to prevent confusion from old repeated connection initializations. The case diagram of the three-way handshake preventing historical connections given by RFC is as follows:

picture

RFC 793

If it is a two-way handshake connection, the historical connection cannot be blocked, so why can't the TCP two-way handshake prevent the historical connection?

Let me directly state the conclusion first, mainly because in the case of two handshakes, the "passive initiator" has no intermediate state for the "active initiator" to prevent the historical connection, which may cause the "passive initiator" to establish a historical connection, resulting in resources waste.

Think about it, in the case of two handshakes, the "passive initiator" enters the ESTABLISHED state after receiving the SYN message, which means that it can send data to the other party at this time, but the "active initiator" is still in the ESTABLISHED state at this time. If it does not enter the ESTABLISHED state, assuming that this is a historical connection, the active initiator judges that this connection is a historical connection, then it will return an RST message to disconnect, and the "passive initiator" will It enters the ESTABLISHED state, so it can send data, but it does not know that this is a historical connection, and it will only disconnect after receiving the RST message.

picture

Two-way handshake fails to block historical connections

It can be seen that in the above scenario, the "passive initiator" did not block the historical connection before sending data to the "active initiator", causing the "passive initiator" to establish a historical connection and send data in vain , properly wasting the resources of the "passive initiator".

Therefore, to solve this phenomenon, it is best to block the historical connection before the "passive initiator" sends data, that is, before the connection is established, so as not to cause waste of resources, and to realize this function, it takes three times shake hands.

Source code analysis
Do I return RST when I say return to RST? Of course not, the source code must be used to prove the conclusion I said.

Some students may be discouraged when they hear that source code analysis is required.

In fact, to analyze our problem today, as long as you understand if else, I will also use Chinese to express the logic of the code, so it is also possible to simply read my text.

This time we focus on analyzing how to process the syn+ack message with an incorrect confirmation number in the SYN_SENT state.

The client in the SYN_SENT state will finally call tcp_rcv_state_process after receiving the syn+ack message from the server, where it will do corresponding processing according to the TCP state. Here we only focus on the SYN_SENT state.

// net/ipv4/tcp_ipv4.c
int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
{
 ...
  
 int queued = 0;
  
  ...
  
 switch (sk->sk_state) {
 case TCP_CLOSE:
  ...
 case TCP_LISTEN:
  ...
 case TCP_SYN_SENT:
    ....
  queued = tcp_rcv_synsent_state_process(sk, skb, th);
  if (queued >= 0)
   return queued;
    ...
 }


It can be seen that next, the tcp_rcv_synsent_state_process function will continue to be called.

static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
      const struct tcphdr *th)
{
 ....

 if (th->ack) {
  /* rfc793:
   * "If the state is SYN-SENT then
   *    first check the ACK bit
   *      If the ACK bit is set
   *   If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send
   *        a reset (unless the RST bit is set, if so drop
   *        the segment and return)"
   */
    // ack 的确认号不是预期的
  if (!after(TCP_SKB_CB(skb)->ack_seq, tp->snd_una) ||
      after(TCP_SKB_CB(skb)->ack_seq, tp->snd_nxt))
      //回 RST 报文
   goto reset_and_undo;

  ...
}


From the above function, we can know that in the SYN_SENT state, the client will return a RST message if it receives a syn+ack message with an incorrect confirmation number.

Summary
In the TCP three-way handshake, the ack confirmation number received by the client in the second handshake is not what it expects, what will happen? Should it directly discard or return the RST message?

Return RST message.

Under what circumstances will an incorrect ack (ack in the second handshake) be received?

When the client sends multiple SYN packets and the network is congested, the "old SYN packet" arrives at the server earlier than the "new SYN packet", and the server will follow the received "old SYN packet". "SYN message" to reply a syn+ack message, but the acknowledgment number of this message is not what the client expects to receive, so the client will return a RST message.

Guess you like

Origin blog.csdn.net/weixin_42450130/article/details/130024661