restructuring code
authorvenaas <venaas>
Thu, 21 Aug 2008 09:55:13 +0000 (09:55 +0000)
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>
Thu, 21 Aug 2008 09:55:13 +0000 (09:55 +0000)
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@351 e88ac4ed-0b26-0410-9574-a7f39faa03bf

dtls.c
dtls.h
radsecproxy.c
radsecproxy.h
udp.c
udp.h
util.c
util.h

diff --git a/dtls.c b/dtls.c
index 5bd7826..9f68133 100644 (file)
--- a/dtls.c
+++ b/dtls.c
@@ -32,6 +32,9 @@
 #include "radsecproxy.h"
 #include "dtls.h"
 
+static int client4_sock = -1;
+static int client6_sock = -1;
+
 int udp2bio(int s, struct queue *q, int cnt) {
     unsigned char *buf;
     BIO *rbio;
@@ -470,3 +473,42 @@ void *dtlsclientrd(void *arg) {
            free(buf);
     }
 }
+
+void addclientdtls(struct client *client) {
+    client->replyq = newqueue();
+    client->rbios = newqueue();
+}
+
+void addserverextradtls(struct clsrvconf *conf) {
+    switch (conf->addrinfo->ai_family) {
+    case AF_INET:
+       if (client4_sock < 0) {
+           client4_sock = bindtoaddr(getsrcprotores(RAD_DTLS), AF_INET, 0, 1);
+           if (client4_sock < 0)
+               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
+       }
+       conf->servers->sock = client4_sock;
+       break;
+    case AF_INET6:
+       if (client6_sock < 0) {
+           client6_sock = bindtoaddr(getsrcprotores(RAD_DTLS), AF_INET6, 0, 1);
+           if (client6_sock < 0)
+               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
+       }
+       conf->servers->sock = client6_sock;
+       break;
+    default:
+       debugx(1, DBG_ERR, "addserver: unsupported address family");
+    }
+}
+
+void initextradtls() {
+    pthread_t cl4th, cl6th;
+    
+    if (client4_sock >= 0)
+       if (pthread_create(&cl4th, NULL, udpdtlsclientrd, (void *)&client4_sock))
+           debugx(1, DBG_ERR, "pthread_create failed");
+    if (client6_sock >= 0)
+       if (pthread_create(&cl6th, NULL, udpdtlsclientrd, (void *)&client6_sock))
+           debugx(1, DBG_ERR, "pthread_create failed");
+}
diff --git a/dtls.h b/dtls.h
index 41ee54d..af9054d 100644 (file)
--- a/dtls.h
+++ b/dtls.h
@@ -12,3 +12,6 @@ void *dtlsservernew(void *arg);
 void *dtlsclientrd(void *arg);
 void *udpdtlsclientrd(void *arg);
 int clientradputdtls(struct server *server, unsigned char *rad);
+void addclientdtls(struct client *client);
+void addserverextradtls(struct clsrvconf *conf);
+void initextradtls();
index 63dba64..8f76aaa 100644 (file)
@@ -75,11 +75,6 @@ struct list *realms, *tlsconfs, *rewriteconfs;
 
 static struct addrinfo *srcprotores[4] = { NULL, NULL, NULL, NULL };
 
-static struct queue *udp_server_replyq = NULL;
-static int udp_client4_sock = -1;
-static int udp_client6_sock = -1;
-static int dtls_client4_sock = -1;
-static int dtls_client6_sock = -1;
 static pthread_mutex_t tlsconfs_lock;
 static pthread_mutex_t *ssl_locks = NULL;
 static long *ssl_lock_count;
@@ -106,8 +101,11 @@ static const struct protodefs protodefs[] = {
        udpserverrd, /* listener */
        &options.sourceudp, /* srcaddrport */
        NULL, /* connecter */
-       udpclientrd, /* clientreader */
-       clientradputudp /* clientradput */
+       NULL, /* clientconnreader */
+       clientradputudp, /* clientradput */
+       addclientudp, /* addclient */
+       addserverextraudp, /* addserverextra */
+       initextraudp /* initextra */
     },
     {   "tls", /* TLS, assuming RAD_TLS defined as 1 */
        "mysecret", /* secretdefault */
@@ -120,8 +118,11 @@ static const struct protodefs protodefs[] = {
        tlslistener, /* listener */
        &options.sourcetls, /* srcaddrport */
        tlsconnect, /* connecter */
-       tlsclientrd, /* clientreader */
-       clientradputtls /* clientradput */
+       tlsclientrd, /* clientconnreader */
+       clientradputtls, /* clientradput */
+       NULL, /* addclient */
+       NULL, /* addserverextra */
+       NULL /* initextra */
     },
     {   "tcp", /* TCP, assuming RAD_TCP defined as 2 */
        NULL, /* secretdefault */
@@ -134,8 +135,11 @@ static const struct protodefs protodefs[] = {
        tcplistener, /* listener */
        &options.sourcetcp, /* srcaddrport */
        tcpconnect, /* connecter */
-       tcpclientrd, /* clientreader */
-       clientradputtcp /* clientradput */
+       tcpclientrd, /* clientconnreader */
+       clientradputtcp, /* clientradput */
+       NULL, /* addclient */
+       NULL, /* addserverextra */
+       NULL /* initextra */
     },
     {   "dtls", /* DTLS, assuming RAD_DTLS defined as 3 */
        "mysecret", /* secretdefault */
@@ -148,8 +152,11 @@ static const struct protodefs protodefs[] = {
        udpdtlsserverrd, /* listener */
        &options.sourcedtls, /* srcaddrport */
        dtlsconnect, /* connecter */
-       dtlsclientrd, /* clientreader */
-       clientradputdtls /* clientradput */
+       dtlsclientrd, /* clientconnreader */
+       clientradputdtls, /* clientradput */
+       addclientdtls, /* addclient */
+       addserverextradtls, /* addserverextra */
+       initextradtls /* initextra */
     },
     {   NULL
     }
@@ -307,33 +314,6 @@ int resolvepeer(struct clsrvconf *conf, int ai_flags) {
     return 1;
 }        
 
-int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
-    int s, on = 1;
-    struct addrinfo *res;
-    
-    for (res = addrinfo; 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);
-        if (s < 0) {
-            debug(DBG_WARN, "bindtoaddr: socket failed");
-            continue;
-        }
-       if (reuse)
-           setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-#ifdef IPV6_V6ONLY
-       if (v6only)
-           setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
-#endif         
-
-       if (!bind(s, res->ai_addr, res->ai_addrlen))
-           return s;
-       debug(DBG_WARN, "bindtoaddr: bind failed");
-        close(s);
-    }
-    return -1;
-}        
-
 char *parsehostport(char *s, struct clsrvconf *conf, char *default_port) {
     char *p, *field;
     int ipv6 = 0;
@@ -490,11 +470,11 @@ struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_
 }
 
 /* returns next config of given type, or NULL */
-struct clsrvconf *find_conf_type(uint8_t type, struct list *confs, struct list_node **cur) {
+struct clsrvconf *find_clconf_type(uint8_t type, struct list_node **cur) {
     struct list_node *entry;
     struct clsrvconf *conf;
     
-    for (entry = (cur && *cur ? list_next(*cur) : list_first(confs)); entry; entry = list_next(entry)) {
+    for (entry = (cur && *cur ? list_next(*cur) : list_first(clconfs)); entry; entry = list_next(entry)) {
        conf = (struct clsrvconf *)entry->data;
        if (conf->type == type) {
            if (cur)
@@ -558,9 +538,10 @@ struct client *addclient(struct clsrvconf *conf) {
     
     memset(new, 0, sizeof(struct client));
     new->conf = conf;
-    new->replyq = conf->type == RAD_UDP ? udp_server_replyq : newqueue();
-    if (conf->type == RAD_DTLS)
-       new->rbios = newqueue();
+    if (conf->pdef->addclient)
+       conf->pdef->addclient(new);
+    else
+       new->replyq = newqueue();
     list_push(conf->clients, new);
     return new;
 }
@@ -645,54 +626,9 @@ int addserver(struct clsrvconf *conf) {
        freeclsrvres(res);
     }
 
-    switch (type) {
-    case RAD_UDP:
-       switch (conf->addrinfo->ai_family) {
-       case AF_INET:
-           if (udp_client4_sock < 0) {
-               udp_client4_sock = bindtoaddr(srcprotores[RAD_UDP], AF_INET, 0, 1);
-               if (udp_client4_sock < 0)
-                   debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
-           }
-           conf->servers->sock = udp_client4_sock;
-           break;
-       case AF_INET6:
-           if (udp_client6_sock < 0) {
-               udp_client6_sock = bindtoaddr(srcprotores[RAD_UDP], AF_INET6, 0, 1);
-               if (udp_client6_sock < 0)
-                   debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
-           }
-           conf->servers->sock = udp_client6_sock;
-           break;
-       default:
-           debugx(1, DBG_ERR, "addserver: unsupported address family");
-       }
-       break;
-    case RAD_DTLS:
-       switch (conf->addrinfo->ai_family) {
-       case AF_INET:
-           if (dtls_client4_sock < 0) {
-               dtls_client4_sock = bindtoaddr(srcprotores[RAD_DTLS], AF_INET, 0, 1);
-               if (dtls_client4_sock < 0)
-                   debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
-           }
-           conf->servers->sock = dtls_client4_sock;
-           break;
-       case AF_INET6:
-           if (dtls_client6_sock < 0) {
-               dtls_client6_sock = bindtoaddr(srcprotores[RAD_DTLS], AF_INET6, 0, 1);
-               if (dtls_client6_sock < 0)
-                   debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
-           }
-           conf->servers->sock = dtls_client6_sock;
-           break;
-       default:
-           debugx(1, DBG_ERR, "addserver: unsupported address family");
-       }
-       break;
-    default:
-       conf->servers->sock = -1;
-    }
+    conf->servers->sock = -1;
+    if (conf->pdef->addserverextra)
+       conf->pdef->addserverextra(conf);
     
     conf->servers->requests = calloc(MAX_REQUESTS, sizeof(struct request));
     if (!conf->servers->requests) {
@@ -2166,7 +2102,7 @@ void *clientwr(void *arg) {
        if (!conf->pdef->connecter(server, NULL, server->dynamiclookuparg ? 6 : 0, "clientwr"))
            goto errexit;
        server->connectionok = 1;
-       if (pthread_create(&clientrdth, NULL, conf->pdef->clientreader, (void *)server)) {
+       if (pthread_create(&clientrdth, NULL, conf->pdef->clientconnreader, (void *)server)) {
            debug(DBG_ERR, "clientwr: pthread_create failed");
            goto errexit;
        }
@@ -3506,12 +3442,13 @@ void *sighandler(void *arg) {
 }
 
 int main(int argc, char **argv) {
-    pthread_t sigth, udpclient4rdth, udpclient6rdth, udpserverwrth, dtlsclient4rdth, dtlsclient6rdth;
+    pthread_t sigth;
     sigset_t sigset;
     struct list_node *entry;
     uint8_t foreground = 0, pretend = 0, loglevel = 0;
     char *configfile = NULL;
     struct clsrvconf *srvconf;
+    int i;
     
     debug_init("radsecproxy");
     debug_set_level(DEBUG_LEVEL);
@@ -3563,34 +3500,21 @@ int main(int argc, char **argv) {
        freeaddrinfo(srcprotores[RAD_UDP]);
        srcprotores[RAD_UDP] = NULL;
     }
+
+    for (i = 0; protodefs[i].name; i++)
+       if (protodefs[i].initextra)
+           protodefs[i].initextra();
     
-    if (udp_client4_sock >= 0)
-       if (pthread_create(&udpclient4rdth, NULL, protodefs[RAD_UDP].clientreader, (void *)&udp_client4_sock))
-           debugx(1, DBG_ERR, "pthread_create failed");
-    if (udp_client6_sock >= 0)
-       if (pthread_create(&udpclient6rdth, NULL, protodefs[RAD_UDP].clientreader, (void *)&udp_client6_sock))
-           debugx(1, DBG_ERR, "pthread_create failed");
-    
-    if (dtls_client4_sock >= 0)
-       if (pthread_create(&dtlsclient4rdth, NULL, udpdtlsclientrd, (void *)&dtls_client4_sock))
-           debugx(1, DBG_ERR, "pthread_create failed");
-    if (dtls_client6_sock >= 0)
-       if (pthread_create(&dtlsclient6rdth, NULL, udpdtlsclientrd, (void *)&dtls_client6_sock))
-           debugx(1, DBG_ERR, "pthread_create failed");
-    
-    if (find_conf_type(RAD_TCP, clconfs, NULL))
+    if (find_clconf_type(RAD_TCP, NULL))
        createlisteners(RAD_TCP, options.listentcp);
     
-    if (find_conf_type(RAD_TLS, clconfs, NULL))
+    if (find_clconf_type(RAD_TLS, NULL))
        createlisteners(RAD_TLS, options.listentls);
     
-    if (find_conf_type(RAD_DTLS, clconfs, NULL))
+    if (find_clconf_type(RAD_DTLS, NULL))
        createlisteners(RAD_DTLS, options.listendtls);
     
-    if (find_conf_type(RAD_UDP, clconfs, NULL)) {
-       udp_server_replyq = newqueue();
-       if (pthread_create(&udpserverwrth, NULL, udpserverwr, (void *)udp_server_replyq))
-           debugx(1, DBG_ERR, "pthread_create failed");
+    if (find_clconf_type(RAD_UDP, NULL)) {
        createlisteners(RAD_UDP, options.listenudp);
        if (options.listenaccudp)
            createlisteners(RAD_UDP, options.listenaccudp);
index c2e9425..f3c0742 100644 (file)
@@ -187,8 +187,11 @@ struct protodefs {
     void *(*listener)(void*);
     char **srcaddrport;
     int (*connecter)(struct server *, struct timeval *, int, char *);
-    void *(*clientreader)(void*);
+    void *(*clientconnreader)(void*);
     int (*clientradput)(struct server *, unsigned char *);
+    void (*addclient)(struct client *);
+    void (*addserverextra)(struct clsrvconf *);
+    void (*initextra)();
 };
 
 #define RADLEN(x) ntohs(((uint16_t *)(x))[1])
@@ -205,9 +208,11 @@ struct protodefs {
 struct addrinfo *getsrcprotores(uint8_t type);
 struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
 struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
+struct clsrvconf *find_clconf_type(uint8_t type, struct list_node **cur);
 struct client *addclient(struct clsrvconf *conf);
 void removeclient(struct client *client);
 void removeclientrqs(struct client *client);
+struct queue *newqueue();
 int radsrv(struct request *rq);
 X509 *verifytlscert(SSL *ssl);
 int verifyconfcert(X509 *cert, struct clsrvconf *conf);
diff --git a/udp.c b/udp.c
index 470e6d8..db4dbfe 100644 (file)
--- a/udp.c
+++ b/udp.c
 #include "radsecproxy.h"
 #include "tls.h"
 
+static int client4_sock = -1;
+static int client6_sock = -1;
+static struct queue *server_replyq = NULL;
+
 /* exactly one of client and server must be non-NULL */
 /* return who we received from in *client or *server */
 /* return from in sa if not NULL */
@@ -194,3 +198,47 @@ void *udpserverwr(void *arg) {
        free(reply);
     }
 }
+
+void addclientudp(struct client *client) {
+    client->replyq = server_replyq;
+}
+
+void addserverextraudp(struct clsrvconf *conf) {
+    switch (conf->addrinfo->ai_family) {
+    case AF_INET:
+       if (client4_sock < 0) {
+           client4_sock = bindtoaddr(getsrcprotores(RAD_UDP), AF_INET, 0, 1);
+           if (client4_sock < 0)
+               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
+       }
+       conf->servers->sock = client4_sock;
+       break;
+    case AF_INET6:
+       if (client6_sock < 0) {
+           client6_sock = bindtoaddr(getsrcprotores(RAD_UDP), AF_INET6, 0, 1);
+           if (client6_sock < 0)
+               debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->host);
+       }
+       conf->servers->sock = client6_sock;
+       break;
+    default:
+       debugx(1, DBG_ERR, "addserver: unsupported address family");
+    }
+}
+
+void initextraudp() {
+    pthread_t cl4th, cl6th, srvth;
+    
+    if (client4_sock >= 0)
+       if (pthread_create(&cl4th, NULL, udpclientrd, (void *)&client4_sock))
+           debugx(1, DBG_ERR, "pthread_create failed");
+    if (client6_sock >= 0)
+       if (pthread_create(&cl6th, NULL, udpclientrd, (void *)&client6_sock))
+           debugx(1, DBG_ERR, "pthread_create failed");
+
+    if (find_clconf_type(RAD_UDP, NULL)) {
+       server_replyq = newqueue();
+       if (pthread_create(&srvth, NULL, udpserverwr, (void *)server_replyq))
+           debugx(1, DBG_ERR, "pthread_create failed");
+    }
+}
diff --git a/udp.h b/udp.h
index af375d6..e4f1007 100644 (file)
--- a/udp.h
+++ b/udp.h
@@ -9,4 +9,6 @@
 int clientradputudp(struct server *server, unsigned char *rad);
 void *udpclientrd(void *arg);
 void *udpserverrd(void *arg);
-void *udpserverwr(void *arg);
+void addclientudp(struct client *client);
+void addserverextraudp(struct clsrvconf *conf);
+void initextraudp();
diff --git a/util.c b/util.c
index d551cf0..f30f0fb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -98,6 +98,33 @@ char *addr2string(struct sockaddr *addr, socklen_t len) {
     return addr_buf[i];
 }
 
+int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
+    int s, on = 1;
+    struct addrinfo *res;
+
+    for (res = addrinfo; 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);
+       if (s < 0) {
+           debug(DBG_WARN, "bindtoaddr: socket failed");
+           continue;
+       }
+       if (reuse)
+           setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+       #ifdef IPV6_V6ONLY
+       if (v6only)
+           setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+#endif
+
+       if (!bind(s, res->ai_addr, res->ai_addrlen))
+           return s;
+       debug(DBG_WARN, "bindtoaddr: bind failed");
+       close(s);
+    }
+    return -1;
+}
+
 int connectport(int type, char *host, char *port) {
     struct addrinfo hints, *res0, *res;
     int s = -1;
diff --git a/util.h b/util.h
index 7d79856..ca0b425 100644 (file)
--- a/util.h
+++ b/util.h
@@ -1,6 +1,8 @@
 #include <sys/socket.h>
+#include <netdb.h>
 
 char *stringcopy(const char *s, int len);
 char *addr2string(struct sockaddr *addr, socklen_t len);
 void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len);
 int connectport(int type, char *host, char *port);
+int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);