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