1. Introduction

A TCP connection between two sockets tends to remain going for a while even if one of the sockets dies or the communication channel goes down. In most cases, the connection keeps for so long that it seems there’s no timeout.

In this tutorial, we’ll study why this happens and how we can control this behavior.

2. Why Does This Happen?

TCP is designed to provide reliable transmission of data. To that end, it creates a connection between the two communicating parties.

Thus, it must ensure that it sends all data even if there is a momentary failure in the communication channel or one of the parties. To perform this, TCP has a mechanism for acknowledging receipt of data and retransmitting data whenever needed.

Moreover, even in case of failures, TCP needs to keep the connection alive until it’s sure that one of the parties to the communication has died (or is inaccessible). This is a classic case that TCP can keep the connection active for a long time.

3. How Can We Control the Connection Timeout?

In practice, the TCP connection timeout for these cases isn’t controlled by just one parameter but by multiple ones. Therefore, we’ve two types of parameters: global operating system and socket. Let’s see the parameters involved and how they work.

The system-wide TCP parameters may vary for each operating system. **In Linux, we can access them by files in the directory /proc/sys/net/ipv4/.** Hence, these parameters are /proc interfaces. The table below describes the /proc interfaces that are related to the TCP connection timeout:

/proc interface

Description

Unit

Default Value

tcp_keepalive_time

The time a connection needs to be idle before TCP begins sending out keep-alive probes.

Seconds

7200

tcp_keepalive_intvl

Time between TCP keep-alive probes.

Seconds

75

tcp_keepalive_probes

The maximum number of TCP keep-alive probes to send before dropping the connection.

Number of Packets (probes)

9

tcp_retries2

The maximum number of times a TCP packet is retransmitted in established state before giving up.

Number of retransmission attempts

15

The combination of these parameters defines the actual connection timeout. So by default, if the connection is idle, it will take about 2 hours and 11 minutes to close. In other words, this will be the time after the socket waits 7200 seconds before it starts sending probes, and then sends 9 probes every 75 seconds.

The activation of this keep-alive behavior will only occur if the TCP socket has the SO_KEEPALIVE option enabled. The table below describes this and other socket options.

Socket Option

Description

Unit

SO_KEEPALIVE

Enables keep-alives on the socket.

Boolean

TCP_KEEPIDLE

Same as tcp_keepalive_time, but only for the particular socket.

Seconds

TCP_KEEPINTVL

Same as tcp_keepalive_intvl, but only for the particular socket.

Seconds

TCP_KEEPCNT

Same as tcp_keepalive_probes, but only for the particular socket.

Number of Packets (probes)

TCP_USER_TIMEOUT

The time limit that transmitted data may remain unacknowledged, or bufferred data may remain untransmitted (due to zero window size) before TCP will forcibly close the connection.

Milliseconds

Note that if we set TCP_KEEPIDLE, TCP_KEEPINTVL, and TCP_KEEPCNT, their values will overwrite the values of tcp_keepalive_time, tcp_keepalive_intvl, and tcp_keepalive_probes, respectively.

Also, if the connection is busy, the socket will continue trying to send data until it reaches the limit set in TCP_USER_TIMEOUT. But if TCP_USER_TIMEOUT isn’t enabled, the socket will drop the connection when it has made all the attempts defined in tcp_retries2.

We can change this behavior by setting different values for the mentioned parameters.

The same information on Windows Systems can be found in the Tcpip\Parameters and Socket Options documentation.

4. Conclusion

In this article, we studied why TCP sometimes keeps the connection for so long that there seems to be no timeout. We learned that this behavior can be changed through multiple operating systems and socket parameters.