TCP Handshake
This post analyzes the TCP Handshake.
1. TCP Handshake
1.1. TCP 3Way, 4Way Handshake
![[Figure 1] TCP 3Way, 4Way Handshake](/blog-software/docs/theory-analysis/tcp-handshake/images/tcp-3way-4way-handshake.png)
[Figure 1] TCP 3Way, 4Way Handshake
The 3Way Handshake is the Handshake for creating a TCP Connection, and the 4Way Handshake is the Handshake for gracefully terminating an established TCP Connection. The upper part of [Figure 1] shows the TCP 3Way Handshake, and the lower part of [Figure 2] shows the 4Way Handshake.
| |
[Shell 1] shows the Packets dumped using the tcpdump command on Linux while the TCP 3Way Handshake and 4Way Handshake are performed. In [Shell 1], S in Flags represents the Sync Flag, F represents the Fin Flag, and Dot(.) represents the ACK Flag. Therefore, the upper part of [Shell 1] shows the 3Way Handshake process, and the lower part of [Shell 1] shows the 4Way Handshake process.
In [Shell 1], the 3Way Handshake is identical to the TCP standard, but it can be seen that the 4Way Handshake is performed in 3WAY, differently from the standard. Linux by default uses a method that saves Network Bandwidth by sending FIN and ACK at the same time. Therefore, on Linux, the 4Way Handshake process does not actually exchange Packets four times.
1.1.1. 3Way Handshake
The upper part of [Figure 1] shows the 3Way Handshake. Starting with the Client, the 3Way Handshake is performed by exchanging the SYN, SYN+ACK, and ACK Flags. In the TCP standard, since the Client starts the 3Way Handshake first, the Client is referred to as the Active Opener, and the Server is referred to as the Passive Opener. The Client calls the connect() System Call to send the SYN Flag to the Server and enters the SYN-SENT state. The Client’s SYN-SENT state is maintained until it receives the SYN+ACK Flag from the Server or a Timeout occurs.
The Server, which entered the LISTEN state by calling the bind() and listen() System Calls, receives the SYN Flag from the Client, then calls the accept() System Call to send the SYN+ACK Flag to the Client and enters the SYN-RECEIVED state. The Server’s SYN-RECEIVED state is maintained until it receives the ACK Flag or a Data Packet from the Client, or a Timeout occurs. The Timeout values of SYN-SENT and SYN-RECEIVED differ depending on the OS configuration.
The Client’s connect() System Call terminates after receiving the SYN+ACK Flag from the Server. After that, the Client sends the ACK Flag to the Server, enters the ESTABLISHED state, and exchanges Data with the Server through send()/recv() System Calls. The Server’s accept() System Call terminates upon receiving the ACK Flag from the Client or by the SYN-RECEIVED Timeout.
Even if the ACK Flag that the Client sent in response to the SYN+ACK Flag is lost and the Server fails to receive the ACK Flag, no serious problem occurs. This is because, through the ACK Flag and Sequence Number that the Client subsequently sends along with a Data Packet, the Server can indirectly know that the Client received the ACK+SYN Flag it sent. Therefore, even when a Data Packet is received from the Client, the Server’s accept() System Call terminates, and the Server enters the ESTABLISHED state and exchanges Data with the Client through send()/recv() System Calls.
1.1.2. 4Way Handshake
The lower part of [Figure 1] shows the 4Way Handshake performed with the Client sending the FIN Flag first. Not only the Client but also the Server can start the 4Way Handshake by sending the FIN Flag first. In the TCP standard, the side that starts the 4Way Handshake first is referred to as the Active Closer, and the other side is referred to as the Passive Closer. Therefore, in [Figure 1], the Client becomes the Active Closer and the Server becomes the Passive Closer.
When the close() System Call is called on the Active Closer or the Active Closer’s Process terminates, the Socket used by the Active Closer is Closed. When the Socket is Closed, the FIN Flag is sent to the other side. After that, the Active Closer enters the FIN-WAIT-1 state, which is maintained until it receives the ACK Flag from the Passive Closer. The Passive Closer that receives the FIN Flag sends the ACK Flag and enters the CLOSE-WAIT state.
CLOSE-WAIT, as can be inferred from its name, refers to the state of waiting until the Socket is Closed. That is, just like the Active Closer, it is the state of waiting for the Socket to be Closed by the close() System Call being called on the Passive Closer or the Passive Closer’s Process terminating. After that, when the Passive Closer’s Socket is Closed, the Passive Closer sends the FIN Flag to the Active Closer and enters the LAST-ACK state. Then the Passive Closer receives the ACK Flag from the Active Closer and enters the CLOSE state.
The Active Closer, having received the ACK Flag and FIN Flag from the Passive Closer, enters the FIN-WAIT-2 state and then the TIME-WAIT state, and enters the CLOSE state after a certain amount of time. The TCP standard defines that the TIME-WAIT state must be maintained for 2MSL (2 * Maximum Segment Lifetime). That is, it is a state that waits until the Packets (Segments) related to the terminated Connection are completely removed from the Network, so as not to affect new Connections created afterwards.
1.2. TCP Reset
![[Figure 2] TCP Reset at Connection Start](/blog-software/docs/theory-analysis/tcp-handshake/images/tcp-reset-connection-start.png)
[Figure 2] TCP Reset at Connection Start
| |
The TCP RST Flag is used to urgently terminate a TCP Connection created due to an unexpected situation. [Figure 2] shows the RST Flag that occurs when a Client sends the Sync Flag to an incorrect IP/Port to create a TCP Connection, and [Shell 2] shows the actual Packets at that moment dumped using the tcpdump command. In [Shell 2], R in Flags represents the RST Flag. The Server that receives the Client’s SYN Flag sends the RST Flag and immediately terminates the Connection.
![[Figure 3] TCP Reset in Connection](/blog-software/docs/theory-analysis/tcp-handshake/images/tcp-reset-connection.png)
[Figure 3] TCP Reset in Connection
| |
[Figure 3] shows the case where the Server sends the RST Flag first while a TCP Connection is established, and [Shell 2] shows the actual Packets at that moment dumped using the tcpdump command. The Client that receives the RST Flag terminates the TCP Connection without any further Handshake.
2. References
- TCP Transport - An Introduction to Computer Networks : http://intronetworks.cs.luc.edu/1/html/tcp.html
- When/how does Linux decide to close a socket on application kill : https://unix.stackexchange.com/questions/386536/when-how-does-linux-decides-to-close-a-socket-on-application-kill
- Can you send a TCP packet with RST flag set using iptables : https://unix.stackexchange.com/questions/282613/can-you-send-a-tcp-packet-with-rst-flag-set-using-iptables-as-a-way-to-trick-nma
- What if a TCP handshake segment is lost : https://stackoverflow.com/questions/16259774/what-if-a-tcp-handshake-segment-is-lost
- Final Analysis of CLOSE_WAIT & TIME_WAIT : https://tech.kakao.com/2016/04/21/closewait-timewait/
- Why TIME_WAIT state need to be 2MSL long : https://stackoverflow.com/questions/25338862/why-time-wait-state-need-to-be-2msl-long
- TCP connection termination FIN, FIN ACK, ACK : https://cs.stackexchange.com/questions/76393/tcp-connection-termination-fin-fin-ack-ack
- What is a FIN/ACK message in TCP : https://stackoverflow.com/questions/30043126/what-is-a-finack-message-in-tcp