diff --git a/src/config.c b/src/config.c index 37cc138b616acb3f8c950827a799c51d6b8356d1..fea3a0349e1c2f3b787ccb8aa3f8f3cb3dfc42ce 100644 --- a/src/config.c +++ b/src/config.c @@ -81,6 +81,11 @@ void loadServerConfigFromString(char *config) { if (server.maxidletime < 0) { err = "Invalid timeout value"; goto loaderr; } + } else if (!strcasecmp(argv[0],"tcp-keepalive") && argc == 2) { + server.tcpkeepalive = atoi(argv[1]); + if (server.tcpkeepalive < 0) { + err = "Invalid tcp-keepalive value"; goto loaderr; + } } else if (!strcasecmp(argv[0],"port") && argc == 2) { server.port = atoi(argv[1]); if (server.port < 0 || server.port > 65535) { @@ -528,6 +533,10 @@ void configSetCommand(redisClient *c) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0 || ll > LONG_MAX) goto badfmt; server.maxidletime = ll; + } else if (!strcasecmp(c->argv[2]->ptr,"tcp-keepalive")) { + if (getLongLongFromObject(o,&ll) == REDIS_ERR || + ll < 0 || ll > INT_MAX) goto badfmt; + server.tcpkeepalive = ll; } else if (!strcasecmp(c->argv[2]->ptr,"appendfsync")) { if (!strcasecmp(o->ptr,"no")) { server.aof_fsync = AOF_FSYNC_NO; @@ -795,6 +804,7 @@ void configGetCommand(redisClient *c) { config_get_numerical_field("maxmemory",server.maxmemory); config_get_numerical_field("maxmemory-samples",server.maxmemory_samples); config_get_numerical_field("timeout",server.maxidletime); + config_get_numerical_field("tcp-keepalive",server.tcpkeepalive); config_get_numerical_field("auto-aof-rewrite-percentage", server.aof_rewrite_perc); config_get_numerical_field("auto-aof-rewrite-min-size", diff --git a/src/networking.c b/src/networking.c index a7d14b49146a194ccd38d2dc4bd2e77f0c2dbbbd..66a2702c518a0c2fd283db8786b1fef7e36eea3c 100644 --- a/src/networking.c +++ b/src/networking.c @@ -59,6 +59,8 @@ redisClient *createClient(int fd) { if (fd != -1) { anetNonBlock(NULL,fd); anetEnableTcpNoDelay(NULL,fd); + if (server.tcpkeepalive) + anetKeepAlive(NULL,fd,server.tcpkeepalive); if (aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c) == AE_ERR) { diff --git a/src/redis.c b/src/redis.c index b125dcd6afa02ab9d70ed01e25bc8e7f4bab057a..43fec05a699f13c1ee3a93f9f8573d586c04e59d 100644 --- a/src/redis.c +++ b/src/redis.c @@ -1130,6 +1130,7 @@ void initServerConfig() { server.dbnum = REDIS_DEFAULT_DBNUM; server.verbosity = REDIS_NOTICE; server.maxidletime = REDIS_MAXIDLETIME; + server.tcpkeepalive = 0; server.client_max_querybuf_len = REDIS_MAX_QUERYBUF_LEN; server.saveparams = NULL; server.loading = 0; diff --git a/src/redis.h b/src/redis.h index a0f86974c552214e74a16a3bf953293fa5639732..19fe37acef676d5affa4060125323d29d9eb9ac3 100644 --- a/src/redis.h +++ b/src/redis.h @@ -698,6 +698,7 @@ struct redisServer { /* Configuration */ int verbosity; /* Loglevel in redis.conf */ int maxidletime; /* Client timeout in seconds */ + int tcpkeepalive; /* Set SO_KEEPALIVE if non-zero. */ size_t client_max_querybuf_len; /* Limit for client query buffer length */ int dbnum; /* Total number of configured DBs */ int daemonize; /* True if running as a daemon */