timeout for connect
[radsecproxy.git] / radsecproxy.c
index 7266597..5aae539 100644 (file)
@@ -53,7 +53,6 @@
 #endif
 #include <sys/time.h>
 #include <sys/types.h>
-#include <sys/select.h>
 #include <ctype.h>
 #include <sys/wait.h>
 #include <arpa/inet.h>
@@ -1738,7 +1737,7 @@ void *clientwr(void *arg) {
     }
     
     if (!resolvehostports(conf->hostports, conf->pdef->socktype)) {
-       debug(DBG_WARN, "failed to resolve host %s port %s", conf->hostsrc ? conf->hostsrc : "(null)", conf->portsrc ? conf->portsrc : "(null)");
+       debug(DBG_WARN, "clientwr: resolve failed");
        server->dynstartup = 0;
        sleep(900);
        goto errexit;
@@ -1884,14 +1883,14 @@ void *clientwr(void *arg) {
 
 void createlistener(uint8_t type, char *arg) {
     pthread_t th;
-    struct addrinfo *listenres, *res;
+    struct addrinfo *res;
     int s = -1, on = 1, *sp = NULL;
-
-    listenres = resolvepassiveaddrinfo(arg, protodefs[type]->portdefault, protodefs[type]->socktype);
-    if (!listenres)
+    struct hostportres *hp = newhostport(arg, protodefs[type]->portdefault, 0);
+    
+    if (!hp || !resolvehostport(hp, protodefs[type]->socktype, 1))
        debugx(1, DBG_ERR, "createlistener: failed to resolve %s", arg);
     
-    for (res = listenres; res; res = res->ai_next) {
+    for (res = hp->addrinfo; res; res = res->ai_next) {
         s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
         if (s < 0) {
             debug(DBG_WARN, "createlistener: socket failed");
@@ -1920,8 +1919,8 @@ void createlistener(uint8_t type, char *arg) {
     if (!sp)
        debugx(1, DBG_ERR, "createlistener: socket/bind failed");
     
-    debug(DBG_WARN, "createlistener: listening for %s on %s", protodefs[type]->name, arg);
-    freeaddrinfo(listenres);
+    debug(DBG_WARN, "createlistener: listening for %s on %s:%s", protodefs[type]->name, hp->host ? hp->host : "*", hp->port);
+    freehostport(hp);
 }
 
 void createlisteners(uint8_t type) {
@@ -2470,7 +2469,8 @@ int setttlattr(struct options *opts, char *defaultattr) {
 
 void freeclsrvconf(struct clsrvconf *conf) {
     free(conf->name);
-    free(conf->hostsrc);
+    if (conf->hostsrc)
+       freegconfmstr(conf->hostsrc);
     free(conf->portsrc);
     free(conf->secret);
     free(conf->tls);
@@ -2519,10 +2519,51 @@ int mergeconfstring(char **dst, char **src) {
     return 1;
 }
 
+char **mstringcopy(char **in) {
+    char **out;
+    int n;
+    
+    if (!in)
+       return NULL;
+
+    for (n = 0; in[n]; n++);
+    out = malloc((n + 1) * sizeof(char *));
+    if (!out)
+       return NULL;
+    for (n = 0; in[n]; n++) {
+       out[n] = stringcopy(in[n], 0);
+       if (!out[n]) {
+           freegconfmstr(out);
+           return NULL;
+       }
+    }
+    out[n] = NULL;
+    return out;
+}
+
+int mergeconfmstring(char ***dst, char ***src) {
+    char **t;
+    
+    if (*src) {
+       *dst = *src;
+       *src = NULL;
+       return 1;
+    }
+    if (*dst) {
+       t = mstringcopy(*dst);
+       if (!t) {
+           debug(DBG_ERR, "malloc failed");
+           return 0;
+       }
+       *dst = t;
+    }
+    return 1;
+}
+
 /* assumes dst is a shallow copy */
 int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
     if (!mergeconfstring(&dst->name, &src->name) ||
-       !mergeconfstring(&dst->hostsrc, &src->hostsrc) ||
+       !mergeconfmstring(&dst->hostsrc, &src->hostsrc) ||
        !mergeconfstring(&dst->portsrc, &src->portsrc) ||
        !mergeconfstring(&dst->secret, &src->secret) ||
        !mergeconfstring(&dst->tls, &src->tls) ||
@@ -2557,7 +2598,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
     
     if (!getgenericconfig(cf, block,
                          "type", CONF_STR, &conftype,
-                         "host", CONF_STR, &conf->hostsrc,
+                         "host", CONF_MSTR, &conf->hostsrc,
                          "secret", CONF_STR, &conf->secret,
 #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)    
                          "tls", CONF_STR, &conf->tls,
@@ -2575,9 +2616,14 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
        debugx(1, DBG_ERR, "configuration error");
     
     conf->name = stringcopy(val, 0);
-    if (!conf->hostsrc)
-       conf->hostsrc = stringcopy(val, 0);
-    if (!conf->name || !conf->hostsrc)
+    if (conf->name && !conf->hostsrc) {
+       conf->hostsrc = malloc(2 * sizeof(char *));
+       if (conf->hostsrc) {
+           conf->hostsrc[0] = stringcopy(val, 0);
+           conf->hostsrc[1] = NULL;
+       }
+    }
+    if (!conf->name || !conf->hostsrc || !conf->hostsrc[0])
        debugx(1, DBG_ERR, "malloc failed");
        
     if (!conftype)
@@ -2627,7 +2673,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
 
     if (!addhostport(&conf->hostports, conf->hostsrc, conf->pdef->portdefault, 1) ||
        !resolvehostports(conf->hostports, conf->pdef->socktype))
-       debugx(1, DBG_ERR, "failed to resolve %s, exiting", conf->hostsrc ? conf->hostsrc : "(null)");
+       debugx(1, DBG_ERR, "resolve failed, exiting");
     
     if (!conf->secret) {
        if (!conf->pdef->secretdefault)
@@ -2685,7 +2731,7 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {
     }
 
     if (!conf->dynamiclookupcommand && !resolvehostports(conf->hostports, conf->pdef->socktype)) {
-       debug(DBG_ERR, "resolve host %s port %s, exiting", conf->hostsrc ? conf->hostsrc : "(null)", conf->portsrc ? conf->portsrc : "(null)");
+       debug(DBG_ERR, "resolve failed, exiting");
        return 0;
     }
     return 1;
@@ -2713,7 +2759,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
 
     if (!getgenericconfig(cf, block,
                          "type", CONF_STR, &conftype,
-                         "host", CONF_STR, &conf->hostsrc,
+                         "host", CONF_MSTR, &conf->hostsrc,
                          "port", CONF_STR, &conf->portsrc,
                          "secret", CONF_STR, &conf->secret,
 #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)    
@@ -2736,17 +2782,17 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
     }
     
     conf->name = stringcopy(val, 0);
-    if (!conf->name) {
+    if (conf->name && !conf->hostsrc) {
+       conf->hostsrc = malloc(2 * sizeof(char *));
+       if (conf->hostsrc) {
+           conf->hostsrc[0] = stringcopy(val, 0);
+           conf->hostsrc[1] = NULL;
+       }
+    }
+    if (!conf->name || !conf->hostsrc || !conf->hostsrc[0]) {
         debug(DBG_ERR, "malloc failed");
        goto errexit;
     }
-    if (!conf->hostsrc) {
-       conf->hostsrc = stringcopy(val, 0);
-       if (!conf->hostsrc) {
-            debug(DBG_ERR, "malloc failed");
-           goto errexit;
-        }
-    }
 
     if (!conftype) {
        debug(DBG_ERR, "error in block %s, option type missing", block);