Can the three handshake process established by the TCP connection carry data?

Source: Internet
Author: User
Tags ack

A few days ago, the lab group threw out a question:can the three handshake process built by a TCP connection carry data? suddenly found that they really do not know this problem, on weekdays with tcpdump or Wireshark grab bag, never notice the third handshake ACK Packet has no data. So hurriedly with NC with Tcpdump grabbed a few packs want to test. But after many experiments, it was true that the third handshake had no other data (explained later). Later in the inquiry found that the process is problematic, so the process and conclusion of the reorganization of the study into this article, for later reference.

First, a three-time handshake diagram (the following picture from the network, if the infringement of the author's rights, please contact me to delete):

The process package with the SYN flag in the RFC793 document is not portable, that is, the first two of the three handshakes are not portable (logically, the connection has not been established, and carrying the data seems to be a bit justified). The point is that the third handshake can carry data.

First, the conclusion: the TCP protocol establishes a connection for the third handshake during the three-handshake process allowing data to be carried.

Let's take a look at the RFC793 documentation for the connection Creation section of the TCP state change graph above. The RFC793 documentation gives the following statement (omitting unimportant parts):

The point is that the "data or controls which were queued for transmission can be included", meaning that the standard indicates that the third handshake ACK packet is portable. So what does the kernel stack of Linux do? Mr. Houtie said, "There is no secret before the source code." Recently coincided with the release of Kernel 4.0 official version, then trace this version of the kernel stack of the source code bar.

Before exploring the source code, we assume that the reader is familiar with the basic socket programming of Linux, at least familiar with the connection process (refer to this article "talking about the front end of server programming" socket connection process diagram). The socket interface and the protocol stack can be hooked up to the socket interface and the kernel stack.

First, the third handshake package is sent by the connection initiator (hereinafter referred to as the client) to the Port Listener (hereinafter referred to as the server), so only need to find the kernel stack in a connection in the SYN-RECV (figure in the syn_received) state when the packet is received after the processing process. After a search, the tcp_rcv_state_process function in the tcp_input.c file in the Net\ipv4 directory handles the process.

This function is actually a TCP state machine that handles the processing of packets that are received when the TCP connection is in each state. There are several side-by-side switch statements, because the function is very long, so it is easier to see the wrong level of relationships. Is the process of syn-recv state after streamlining the code without attention:

It is important to note that these two switch statements are tied. So when the TCP_SYN_RECV state receives a legitimate two handshake packet, it immediately sets the socket state to the tcp_established state, and executes the case to the tcp_established state below. The data it contains, if any, will continue to be processed.

The above indicates that the service side is able to process normally when the ACK of the third handshake sent by the client contains data. What about the client side? Let's see how the third ACK packet is sent when the client is in the Syn-send state.

The implementation of the Tcp_rcv_synsent_state_process function is long and the final key point is directly posted here:

At a glance, huh? The IF condition does not satisfy the direct reply to a separate ACK packet, and if any conditions are met, the timer is set to wait for a short time using the Inet_csk_reset_xmit_timer function. This period of time if there is data, with the data sent Ack, no data reply ack.

The previous question was solved.

But what are the three conditions? What can cause a third handshake package to carry data? Or, want to catch a third handshake with data package, what do I need to do? Don't worry, this blog has always liked to be inquisitive, and listen to the following one by one Tao.

Condition 1:sk->sk_write_pending! = 0

This value is 0 by default, so what will cause a non-0? The answer is that the protocol stack sends the data to the function when the socket state is not established, the variable is done with the + + operation, and wait for a small time to try to send the data. Look at the picture:

The Sk_stream_wait_connect function in NET/CORE/STREAM.C does the following:

Sk->sk_write_pending increments, and waits for the socket connection to reach the established state to emit data. That's a clear explanation.

The default mode of operation of a Linux socket is blocked, that is, the client's connect call is blocked by default, waiting for the three-time handshake to end or an error to be returned. Then NC, a command-line applet that is completely implemented with blocking sockets and does not modify the default socket parameters, waits for the connection to return successfully or fails to send the data, which is why we cannot catch the third handshake package with the data.

Then set the non-blocking sockets, connect immediately after the send data, the connection process is not instantaneous connection success, perhaps have the opportunity to see the third handshake packet with data. However, the Open Source network library, even if it is a non-blocking socket, is a writable event that listens to the socket, confirming that the connection is successful before the data is written. To save this almost negligible performance, it's not as valuable as safe and reliable code.

Condition 2:icsk->icsk_accept_queue.rskq_defer_accept! = 0

This is a very strange condition, defer_accept is a socket option that is used to defer the accept, which is actually when the first data is received before a connection is created. Tcp_defer_accept This option is typically used on the service side, which affects the SYN and accept queues of the socket. Default is not set, three times the handshake is completed, the socket enters the accept queue, the application layer perceives and accept the related connection. When the tcp_defer_accept is set, the three handshake is completed, the socket does not enter the accept queue, but is left directly in the SYN queue (with a length limit, the new connection is rejected by the kernel) until the data is really sent over to the accept queue. This parameter is set to the server can accept after the direct read, there must be data, but also save a system call.

The SYN queue holds the socket of the SYN_RECV state, the length is controlled by the Net.ipv4.tcp_max_syn_backlog parameter, the backlog parameter is set when the accept queue is called in Listen, and the kernel hard limit is determined by the The net.core.somaxconn limit, that is, the actual value is determined by min (backlog,somaxconn).

It is interesting that if the client first bind to a port and IP, then setsockopt (tcp_defer_accept), and then connect the server, this time there will be rskq_defer_accept=1 situation, At this time the kernel will set the timer to wait for the data to reply ACK packets together. I've never done this before, is it just to improve performance by reducing the empty packets sent for an ACK at a time? Which student knows kindly to inform, thank.

Condition 3:icsk->icsk_ack.pingpong! = 0

Pingpong This property is actually a socket option to indicate whether the current link is an interactive data stream, and if its value is 1, it indicates that the delay acknowledgement mechanism is used for the interactive data flow.

Well, this is the end of the article, the above functions appear to be more disorganized. Specific call chain can refer to this article "TCP Kernel Source analysis note", but because the kernel version of the different, there may be some differences. After all, I did not study the protocol stack, I dare not say anything.

Can the three handshake process established by the TCP connection carry data?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.