From e48d335d7b347ad84b0c363c558dd1d0ffc5ff16 Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Thu, 11 May 2017 16:39:26 +0200 Subject: [PATCH 1/6] set tcp keepalive socket options --- tcp.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tcp.c b/tcp.c index 77a6044..9d79bd3 100644 --- a/tcp.c +++ b/tcp.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,9 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t struct timeval now; time_t elapsed; + int optval; + socklen_t optlen = sizeof(optval); + debug(DBG_DBG, "tcpconnect: called from %s", text); pthread_mutex_lock(&server->lock); if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) { @@ -118,8 +122,30 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t if (server->sock >= 0) close(server->sock); - if ((server->sock = connecttcphostlist(server->conf->hostports, srcres)) >= 0) + if ((server->sock = connecttcphostlist(server->conf->hostports, srcres)) >= 0) { + optval = 1; + if(setsockopt(server->sock, SOL_SOCKET, TCP_KEEPCNT, &optval, optlen) < 0) { + debug(DBG_ERR, "tcpconnect: setsockopt TCP_KEEPCNT failed"); + } + optval = 2000; + if(setsockopt(server->sock, SOL_SOCKET, TCP_KEEPIDLE, &optval, optlen) < 0) { + debug(DBG_ERR, "tcpconnect: setsockopt TCP_KEEPIDLE %d failed", optval); + } + if(getsockopt(server->sock, SOL_SOCKET, TCP_KEEPIDLE, &optval, &optlen) < 0) { + debug(DBG_ERR, "tcpconnect: getsockopt failed"); + }else{ + debug(DBG_ERR, "tcpconnect: TCP_KEEPIDLE is %d", optval); + } + optval = 1; + if(setsockopt(server->sock, SOL_SOCKET, TCP_KEEPINTVL, &optval, optlen) < 0) { + debug(DBG_ERR, "tcpconnect: setsockopt TCP_KEEPINTVL failed"); + } + optval = 1; + if(setsockopt(server->sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) { + debug(DBG_ERR, "tcpconnect: setsockopt SO_KEEPALIVE failed"); + } break; + } } server->connectionok = 1; gettimeofday(&server->lastconnecttry, NULL); From 0f342f7235713416ccae7c52d8de469f5bf76d03 Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Fri, 12 May 2017 17:55:48 +0200 Subject: [PATCH 2/6] move setsockopt to util function --- tcp.c | 26 +------------------------- tls.c | 2 ++ util.c | 23 +++++++++++++++++++++++ util.h | 1 + 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/tcp.c b/tcp.c index 9d79bd3..a194055 100644 --- a/tcp.c +++ b/tcp.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -84,9 +83,6 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t struct timeval now; time_t elapsed; - int optval; - socklen_t optlen = sizeof(optval); - debug(DBG_DBG, "tcpconnect: called from %s", text); pthread_mutex_lock(&server->lock); if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) { @@ -123,27 +119,7 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t if (server->sock >= 0) close(server->sock); if ((server->sock = connecttcphostlist(server->conf->hostports, srcres)) >= 0) { - optval = 1; - if(setsockopt(server->sock, SOL_SOCKET, TCP_KEEPCNT, &optval, optlen) < 0) { - debug(DBG_ERR, "tcpconnect: setsockopt TCP_KEEPCNT failed"); - } - optval = 2000; - if(setsockopt(server->sock, SOL_SOCKET, TCP_KEEPIDLE, &optval, optlen) < 0) { - debug(DBG_ERR, "tcpconnect: setsockopt TCP_KEEPIDLE %d failed", optval); - } - if(getsockopt(server->sock, SOL_SOCKET, TCP_KEEPIDLE, &optval, &optlen) < 0) { - debug(DBG_ERR, "tcpconnect: getsockopt failed"); - }else{ - debug(DBG_ERR, "tcpconnect: TCP_KEEPIDLE is %d", optval); - } - optval = 1; - if(setsockopt(server->sock, SOL_SOCKET, TCP_KEEPINTVL, &optval, optlen) < 0) { - debug(DBG_ERR, "tcpconnect: setsockopt TCP_KEEPINTVL failed"); - } - optval = 1; - if(setsockopt(server->sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) { - debug(DBG_ERR, "tcpconnect: setsockopt SO_KEEPALIVE failed"); - } + enable_keepalive(server->sock); break; } } diff --git a/tls.c b/tls.c index bbf9da3..7b18232 100644 --- a/tls.c +++ b/tls.c @@ -130,6 +130,8 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t if ((server->sock = connecttcphostlist(server->conf->hostports, srcres)) < 0) continue; + enable_keepalive(server->sock); + SSL_free(server->ssl); server->ssl = NULL; ctx = tlsgetctx(handle, server->conf->tlsconf); diff --git a/util.c b/util.c index c976175..41e299c 100644 --- a/util.c +++ b/util.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -123,6 +124,28 @@ void disable_DF_bit(int socket, struct addrinfo *res) { } } +void enable_keepalive(int socket) { + int optval; + socklen_t optlen = sizeof(optval); + + optval = 3; + if(setsockopt(socket, SOL_TCP, TCP_KEEPCNT, &optval, optlen) < 0) { + debug(DBG_ERR, "enable_keepalive: setsockopt TCP_KEEPCNT failed"); + } + optval = 10; + if(setsockopt(socket, SOL_TCP, TCP_KEEPIDLE, &optval, optlen) < 0) { + debug(DBG_ERR, "enable_keepalive: setsockopt TCP_KEEPIDLE %d failed", optval); + } + optval = 10; + if(setsockopt(socket, SOL_TCP, TCP_KEEPINTVL, &optval, optlen) < 0) { + debug(DBG_ERR, "enable_keepalive: setsockopt TCP_KEEPINTVL failed"); + } + optval = 1; + if(setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) { + debug(DBG_ERR, "enable_keepalive: setsockopt SO_KEEPALIVE failed"); + } +} + int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) { int s, on = 1; struct addrinfo *res; diff --git a/util.h b/util.h index 36a5cdd..b5758f5 100644 --- a/util.h +++ b/util.h @@ -20,6 +20,7 @@ void port_set(struct sockaddr *sa, uint16_t port); void printfchars(char *prefixfmt, char *prefix, char *charfmt, uint8_t *chars, int len); void disable_DF_bit(int socket, struct addrinfo *res); +void enable_keepalive(int socket); int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only); int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout); From 5f70899cc6425d590c707a2d237cec55644b8c0c Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Fri, 12 May 2017 17:57:46 +0200 Subject: [PATCH 3/6] do tcp timeout & cleanup same as tls --- tcp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tcp.c b/tcp.c index a194055..4e1883c 100644 --- a/tcp.c +++ b/tcp.c @@ -223,8 +223,10 @@ void *tcpclientrd(void *arg) { for (;;) { /* yes, lastconnecttry is really necessary */ lastconnecttry = server->lastconnecttry; - buf = radtcpget(server->sock, 0); + buf = radtcpget(server->sock, server->dynamiclookuparg ? IDLE_TIMEOUT : 0); if (!buf) { + if (server->dynamiclookuparg) + break; tcpconnect(server, &lastconnecttry, 0, "tcpclientrd"); continue; } @@ -232,6 +234,9 @@ void *tcpclientrd(void *arg) { replyh(server, buf); } server->clientrdgone = 1; + pthread_mutex_lock(&server->newrq_mutex); + pthread_cond_signal(&server->newrq_cond); + pthread_mutex_unlock(&server->newrq_mutex); return NULL; } From b539e010b8c87d3fd5a26fa1406dbdee9314d600 Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Tue, 16 May 2017 17:45:56 +0200 Subject: [PATCH 4/6] add config option for tcpKeepalive (client and server) --- radsecproxy.c | 2 ++ radsecproxy.h | 1 + tcp.c | 5 ++++- tls.c | 7 +++++-- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/radsecproxy.c b/radsecproxy.c index fe76f7c..cf24d01 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -2716,6 +2716,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char #endif "DuplicateInterval", CONF_LINT, &dupinterval, "addTTL", CONF_LINT, &addttl, + "tcpKeepalive", CONF_BLN, &conf->keepalive, "rewrite", CONF_STR, &rewriteinalias, "rewriteIn", CONF_STR, &conf->confrewritein, "rewriteOut", CONF_STR, &conf->confrewriteout, @@ -2899,6 +2900,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char "CertificateNameCheck", CONF_BLN, &conf->certnamecheck, #endif "addTTL", CONF_LINT, &addttl, + "tcpKeepalive", CONF_BLN, &conf->keepalive, "rewrite", CONF_STR, &rewriteinalias, "rewriteIn", CONF_STR, &conf->confrewritein, "rewriteOut", CONF_STR, &conf->confrewriteout, diff --git a/radsecproxy.h b/radsecproxy.h index 244eb5c..bbee5b9 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -132,6 +132,7 @@ struct clsrvconf { uint8_t dupinterval; uint8_t certnamecheck; uint8_t addttl; + uint8_t keepalive; uint8_t loopprevention; struct rewrite *rewritein; struct rewrite *rewriteout; diff --git a/tcp.c b/tcp.c index 4e1883c..d52edff 100644 --- a/tcp.c +++ b/tcp.c @@ -119,7 +119,8 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t if (server->sock >= 0) close(server->sock); if ((server->sock = connecttcphostlist(server->conf->hostports, srcres)) >= 0) { - enable_keepalive(server->sock); + if (server->conf->keepalive) + enable_keepalive(server->sock); break; } } @@ -335,6 +336,8 @@ void *tcpservernew(void *arg) { if (conf) { client = addclient(conf, 1); if (client) { + if(conf->keepalive) + enable_keepalive(s); client->sock = s; client->addr = addr_copy((struct sockaddr *)&from); tcpserverrd(client); diff --git a/tls.c b/tls.c index 7b18232..2932b7b 100644 --- a/tls.c +++ b/tls.c @@ -130,7 +130,8 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t if ((server->sock = connecttcphostlist(server->conf->hostports, srcres)) < 0) continue; - enable_keepalive(server->sock); + if (server->conf->keepalive) + enable_keepalive(server->sock); SSL_free(server->ssl); server->ssl = NULL; @@ -424,7 +425,7 @@ void *tlsservernew(void *arg) { cert = verifytlscert(ssl); if (!cert) goto exit; - accepted_tls = conf->tlsconf; + accepted_tls = conf->tlsconf; } while (conf) { @@ -432,6 +433,8 @@ void *tlsservernew(void *arg) { X509_free(cert); client = addclient(conf, 1); if (client) { + if (conf->keepalive) + enable_keepalive(s); client->ssl = ssl; client->addr = addr_copy((struct sockaddr *)&from); tlsserverrd(client); From d238e4bd0026a80b8d421b371abe0b1d3ebb2547 Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Tue, 16 May 2017 17:59:44 +0200 Subject: [PATCH 5/6] add documentation for tcpKeepalive --- radsecproxy.conf.5.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/radsecproxy.conf.5.xml b/radsecproxy.conf.5.xml index b5f71b6..4f706b8 100644 --- a/radsecproxy.conf.5.xml +++ b/radsecproxy.conf.5.xml @@ -510,6 +510,7 @@ blocktype name { certificateNameCheck, matchCertificateAttribute, duplicateInterval, AddTTL, + tcpKeepalive fticksVISCOUNTRY, fticksVISINST, rewrite, rewriteIn, rewriteOut, and @@ -587,6 +588,11 @@ blocktype name { that for details. Any value configured here overrides the basic one when sending messages to this client. + + The tcpKeepalive option enables TCP keepalives. If + keepalives are not answered withing 30s the connections is considered + lost. + The fticksVISCOUNTRY option configures clients eligible to F-Ticks logging as defined by the @@ -682,7 +688,8 @@ blocktype name { type, secret, tls, certificateNameCheck, matchCertificateAttribute, - AddTTL, rewrite, + AddTTL, tcpKeepalive, + rewrite, rewriteIn, rewriteOut, statusServer, retryCount, dynamicLookupCommand and @@ -704,7 +711,8 @@ blocktype name { type, secret, tls, certificateNameCheck, matchCertificateAttribute, - AddTTL, rewrite, + AddTTL, tcpKeepalive, + rewrite, rewriteIn and rewriteOut are just as specified for the client block above, except that defaultServer (and not From 62a452e53e0df0032a9fe2b81f64587054b70b62 Mon Sep 17 00:00:00 2001 From: Fabian Mauchle Date: Thu, 11 Jan 2018 18:07:29 +0100 Subject: [PATCH 6/6] fix typos in manpage --- radsecproxy.conf.5.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radsecproxy.conf.5.xml b/radsecproxy.conf.5.xml index 4f706b8..0f57cb1 100644 --- a/radsecproxy.conf.5.xml +++ b/radsecproxy.conf.5.xml @@ -590,7 +590,7 @@ blocktype name { The tcpKeepalive option enables TCP keepalives. If - keepalives are not answered withing 30s the connections is considered + keepalives are not answered within 30s the connection is considered lost.