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.