Don't cry and die on a configured server (!) which doesn't resolve (DNS). Just cry... postpone-resolving
authorLinus Nordberg <linus@nordu.net>
Wed, 11 Apr 2012 11:30:30 +0000 (13:30 +0200)
committerLinus Nordberg <linus@nordu.net>
Wed, 11 Apr 2012 11:30:30 +0000 (13:30 +0200)
Part of fixing RADSECPROXY-30.

common.c [new file with mode: 0644]
common.h [new file with mode: 0644]
dtls.c
radsecproxy.c
radsecproxy.h
udp.c
util.c
util.h

diff --git a/common.c b/common.c
new file mode 100644 (file)
index 0000000..6a73a2c
--- /dev/null
+++ b/common.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012 NORDUnet A/S
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#include <sys/socket.h>
+/*#include <netinet/in.h>*/
+#include <netdb.h>
+#include <assert.h>
+#include "radsecproxy.h"
+#include "debug.h"
+#include "hostport.h"
+#include "util.h"
+#include "common.h"
+
+int
+addserverextra(const struct clsrvconf *conf,
+               int *socket4,
+               int *socket6,
+               struct addrinfo *addrinfo)
+{
+    struct hostportres *hp = NULL;
+
+    assert(conf != NULL);
+    assert(socket != NULL);
+
+    if (list_first(conf->hostports) == NULL)
+        return 0;
+    hp = (struct hostportres *) list_first(conf->hostports)->data;
+    if (hp == NULL || hp->addrinfo == NULL)
+        return 0;
+
+    switch (hp->addrinfo->ai_family) {
+    case AF_INET:
+       if (*socket4 < 0) {
+            /* FIXME: arg 4 is v6only, wtf? */
+           *socket4 = bindtoaddr(addrinfo, AF_INET, 0, 1);
+           if (*socket4 < 0) {
+               debug(DBG_ERR,
+                      "%s: failed to create client socket for server %s",
+                      __func__, conf->name);
+                return 0;
+            }
+       }
+       conf->servers->sock = *socket4;
+       break;
+    case AF_INET6:
+       if (*socket6 < 0) {
+           *socket6 = bindtoaddr(addrinfo, AF_INET6, 0, 1);
+           if (*socket6 < 0) {
+               debug(DBG_ERR,
+                      "%s: failed to create client socket for server %s",
+                      __func__, conf->name);
+                return 0;
+            }
+       }
+       conf->servers->sock = *socket6;
+       break;
+    default:
+       debug(DBG_ERR, "%s: unsupported address family", __func__);
+        return 0;
+    }
+
+    return 1;
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/common.h b/common.h
new file mode 100644 (file)
index 0000000..e94f347
--- /dev/null
+++ b/common.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2012 NORDUnet A/S
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+int addserverextra(const struct clsrvconf *conf,
+                   int *socket4,
+                   int *socket6,
+                   struct addrinfo *addrinfo);
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/dtls.c b/dtls.c
index 19386c4..9913cd9 100644 (file)
--- a/dtls.c
+++ b/dtls.c
@@ -28,6 +28,7 @@
 #include <openssl/err.h>
 #include "hash.h"
 #include "radsecproxy.h"
+#include "common.h"
 
 #ifdef RADPROT_DTLS
 #include "debug.h"
@@ -40,7 +41,7 @@ void *udpdtlsserverrd(void *arg);
 int dtlsconnect(struct server *server, struct timeval *when, int timeout, char *text);
 void *dtlsclientrd(void *arg);
 int clientradputdtls(struct server *server, unsigned char *rad);
-void addserverextradtls(struct clsrvconf *conf);
+int addserverextradtls(const struct clsrvconf *conf);
 void dtlssetsrcres();
 void initextradtls();
 
@@ -665,27 +666,8 @@ void *dtlsclientrd(void *arg) {
     return NULL;
 }
 
-void addserverextradtls(struct clsrvconf *conf) {
-    switch (((struct hostportres *)list_first(conf->hostports)->data)->addrinfo->ai_family) {
-    case AF_INET:
-       if (client4_sock < 0) {
-           client4_sock = bindtoaddr(srcres, AF_INET, 0, 1);
-           if (client4_sock < 0)
-               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->name);
-       }
-       conf->servers->sock = client4_sock;
-       break;
-    case AF_INET6:
-       if (client6_sock < 0) {
-           client6_sock = bindtoaddr(srcres, AF_INET6, 0, 1);
-           if (client6_sock < 0)
-               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->name);
-       }
-       conf->servers->sock = client6_sock;
-       break;
-    default:
-       debugx(1, DBG_ERR, "addserver: unsupported address family");
-    }
+int addserverextradtls(const struct clsrvconf *conf) {
+    return addserverextra(conf, &client4_sock, &client6_sock, srcres);
 }
 
 void initextradtls() {
index 845c208..15ce540 100644 (file)
@@ -360,7 +360,8 @@ int addserver(struct clsrvconf *conf) {
 
     conf->servers->sock = -1;
     if (conf->pdef->addserverextra)
-       conf->pdef->addserverextra(conf);
+       if (!conf->pdef->addserverextra(conf))
+            return 0;
 
     conf->servers->requests = calloc(MAX_REQUESTS, sizeof(struct rqout));
     if (!conf->servers->requests) {
@@ -2822,10 +2823,9 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {
        return 0;
     }
 
-    if (!conf->dynamiclookupcommand && !resolvehostports(conf->hostports, conf->pdef->socktype)) {
-       debug(DBG_ERR, "%s: resolve failed", __func__);
-       return 0;
-    }
+    if (!conf->dynamiclookupcommand && !resolvehostports(conf->hostports, conf->pdef->socktype))
+       debug(DBG_WARN, "%s: resolve failed", __func__);
+
     return 1;
 }
 
@@ -3295,7 +3295,7 @@ int radsecproxy_main(int argc, char **argv) {
        if (srvconf->dynamiclookupcommand)
            continue;
        if (!addserver(srvconf))
-           debugx(1, DBG_ERR, "failed to add server");
+           debug(DBG_WARN, "failed to add at least one server");
        if (pthread_create(&srvconf->servers->clientth, NULL, clientwr,
                           (void *)(srvconf->servers)))
            debugx(1, DBG_ERR, "pthread_create failed");
index 184231b..e4ac4a0 100644 (file)
@@ -212,7 +212,7 @@ struct protodefs {
     void *(*clientconnreader)(void*);
     int (*clientradput)(struct server *, unsigned char *);
     void (*addclient)(struct client *);
-    void (*addserverextra)(struct clsrvconf *);
+    int (*addserverextra)(const struct clsrvconf *conf);
     void (*setsrcres)();
     void (*initextra)();
 };
diff --git a/udp.c b/udp.c
index 2724a1d..9484ab9 100644 (file)
--- a/udp.c
+++ b/udp.c
@@ -25,6 +25,7 @@
 #include <regex.h>
 #include <pthread.h>
 #include "radsecproxy.h"
+#include "common.h"
 #include "hostport.h"
 
 #ifdef RADPROT_UDP
@@ -36,7 +37,7 @@ static char **getlistenerargs();
 void *udpserverrd(void *arg);
 int clientradputudp(struct server *server, unsigned char *rad);
 void addclientudp(struct client *client);
-void addserverextraudp(struct clsrvconf *conf);
+int addserverextraudp(const struct clsrvconf *conf);
 void udpsetsrcres();
 void initextraudp();
 
@@ -316,27 +317,8 @@ void addclientudp(struct client *client) {
     client->replyq = server_replyq;
 }
 
-void addserverextraudp(struct clsrvconf *conf) {
-    switch (((struct hostportres *)list_first(conf->hostports)->data)->addrinfo->ai_family) {
-    case AF_INET:
-       if (client4_sock < 0) {
-           client4_sock = bindtoaddr(srcres, AF_INET, 0, 1);
-           if (client4_sock < 0)
-               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->name);
-       }
-       conf->servers->sock = client4_sock;
-       break;
-    case AF_INET6:
-       if (client6_sock < 0) {
-           client6_sock = bindtoaddr(srcres, AF_INET6, 0, 1);
-           if (client6_sock < 0)
-               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->name);
-       }
-       conf->servers->sock = client6_sock;
-       break;
-    default:
-       debugx(1, DBG_ERR, "addserver: unsupported address family");
-    }
+int addserverextraudp(const struct clsrvconf *conf) {
+    return addserverextra(conf, &client4_sock, &client6_sock, srcres);
 }
 
 void initextraudp() {
diff --git a/util.c b/util.c
index dc36ed9..b9b27e8 100644 (file)
--- a/util.c
+++ b/util.c
@@ -114,7 +114,7 @@ char *addr2string(struct sockaddr *addr) {
    RADIUS packet to be discarded on first attempt (due to Path MTU discovery).
 */
 
-void disable_DF_bit(int socket, struct addrinfo *res) {
+void disable_DF_bit(int socket, const struct addrinfo *res) {
     if ((res->ai_family == AF_INET) && (res->ai_socktype == SOCK_DGRAM)) {
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
         /*
@@ -132,11 +132,11 @@ void disable_DF_bit(int socket, struct addrinfo *res) {
     }
 }
 
-int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
+int bindtoaddr(const struct addrinfo *addrinfo, int family, int reuse, int v6only) {
     int s, on = 1;
-    struct addrinfo *res;
+    const struct addrinfo *res = addrinfo;
 
-    for (res = addrinfo; res; res = res->ai_next) {
+    for (; res; res = res->ai_next) {
        if (family != AF_UNSPEC && family != res->ai_family)
            continue;
        s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
diff --git a/util.h b/util.h
index d8d002c..1bd8c33 100644 (file)
--- a/util.h
+++ b/util.h
@@ -15,8 +15,8 @@ struct sockaddr *addr_copy(struct sockaddr *in);
 void port_set(struct sockaddr *sa, uint16_t port);
 
 void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len);
-void disable_DF_bit(int socket, struct addrinfo *res);
-int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);
+void disable_DF_bit(int socket, const struct addrinfo *res);
+int bindtoaddr(const struct addrinfo *addrinfo, int family, int reuse, int v6only);
 int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout);