diff --git a/ChangeLog b/ChangeLog index cd5c58a..0ae86bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -14,6 +14,8 @@ Changes between 1.6.8 and the master branch aware that use of the DynamicLookupCommand configuration option still enables code known to be buggy. - Use a listen(2) backlog of 128 (RADSECPROXY-72). + - Replace several server status bits with a single state enum. + (RADSECPROXY-71) Bug fixes: - Detect the presence of docbook2x-man correctly. @@ -25,6 +27,8 @@ Changes between 1.6.8 and the master branch - Tie Access-Request log lines to response log lines (RADSECPROXY-60). - Take lock on realm refcount before updating it (RADSECPROXY-77). - Fix a couple of memory leaks and NULL ptr derefs in error cases. + - Don't forget about good dynamically discovered (TLS) connections + (RADSECPROXY-69). 2016-09-21 1.6.8 Bug fixes: diff --git a/dtls.c b/dtls.c index e96e704..54fb5c7 100644 --- a/dtls.c +++ b/dtls.c @@ -556,8 +556,8 @@ int dtlsconnect(struct server *server, struct timeval *when, int timeout, char * return 0; } - if (server->connectionok) { - server->connectionok = 0; + if (server->state == RSP_SERVER_STATE_CONNECTED) { + server->state = RSP_SERVER_STATE_RECONNECTING; sleep(2); } else if (elapsed < 1) sleep(2); @@ -591,7 +591,7 @@ int dtlsconnect(struct server *server, struct timeval *when, int timeout, char * } X509_free(cert); debug(DBG_WARN, "dtlsconnect: DTLS connection to %s port %s up", hp->host, hp->port); - server->connectionok = 1; + server->state = RSP_SERVER_STATE_CONNECTED; gettimeofday(&server->lastconnecttry, NULL); pthread_mutex_unlock(&server->lock); return 1; @@ -603,7 +603,7 @@ int clientradputdtls(struct server *server, unsigned char *rad) { unsigned long error; struct clsrvconf *conf = server->conf; - if (!server->connectionok) + if (server->state != RSP_SERVER_STATE_CONNECTED) return 0; len = RADLEN(rad); if ((cnt = SSL_write(server->ssl, rad, len)) <= 0) { diff --git a/radsecproxy.c b/radsecproxy.c index c7a50ec..a90fb94 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -707,7 +707,7 @@ int hasdynamicserver(struct list *srvconfs) { struct list_node *entry; for (entry = list_first(srvconfs); entry; entry = list_next(entry)) - if (((struct clsrvconf *)entry->data)->dynamiclookupcommand) + if (((struct clsrvconf *)entry->data)->servers->dynamiclookuparg) return 1; return 0; } @@ -1260,11 +1260,11 @@ struct clsrvconf *choosesrvconf(struct list *srvconfs) { server = (struct clsrvconf *)entry->data; if (!server->servers) return server; - if (server->servers->dynfailing) + if (server->servers->state == RSP_SERVER_STATE_FAILING) continue; if (!first) first = server; - if (!server->servers->connectionok && !server->servers->dynstartup) + if (server->servers->state == RSP_SERVER_STATE_STARTUP || server->servers->state == RSP_SERVER_STATE_RECONNECTING) continue; if (!server->servers->lostrqs) return server; @@ -1560,7 +1560,6 @@ void replyh(struct server *server, unsigned char *buf) { struct tlv *attr; struct list_node *node; - server->connectionok = 1; server->lostrqs = 0; rqout = server->requests + buf[1]; @@ -1753,10 +1752,10 @@ void *clientwr(void *arg) { #define ZZZ 900 + server->state = RSP_SERVER_STATE_STARTUP; if (server->dynamiclookuparg && !dynamicconfig(server)) { dynconffail = 1; - server->dynstartup = 0; - server->dynfailing = 1; + server->state = RSP_SERVER_STATE_FAILING; debug(DBG_WARN, "%s: dynamicconfig(%s: %s) failed, sleeping %ds", __func__, server->conf->name, server->dynamiclookuparg, ZZZ); sleep(ZZZ); @@ -1767,6 +1766,7 @@ void *clientwr(void *arg) { * dynamicconfig() above? */ if (!resolvehostports(conf->hostports, conf->hostaf, conf->pdef->socktype)) { debug(DBG_WARN, "%s: resolve failed, sleeping %ds", __func__, ZZZ); + server->state = RSP_SERVER_STATE_FAILING; sleep(ZZZ); goto errexit; } @@ -1780,23 +1780,21 @@ void *clientwr(void *arg) { if (conf->pdef->connecter) { if (!conf->pdef->connecter(server, NULL, server->dynamiclookuparg ? 5 : 0, "clientwr")) { + server->state = RSP_SERVER_STATE_FAILING; if (server->dynamiclookuparg) { - server->dynstartup = 0; - server->dynfailing = 1; debug(DBG_WARN, "%s: connect failed, sleeping %ds", __func__, ZZZ); sleep(ZZZ); } goto errexit; } - server->connectionok = 1; if (pthread_create(&clientrdth, &pthread_attr, conf->pdef->clientconnreader, (void *)server)) { debugerrno(errno, DBG_ERR, "clientwr: pthread_create failed"); + server->state = RSP_SERVER_STATE_FAILING; goto errexit; } - } else - server->connectionok = 1; - server->dynstartup = 0; + } + server->state = RSP_SERVER_STATE_CONNECTED; for (;;) { pthread_mutex_lock(&server->newrq_mutex); @@ -1834,6 +1832,7 @@ void *clientwr(void *arg) { for (i = 0; i < MAX_REQUESTS; i++) { if (server->clientrdgone) { + server->state = RSP_SERVER_STATE_FAILING; if (conf->pdef->connecter) pthread_join(clientrdth, NULL); goto errexit; @@ -1885,7 +1884,7 @@ void *clientwr(void *arg) { conf->pdef->clientradput(server, rqout->rq->buf); pthread_mutex_unlock(rqout->lock); } - if (conf->statusserver && server->connectionok) { + if (conf->statusserver && server->state == RSP_SERVER_STATE_CONNECTED) { secs = server->lastrcv.tv_sec > laststatsrv.tv_sec ? server->lastrcv.tv_sec : laststatsrv.tv_sec; gettimeofday(&now, NULL); if (now.tv_sec - secs > STATUS_SERVER_PERIOD) { @@ -1906,8 +1905,6 @@ void *clientwr(void *arg) { free(conf); else freeclsrvconf(conf); - } else { - conf->servers = NULL; } freeserver(server, 1); return NULL; @@ -2188,7 +2185,7 @@ struct list *createsubrealmservers(struct realm *realm, struct list *srvconfs) { * the srvconfs list. */ if (addserver(srvconf)) { srvconf->servers->dynamiclookuparg = stringcopy(realm->name, 0); - srvconf->servers->dynstartup = 1; + srvconf->servers->state = RSP_SERVER_STATE_STARTUP; debug(DBG_DBG, "%s: new client writer for %s", __func__, srvconf->servers->conf->name); if (pthread_create(&clientth, &pthread_attr, clientwr, (void *)(srvconf->servers))) { diff --git a/radsecproxy.h b/radsecproxy.h index 78eafcd..ace2e01 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -58,6 +58,13 @@ enum rsp_fticks_mac_type { RSP_FTICKS_MAC_FULLY_KEY_HASHED }; +enum rsp_server_state { + RSP_SERVER_STATE_STARTUP = 0, /* default */ + RSP_SERVER_STATE_CONNECTED, + RSP_SERVER_STATE_RECONNECTING, + RSP_SERVER_STATE_FAILING +}; + struct options { char *pidfile; char *logdestination; @@ -166,10 +173,8 @@ struct server { uint8_t clientrdgone; struct timeval lastconnecttry; struct timeval lastreply; - uint8_t connectionok; + enum rsp_server_state state; uint8_t lostrqs; - uint8_t dynstartup; - uint8_t dynfailing; char *dynamiclookuparg; int nextid; struct timeval lastrcv; diff --git a/tcp.c b/tcp.c index d52edff..80cabee 100644 --- a/tcp.c +++ b/tcp.c @@ -102,8 +102,8 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t pthread_mutex_unlock(&server->lock); return 0; } - if (server->connectionok) { - server->connectionok = 0; + if (server->state == RSP_SERVER_STATE_CONNECTED) { + server->state = RSP_SERVER_STATE_RECONNECTING; sleep(2); } else if (elapsed < 1) sleep(2); @@ -124,7 +124,7 @@ int tcpconnect(struct server *server, struct timeval *when, int timeout, char *t break; } } - server->connectionok = 1; + server->state = RSP_SERVER_STATE_CONNECTED; gettimeofday(&server->lastconnecttry, NULL); pthread_mutex_unlock(&server->lock); return 1; @@ -205,7 +205,7 @@ int clientradputtcp(struct server *server, unsigned char *rad) { size_t len; struct clsrvconf *conf = server->conf; - if (!server->connectionok) + if (server->state != RSP_SERVER_STATE_CONNECTED) return 0; len = RADLEN(rad); if ((cnt = write(server->sock, rad, len)) <= 0) { diff --git a/tls.c b/tls.c index 2932b7b..8d9bfa6 100644 --- a/tls.c +++ b/tls.c @@ -111,8 +111,8 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t pthread_mutex_unlock(&server->lock); return 0; } - if (server->connectionok) { - server->connectionok = 0; + if (server->state == RSP_SERVER_STATE_CONNECTED) { + server->state = RSP_SERVER_STATE_RECONNECTING; sleep(2); } else if (elapsed < 1) sleep(2); @@ -158,7 +158,7 @@ int tlsconnect(struct server *server, struct timeval *when, int timeout, char *t X509_free(cert); } debug(DBG_WARN, "tlsconnect: TLS connection to %s up", server->conf->name); - server->connectionok = 1; + server->state = RSP_SERVER_STATE_CONNECTED; gettimeofday(&server->lastconnecttry, NULL); pthread_mutex_unlock(&server->lock); return 1; @@ -254,7 +254,7 @@ int clientradputtls(struct server *server, unsigned char *rad) { unsigned long error; struct clsrvconf *conf = server->conf; - if (!server->connectionok) + if (server->state != RSP_SERVER_STATE_CONNECTED) return 0; len = RADLEN(rad); if ((cnt = SSL_write(server->ssl, rad, len)) <= 0) {