A: Summary overview
When you meet difficult don’t also difficult, the east wind powerless flowers residual. After the three-way handshake, the MTU and MSS limit the packet size, the sliding window control the sender traffic, the congestion control control the network status, and the detailed explanation of the connection queue during the three-way handshake. Finally, dust to dust, it’s time to release the connection and say goodbye. This article will elaborate on the four-wave process, state changes, and some verification of whether the four-wave is not needed! Many pictures in this paper are from Master Zhang’s gold-digging pamphlet. We have contacted and agreed with the author. If you are interested, you can buy the pamphlet and read it carefully
Two: four wave process
The active closing party is defined as A and the passive closing party as B in the process description below
- User A sends A FIN packet to close the connection
FIN-WAIT-1
No more packets will be sent to end B - User B replies to the ACK packet immediately after receiving the FIN packet
CLOSE-WAIT
state - After receiving the ACK packet sent by B, USER A changes its status to
FIN-WAIT-2
- B checks whether there is any data to send. If there is any data to send, the system sends all unsent data. If there is no data to send, the system sends a FIN packet
LAST-ACK
state - After receiving the FIN packet from USER B, user A sends an ACK packet to enter
TIME-WAIT
State waiting for - A will release the connection after two MSL clocks
CLOSED
- B will directly release the connection after receiving the ACK confirmation packet transmitted by A
CLOSED
state
Three: four wave simulation
--tolerance_usecs=1000000 0 socket(... , SOCK_STREAM, IPPROTO_TCP) = 3 +0 bind(3, ... ,...). = 0 +0 listen(3, 1) = 0 +0 < S 0:0(0) win 65535 <mss 100> +0 > S. 0:0(0) ack 1 <... > .1 < . 1:1(0) ack 1 win 65535 +.1 accept(3, ... ,...). = 4 / / the server disconnected active +. 1 close (4) = 0 + 0 > F. 1:1 (0) ack 1 <... 1 <.1:1 (0) ACK 2 win 257 // Inject FIN into protocol stack The simulated server received FIN +.1 < F.1:1 (0) win 65535 < MSS 100> +0 'sleep 1000000'Copy the code
- The server sends a FIN packet to disconnect the connection
- The client replies with ACK
- The client replies to the FIN again
- The server replies with ACK
Four: four strokes
Four waves must be four waves, right? This is the kind of soul-searching that happens all the time, and you can say there’s a whole bunch of reasons to support it. In fact, the most important thing is that the passive closing party needs to check whether there is any data to be transmitted, so the FIN and ACK are sent twice. This is one more step than the three-way handshake, recall that SYN+ACK was sent as a packet. But think about it. If there is no data to send, will the FIN+ACK packet be sent together? See the screenshot below for verification:
TCP(6) — retransmission and confirmation
Five: time-wait state
The active closing party usually needs to WAIT for 2MSL of TIME before entering the CLOSED state. What is the use of waiting 2MSL of TIME to enter the CLOSED state? Why is it designed this way?
Six: timestamp
/proc/sys/net/ipv4/tcp_timestamp
- TSval stores the incremental timestamp of this request
- Tsecr stores the last time stamp of the data sender
Seven: tcp_tw_reuse
When a large number of TIME_WAIT connections exist in the system, it is undoubtedly a very serious waste of TIME. Therefore, it is hoped that time-wait connections can be reused. The system provides the /proc/sys/net/ipv4/tcp_tw_reuse parameter to reuse time-wait parameters as follows:
- If an old connection packet is lost due to network fluctuation, the new connection will discard the packet when it determines that the timestamp carried by the packet is smaller than the current record timestamp
- If packets are lost due to ACK, when the passive close party retransmits FIN+ACK, the active close party also uses the timestamp to detect the phenomenon and replies to the RST for disconnection
A more radical alternative to tcp_tw_reuse is tcp_tw_recyle, which caches the timestamps of all IP-created connections and discards any packets that are smaller than that. Such a policy is an explosive operation in the NAT network, so this parameter directly disables it
8: SO_REUSEADDR
A common problem is that when the server crashes, restart the service and find that the address is already occupied. What? In fact, it is time-Wait who is doing the trick. It is not reasonable to WAIT 2MSL for a program to crash and restart, so you can set the parameter SO_REUSEADDR to allow binding of ports connected in time-wait state. This parameter is usually set on the server, because the client port is dynamic, but the server is always listening on a certain port
9: SO_LINGER
- L_onoff: 0 indicates that SO_LINGER is disabled. If the value is not 0, SO_LINGER is enabled
- L_linger: Enable when l_ONOFF is not 0. If this parameter is 0, all buffer data is discarded and an RST is sent to disconnect the connection. Non-0 indicates that the RST packet will be disconnected regardless of whether the data is sent or not