From: Linus Nordberg Date: Thu, 12 Apr 2012 18:20:38 +0000 (+0200) Subject: Merge branch 'master' into dynconf2 X-Git-Tag: radsecproxy-1.6-rc0~11 X-Git-Url: http://www.project-moonshot.org/gitweb/?a=commitdiff_plain;h=0b229b06e65ea2d204e32e44fcf26ffd0cfdcc99;hp=28e1381a49869874b7fd291b8d82f6a231691dbb;p=radsecproxy.git Merge branch 'master' into dynconf2 --- diff --git a/ChangeLog b/ChangeLog index 7b38d95..8ba0401 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,12 +12,19 @@ configured explicitly. This was implemented by Maja Gorecka-Wolniewicz and Paweł Gołaszewski. (RADSECPROXY-29) - Add config option PidFile. (RADSECPROXY-32) + - Preliminary support for DynamicLookupCommand. It's for TLS + servers only at this point. Also, beware of risks for memory + leaks. Bug fixes: - Stop the autoconfery from warning about defining variables conditionally and unconditionally. - Honour configure option --sysconfdir. (RADSECPROXY-31) - Other bugs. (RADSECPROXY-26, -28, -34, -35, -39) + - Don't crash on failing DynamicLookupCommand scripts. + - When a DynamicLookupCommand script is failing, fall back to + other server(s) in the realm. The timeout depends on the kind of + failure. 2011-10-08 1.5 New features: diff --git a/radsecproxy.c b/radsecproxy.c index 88c198f..d8500c1 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -1306,6 +1307,8 @@ struct clsrvconf *choosesrvconf(struct list *srvconfs) { server = (struct clsrvconf *)entry->data; if (!server->servers) return server; + if (server->servers->dynfailing) + continue; if (!first) first = server; if (!server->servers->connectionok && !server->servers->dynstartup) @@ -1344,11 +1347,15 @@ struct server *findserver(struct realm **realm, struct tlv *username, uint8_t ac pthread_mutex_unlock(&(*realm)->mutex); freerealm(*realm); *realm = subrealm; + debug(DBG_DBG, "added realm: %s", (*realm)->name); srvconf = choosesrvconf(acc ? (*realm)->accsrvconfs : (*realm)->srvconfs); + debug(DBG_DBG, "found conf for new realm: %s", srvconf->name); } } - if (srvconf) + if (srvconf) { + debug(DBG_DBG, "found matching conf: %s", srvconf->name); server = srvconf->servers; + } exit: free(id); @@ -1751,18 +1758,25 @@ void *clientwr(void *arg) { conf = server->conf; +#define ZZZ 60 + if (server->dynamiclookuparg && !dynamicconfig(server)) { dynconffail = 1; server->dynstartup = 0; - sleep(900); + server->dynfailing = 1; + debug(DBG_WARN, "%s: dynamicconfig(%s) failed, sleeping %ds", + __func__, server->conf->name, ZZZ); + sleep(ZZZ); goto errexit; } + /* FIXME: Is resolving not always done by compileserverconfig(), + * either as part of static configuration setup or by + * dynamicconfig() above? */ if (!resolvehostports(conf->hostports, conf->pdef->socktype)) { - debug(DBG_WARN, "clientwr: resolve failed"); - server->dynstartup = 0; - sleep(900); - goto errexit; + debug(DBG_WARN, "%s: resolve failed, sleeping %ds", __func__, ZZZ); + sleep(ZZZ); + goto errexit; } memset(&timeout, 0, sizeof(struct timespec)); @@ -1775,8 +1789,11 @@ void *clientwr(void *arg) { if (conf->pdef->connecter) { if (!conf->pdef->connecter(server, NULL, server->dynamiclookuparg ? 5 : 0, "clientwr")) { if (server->dynamiclookuparg) { - server->dynstartup = 0; - sleep(900); + server->dynstartup = 0; + server->dynfailing = 1; + debug(DBG_WARN, "%s: connect failed, sleeping %ds", + __func__, ZZZ); + sleep(ZZZ); } goto errexit; } @@ -2173,10 +2190,17 @@ struct list *createsubrealmservers(struct realm *realm, struct list *srvconfs) { debug(DBG_ERR, "malloc failed"); continue; } + debug(DBG_DBG, "%s: copying config %s", __func__, conf->name); *srvconf = *conf; + /* Shallow copy -- sharing all the pointers. addserver() + * will take care of servers (which btw has to be NUL) but + * the rest of them are shared with the config found in + * the srvconfs list. */ if (addserver(srvconf)) { srvconf->servers->dynamiclookuparg = stringcopy(realm->name, 0); srvconf->servers->dynstartup = 1; + debug(DBG_DBG, "%s: new client writer for %s", + __func__, srvconf->servers->conf->name); if (pthread_create(&clientth, NULL, clientwr, (void *)(srvconf->servers))) { debugerrno(errno, DBG_ERR, "pthread_create failed"); freeserver(srvconf->servers, 1); @@ -2273,14 +2297,9 @@ int dynamicconfig(struct server *server) { } if (status) { - if (WEXITSTATUS(status) == 10) { - debug(DBG_INFO, "dynamicconfig: command signals empty config"); - } - else { - debug(DBG_INFO, "dynamicconfig: command exited with status %d", - WEXITSTATUS(status)); - goto errexit; - } + debug(DBG_INFO, "dynamicconfig: command exited with status %d", + WEXITSTATUS(status)); + goto errexit; } if (ok) @@ -2544,6 +2563,9 @@ int setttlattr(struct options *opts, char *defaultattr) { } void freeclsrvconf(struct clsrvconf *conf) { + assert(conf); + assert(conf->name); + debug(DBG_DBG, "%s: freeing %p (%s)", __func__, conf, conf->name); free(conf->name); if (conf->hostsrc) freegconfmstr(conf->hostsrc); diff --git a/radsecproxy.h b/radsecproxy.h index 680a58d..dc09b1e 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -160,6 +160,7 @@ struct server { uint8_t connectionok; uint8_t lostrqs; uint8_t dynstartup; + uint8_t dynfailing; char *dynamiclookuparg; int nextid; struct timeval lastrcv; diff --git a/tools/naptr-eduroam.sh b/tools/naptr-eduroam.sh index 43d3d9f..6497549 100755 --- a/tools/naptr-eduroam.sh +++ b/tools/naptr-eduroam.sh @@ -70,4 +70,4 @@ if [ -n "${SERVERS}" ]; then exit 0 fi -exit 0 +exit 10 # No server found. diff --git a/tools/radsec-dynsrv.sh b/tools/radsec-dynsrv.sh index 4d00f32..3150018 100755 --- a/tools/radsec-dynsrv.sh +++ b/tools/radsec-dynsrv.sh @@ -48,4 +48,4 @@ if test -n "${SERVERS}" ; then exit 0 fi -exit 0 +exit 10 # No server found. diff --git a/udp.c b/udp.c index 2724a1d..7614f2e 100644 --- a/udp.c +++ b/udp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "radsecproxy.h" #include "hostport.h" @@ -317,6 +318,7 @@ void addclientudp(struct client *client) { } void addserverextraudp(struct clsrvconf *conf) { + assert(list_first(conf->hostports) != NULL); switch (((struct hostportres *)list_first(conf->hostports)->data)->addrinfo->ai_family) { case AF_INET: if (client4_sock < 0) {