TCP keepalive

TCP keepalive is a Linux kernel feature that sends periodic, empty probe packets over an idle socket connection to verify that the remote peer is still alive and responsive. By default, TCP keepalive is turned off for network sockets and must be explicitly enabled per socket using the SO_KEEPALIVE socket option.

Why It Is Used

  • Detecting Dead Peers: If a remote client abruptly crashes, loses power, or disconnects from the network, the local host receives no notification and assumes the connection is still active. Keepalive probes detect this failure and close the zombie socket

  • Preventing Timeout Disconnections: Firewalls, NAT gateways, and load balancers track active connections and silently drop idle ones after a certain timeout period. The continuous traffic from keepalive packets prevents these network devices from terminating the connection.

How Keepalive Works (The 3 Core Parameters)

The Linux kernel monitors three core variables to manage keepalive behavior:

  • tcp_keepalive_time (Default: 7200 seconds / 2 hours): The duration a connection must remain completely idle before Linux fires the first keepalive probe packet

  • tcp_keepalive_intvl (Default: 75 seconds): The interval between consecutive probes if the previous probe did not get an explicit acknowledgment (ACK) reply.

  • tcp_keepalive_probes (Default: 9 probes): The total number of unacknowledged probes sent before declaring the connection dead and forcing the socket to shut down

Using the standard defaults, a dead connection is only detected after 2 hours, 11 minutes, and 15 seconds (7200 + (75 × 9)). Because of this long timeframe, production applications usually lower these values.

Configuring the kernel

There are two ways to configure keepalive parameters inside the kernel via userspace commands:

  • procfs interface

  • sysctl interface

The procfs interface

To read current keepalive time

cat /proc/sys/net/ipv4/tcp_keepalive_time
cat /proc/sys/net/ipv4/tcp_keepalive_intvl
cat /proc/sys/net/ipv4/tcp_keepalive_probes

To update keepalive time

echo 300 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 30 > /proc/sys/net/ipv4/tcp_keepalive_probes

sysctl interface

To read current keepalive time

sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes

To update keepalive time

sysctl -w net.ipv4.tcp_keepalive_time=300 net.ipv4.tcp_keepalive_intvl=60 net.ipv4.tcp_keepalive_probes=30

Programming using socket

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char *argv[])
{
	int sfd;
	int optval;
	socklen_t optlen = sizeof(optval);

	/* Create the socket */
	sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sfd < 0) {
		perror("socket()");
		exit(EXIT_FAILURE);
	}

	/* Check the status for the keepalive option */
	if(getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
		perror("getsockopt()");
		close(sfd);
		exit(EXIT_FAILURE);
	}
	printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));

	/* Set the option active */
	optval = 1;
	optlen = sizeof(optval);
	if(setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
		perror("setsockopt()");
		close(sfd);
		exit(EXIT_FAILURE);
	}
	printf("SO_KEEPALIVE set on socket\n");

	/* Check the status again */
	if(getsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
		perror("getsockopt()");
		close(sfd);
		exit(EXIT_FAILURE);
	}
	printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));

	close(sfd);

	exit(EXIT_SUCCESS);
}




©2023-2024 rculock.com