From ee21c18e5d2e897204a92eb75469307a9ca8ba1e Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 8 Feb 2013 16:30:21 +0100 Subject: [PATCH] Add SO_KEEPALIVE support to anet.c. --- src/anet.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/anet.h | 1 + 2 files changed, 44 insertions(+) diff --git a/src/anet.c b/src/anet.c index 3f037dcad..82bca5534 100644 --- a/src/anet.c +++ b/src/anet.c @@ -75,6 +75,49 @@ int anetNonBlock(char *err, int fd) return ANET_OK; } +/* Set TCP keep alive option to detect dead peers. The interval option + * is only used for Linux as we are using Linux-specific APIs to set + * the probe send time, interval, and count. */ +int anetKeepAlive(char *err, int fd, int interval) +{ + int val = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) + { + anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno)); + return ANET_ERR; + } + +#ifdef __linux__ + /* Default settings are more or less garbage, with the keepalive time + * set to 7200 by default on Linux. Modify settings to make the feature + * actually useful. */ + + /* Send first probe after interval. */ + val = interval; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { + anetSetError(err, "setsockopt TCP_KEEPIDLE: %s\n", strerror(errno)); + return ANET_ERR; + } + + /* Send next probes after interval. */ + val = interval; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { + anetSetError(err, "setsockopt TCP_KEEPINTVL: %s\n", strerror(errno)); + return ANET_ERR; + } + + /* Consider the socket in error state after just one missing ACK reply. */ + val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + anetSetError(err, "setsockopt TCP_KEEPCNT: %s\n", strerror(errno)); + return ANET_ERR; + } +#endif + + return ANET_OK; +} + static int anetSetTcpNoDelay(char *err, int fd, int val) { if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1) diff --git a/src/anet.h b/src/anet.h index dbf36dbd8..696c2c225 100644 --- a/src/anet.h +++ b/src/anet.h @@ -55,5 +55,6 @@ int anetEnableTcpNoDelay(char *err, int fd); int anetDisableTcpNoDelay(char *err, int fd); int anetTcpKeepAlive(char *err, int fd); int anetPeerToString(int fd, char *ip, int *port); +int anetKeepAlive(char *err, int fd, int interval); #endif -- GitLab