1. Overview
The TCP (Transmission Control Protocol) ensures that network packets are reliably exchanged between the sender and the receiver. It utilizes the concept of packet acknowledgment and message timeout. For debugging purposes, it’s sometimes necessary to be able to simulate a TCP socket timeout on a TCP server.
In this tutorial, we’ll learn how to cause a TCP socket timeout using the standard Linux tools.
2. Using iptables to Block the Port
We can use iptables to block a given TCP port on our machine, thereby simulating a TCP timeout.
For example, we can block port 6000:
$ sudo iptables -A INPUT -p tcp --dport 6000 -j DROP
So, let’s understand each part of this command:
- sudo or root privileges are needed when updating the iptables rules
- -A INPUT means to add the input rule
- -p specifies the TCP protocol
- –dport provides the port number
- -j DROP means to add the rule to drop the TCP packet
Finally, let’s now check if the DROP port 6000 rule was added correctly:
$ sudo iptables -L
[sudo] password for user:
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere tcp dpt:x11
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
As a result, we can see that the DROP rule is now added to the INPUT Chain.
3. Test the Timeout
At this point, we can test the timeout by using the netcat (nc) command:
$ nc -vz localhost 6000
nc: connect to localhost (127.0.0.1) port 6000 (tcp) failed: Connection timed out
As we can see, after some time, the connection to port 6000 times out.
The -v option means the verbose mode, while -z means that the port is in scanning mode.
We can measure the exact timeout value by using the time command in front of the nc command:
$ time nc -vz localhost 6000
nc: connect to localhost (127.0.0.1) port 6000 (tcp) failed: Connection timed out
real 2m9,534s
user 0m0,004s
sys 0m0,004s
The resulting timeout is 2 minutes and 9,534 seconds.
4. Update the Timeout Values
To increase or reduce the TCP timeout values, we can use the files located in the directory /proc/sys/net/ipv4/ of the /proc pseudo-filesystem.
So, let’s update the TCP timeout, and then measure how it affects the timeout measurements.
4.1. Reduce the TCP Timeout
There are several files that affect the TCP timeout:
- tcp_retries2
- tcp_keepalive_time
- tcp_keepalive_intvl
- tcp_keepalive_probes
By reducing the default values for the above files, we can achieve lower TCP timeout time.
For example, let’s lower the timeout by changing the number of TCP packet retries. To do so, we first check the default value using the cat command:
$ cat /proc/sys/net/ipv4/tcp_retries2
15
The default number of TCP retries is 15.
Let’s now reduce it to 1 by using the sysctl utility:
$ sudo sysctl -w net.ipv4.tcp_retries2=1
Thus, we set the value for the tcp_retries2 file.
Finally, let’s apply the changes:
$ sudo sysctl -p
As a result, this should save the value and apply it to any future TCP connections.
4.2. Repeat the Timeout Measurement
Let’s check how changing the file has affected our timeout measurements:
$ time nc -vz localhost 6000
nc: connect to localhost (127.0.0.1) port 6000 (tcp) failed: Connection timed out
real 0m11,283s
user 0m0,004s
sys 0m0,004s
As we can see, the timeout has decreased from over two minutes to 11,283 seconds.
5. Conclusion
In this article, we looked at how to simulate a TCP socket timeout. For that, firstly, we learned how to make the TCP port block incoming connections. Secondly, we discovered how to update the TCP timeout value.