Hello, I’m Xiao Lin.

I got a question from a reader who was stumped during an interview for a goose factory when the interviewer asked him this online question:

I have to say, Goose factory really likes to ask network questions, and love to ask network questions under unusual circumstances, before there was another reader interview goose factory network questions:”I’m afraid of the goose factory!”.

If a FIN packet arrives at the client before the packet, the FIN packet is an out-of-order packet and the TCP connection on the client does not change from FIN_WAIT_2 state to TIME_WAIT state.

Therefore, we have to focus on the point is to see.”In FIN_WAIT_2 state, how do I process the received out-of-order FIN packets, and when do TCP connections enter the TIME_WAIT state?“.

I’ll jump to the conclusion:

In the FIN_WAIT_2 state, if an out-of-order FIN packet is received, the packet is added to the out-of-order queue and does not enter the TIME_WAIT state.

Such as front by network latency packet received again, make order queue to have data, then detects whether there is data available in the order queue, if you can find in the order queue with the serial number of the current message to keep the order of the message, will look at the newspaper article FIN logo, if found to have a FIN logo, At this point, the TIME_WAIT state is entered.

I’ve drawn a picture, too, so you can kind of relate it to the picture.

TCP source code analysis

Next, I take you to look at the source code, to hear the source code analysis, some students may be afraid.

In fact, to analyze our question today, you only need to understand if else. I can also express the logic of the code in Chinese, so it is ok to just look at my words.

This time, we analyze how to process the received FIN packet in FIN_WAIT_2 state.

In the Linux kernel, when the IP layer finishes processing the message, it forwards the message to the TCP layer through the tcp_v4_rCV function, so this function is the TCP layer to receive the message entry.

The client in FIN_WAIT_2 state invoics the tcp_v4_do_rCV function after receiving the packet from the server.

Next, the tcp_V4_DO_rCV method calls tcp_RCv_state_process, which does the processing based on the TCP state, focusing on the FIN_WAIT_2 state.

In the above code, you can see that if shutdown disables the read direction, RST packets will be returned when received.

In our case, shutdown only turns off the write direction, so we continue to call tcp_data_queue (because the case TCP_FIN_WAIT2 block does not have a break statement, so we go to this function).

In the tcp_data_queue function above, if the sequence number of the received packets is expected, that is, in order:

  • Determines if the packet has a FIN flag, and if so, calls the tcp_fin function, which converts the FIN_WAIT_2 state to TIME_WAIT.
  • If so, the tcp_ofo_queue function is called. This function checks to see if there are any packets available in the out-of-order queue, that is, to find packets in the out-of-order queue that have serial numbers consistent with the current packet.

When the sequence number of the received packet is not expected, that is, out of order, the tcp_data_queue_OFo function is called and the packet is added to the out of order queue. The data structure of the queue is red-black tree.

In our topic, the FIN packet received by the client is actually an out-of-order packet. Therefore, the tcp_FIN function is not called for state conversion, but the packet is added to the out-of-order queue through the tcp_data_queue_OFo function.

After receiving the packet delayed by the network, the client invoks the tcp_ofo_queue function because the sequence number of the packet is expected and the last received out-of-order FIN packet is added to the out-of-order queue, indicating that the out-of-order queue contains data.

Let’s look at the tcp_ofo_queue function.

In the tcp_ofo_queue function above, the tcp_fin() function is called after finding the packets in the out-of-order queue that can keep the sequence number of the current packets.

Finally, let’s look at the handling of the tcp_fin function.

As you can see, if the current TCP state is TCP_FIN_WAIT2, the fourth wave ACK is sent and tcp_time_wait is called. This function changes the TCP state to TIME_WAIT and starts the TIME_WAIT timer.

How to read TCP source code?

Before many students asked me, HOW do I read TCP source code?

In fact, I look at TCP source, not directly open Linux source directly to see, because Linux source code is too large, if I do not know where the TCP entry function, it is simply looking for a needle in a haystack.

So, in the TCP source code, we can go to the Internet to search for other people’s source code analysis, there have been a lot of predecessors on the Internet to help us analyze the TCP source code, and each function call link, they have written out.

For example, if you want to know the TCP three-handshake/four-wave source implementation, you can use the keyword “TCP three-handshake/four-wave source analysis” to search, most of the article’s comments are still very clear, I started in this way to learn TCP source.

Articles on the Internet usually only include the important parts, and many code details are not posted. If you want to see all the code of a function, you have to look at the kernel code.

Here is a recommended online site to see the Linux kernel code:

Elixir.bootlin.com/linux/lates…

I think it is very good to use, the left side of each version of the code, the upper right corner can also search for functions.

So, I think the experience of the TCP source is, first look for elder write online TCP source code analysis, and then know that the entire function call link, if you want to know the detailed implementation of a function, can in I said that the Linux kernel code search the function of online web site, you can see the realization of the complete function. If you don’t understand the code, you can also copy the code to Baidu or Google search, generally can also find other people’s analysis process.

Learned to see THE TCP source code actually helps us to analyze some abnormal problems, such as today’s network topic, in fact, is not the answer to search on the Internet, and we are also difficult to use the experimental way to simulate.

So if you want to know the answer, you can only look at the source code.


That’s all for now, and we’ll see you next time!