TCP is defined as a connection-oriented and reliable protocol. We will check out how TCP connection works in this article.
How TCP Connection Works?
TCP allows for the transmission of information in both directions. This means that computer systems that communicate over TCP can send and receive data at the same time, similar to a telephone conversation.
The protocol uses segments (packets) as the basic units of data transmission. In addition to the payload, segments can also contain control information and are limited to 1,500 bytes.
The TCP software in the network protocol stack of the operating system is responsible for establishing and terminating the end-to-end connections as well as transferring data.
Establishing a TCP session would begin with a three-way handshake, followed by data transfer, and then a four-way closure. The four-way closure where both sender and receiver agree on closing the session is termed as graceful closure.
After the 4-way closure, the server will allow some minutes of time (default), during which any pending packets on the network are to be processed, this is the TIME_WAIT state. After the TIME_WAIT state completes, all the resources allocated for this connection are released.
Check TCP Connection Status in Linux
To display listeners and connections on Linux we can use the netstat or ss command. While older Linux boxes only support netstat, newer Linux distributions use netstat and ss in parallel. However, with the introduction of ss, netstat is marked as deprecated. Check this post to learn more about TCP sockets.
# Display all the connections netstat -anpl # Display only TCP sockets / connections. netstat -t ss -t # Display only UDP sockets / connections. netstat -u ss -u
TCP Connection States
SYN_SENT Indicates that the sender has initiated the active open process with the receiver.
SYN_RECEIVED Indicates that the receiver has received a SYN segment from the sender.
ESTABLISHED Indicates that the receiver has received a SYN segment from the sender, the sequence numbers are synchronized, and a connection is established.
LISTEN Indicates a state of readiness to accept connection requests.
FIN_WAIT_1 Indicates that an active close process has been initiated. This state forms the first state in the three-step connection termination process.
TIMED_WAIT Indicates that this side is waiting for acknowledgement from another side after it has initiated an active close process. The wait period is timed by a timer mechanism on the sender’s machine.
CLOSE_WAIT Indicates that a FIN segment has arrived from another side to begin the process of terminating the connection.
FIN_WAIT_2 Indicates that the acknowledgement for the FIN segment sent to another side has arrived. This state forms the second state in the three-step connection termination process.
LAST_ACK Indicates that user input for terminating a connection is obtained and that a FIN segment can now be sent to complete the connection termination process. This state is the last state in the three-step connection termination process.
CLOSED Indicates that the acknowledgement for the last FIN segment has arrived and that the connection is terminated.
Examples of SYN_SENT TCP Connection
We can use this Python code to connect port 180 on google.com. This will not work as this port is not open. At the same time, we can open a new terminal to check the state of TCP connection. After some time, the connection will be failed.
If we see SYN_SENT connections, this usually means that there is a firewall problem between sender and receiver. The TCP 3-way handshake can not be completed.
# python -c 'import socket;client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);client_socket.connect(("google.com", 180))'
# netstat -anpl|grep :180 tcp 0 1 10.254.222.37:40896 18.104.22.168:180 SYN_SENT 17998/python
Examples of TIME_WAIT TCP Connection
We will try to connect port 80 on google.com with the following command. This time the connection will work. The state of TCP connection will change from SYN_SENT to ESTABLISHED and become to TIME_WAIT in the end.
TIME_WAIT indicates that the local endpoint (this side) has closed the connection. The connection is being kept around so that any delayed packets can be matched to the connection and handled appropriately
This post shares more about the time_wait tcp connection in Linux.
# python -c 'import socket;client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM);client_socket.connect(("google.com", 80))'
# netstat -anpl|grep :80 tcp 0 0 10.254.222.37:32912 22.214.171.124:80 TIME_WAIT -
Trace TCP Connection in Linux
In Linux RHEL 8, we can use tcpstates command to trace all the TCP connections.
# /usr/share/bcc/tools/tcpstates -T TIME SKADDR C-PID C-COMM LADDR LPORT RADDR RPORT OLDSTATE -> NEWSTATE MS 17:14:23 ffff8caa72f86300 17205 yum 192.168.122.166 0 10.4.204.72 443 CLOSE -> SYN_SENT 0.000 17:14:23 ffff8caa72f86300 0 swapper/2 192.168.122.166 0 10.4.204.72 443 SYN_SENT -> ESTABLISHED 252.507