separated udp
authorvenaas <venaas>
Thu, 21 Aug 2008 08:27:09 +0000 (08:27 +0000)
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>
Thu, 21 Aug 2008 08:27:09 +0000 (08:27 +0000)
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@350 e88ac4ed-0b26-0410-9574-a7f39faa03bf

Makefile
Makefile.am
radsecproxy.c
tcp.c
udp.c [new file with mode: 0644]
udp.h [new file with mode: 0644]

index 06a09d4..51d2b95 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 CFLAGS = -g -Wall -pedantic -pthread
 LDFLAGS = -lssl
-OBJ = util.o debug.o list.o gconfig.o tcp.o tls.o dtls.o radsecproxy.o
+OBJ = util.o debug.o list.o gconfig.o udp.o tcp.o tls.o dtls.o radsecproxy.o
 
 all: radsecproxy
 
index 0bf27aa..505791b 100644 (file)
@@ -5,6 +5,7 @@ radsecproxy_SOURCES = radsecproxy.c \
                       util.c \
                       debug.c \
                       list.c \
+                     udp.c \
                      tcp.c \
                      tls.c \
                      dtls.c \
@@ -13,6 +14,7 @@ radsecproxy_SOURCES = radsecproxy.c \
                       debug.h \
                       util.h \
                       list.h \
+                     udp.h \
                      tcp.h \
                      tls.h \
                      dtls.h
index 1a9fc54..63dba64 100644 (file)
@@ -64,6 +64,7 @@
 #include "util.h"
 #include "gconfig.h"
 #include "radsecproxy.h"
+#include "udp.h"
 #include "tcp.h"
 #include "tls.h"
 #include "dtls.h"
@@ -92,11 +93,6 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
 void freerealm(struct realm *realm);
 void freeclsrvconf(struct clsrvconf *conf);
 void freerqdata(struct request *rq);
-void *udpserverrd(void *arg);
-void *udpclientrd(void *arg);
-int clientradputudp(struct server *server, unsigned char *rad);
-X509 *verifytlscert(SSL *ssl);
-int radsrv(struct request *rq);
 
 static const struct protodefs protodefs[] = {
     {   "udp", /* UDP, assuming RAD_UDP defined as 0 */
@@ -728,83 +724,6 @@ int addserver(struct clsrvconf *conf) {
     return 0;
 }
 
-/* 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 */
-unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
-    int cnt, len;
-    unsigned char buf[4], *rad = NULL;
-    struct sockaddr_storage from;
-    socklen_t fromlen = sizeof(from);
-    struct clsrvconf *p;
-    struct list_node *node;
-    fd_set readfds;
-    
-    for (;;) {
-       if (rad) {
-           free(rad);
-           rad = NULL;
-       }
-       FD_ZERO(&readfds);
-        FD_SET(s, &readfds);
-       if (select(s + 1, &readfds, NULL, NULL, NULL) < 1)
-           continue;
-       cnt = recvfrom(s, buf, 4, MSG_PEEK | MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
-       if (cnt == -1) {
-           debug(DBG_WARN, "radudpget: recv failed");
-           continue;
-       }
-       if (cnt < 20) {
-           debug(DBG_WARN, "radudpget: length too small");
-           recv(s, buf, 4, 0);
-           continue;
-       }
-       
-       p = find_conf(RAD_UDP, (struct sockaddr *)&from, client ? clconfs : srvconfs, NULL);
-       if (!p) {
-           debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from, fromlen));
-           recv(s, buf, 4, 0);
-           continue;
-       }
-       
-       len = RADLEN(buf);
-       if (len < 20) {
-           debug(DBG_WARN, "radudpget: length too small");
-           recv(s, buf, 4, 0);
-           continue;
-       }
-           
-       rad = malloc(len);
-       if (!rad) {
-           debug(DBG_ERR, "radudpget: malloc failed");
-           recv(s, buf, 4, 0);
-           continue;
-       }
-       
-       cnt = recv(s, rad, len, MSG_TRUNC);
-       debug(DBG_DBG, "radudpget: got %d bytes from %s", cnt, addr2string((struct sockaddr *)&from, fromlen));
-
-       if (cnt < len) {
-           debug(DBG_WARN, "radudpget: packet smaller than length field in radius header");
-           continue;
-       }
-       if (cnt > len)
-           debug(DBG_DBG, "radudpget: packet was padded with %d bytes", cnt - len);
-
-       if (client) {
-           node = list_first(p->clients);
-           *client = node ? (struct client *)node->data : addclient(p);
-           if (!*client)
-               continue;
-       } else if (server)
-           *server = p->servers;
-       break;
-    }
-    if (sa)
-       *sa = from;
-    return rad;
-}
-
 int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) {
     int loc, i, l, n, r = 0;
     char *v;
@@ -993,44 +912,6 @@ int verifyconfcert(X509 *cert, struct clsrvconf *conf) {
     return 1;
 }
 
-int clientradputudp(struct server *server, unsigned char *rad) {
-    size_t len;
-    struct sockaddr_storage sa;
-    struct sockaddr *sap;
-    struct clsrvconf *conf = server->conf;
-    in_port_t *port = NULL;
-    
-    len = RADLEN(rad);
-    
-    if (*rad == RAD_Accounting_Request) {
-       sap = (struct sockaddr *)&sa;
-       memcpy(sap, conf->addrinfo->ai_addr, conf->addrinfo->ai_addrlen);
-    } else
-       sap = conf->addrinfo->ai_addr;
-    
-    switch (sap->sa_family) {
-    case AF_INET:
-       port = &((struct sockaddr_in *)sap)->sin_port;
-       break;
-    case AF_INET6:
-       port = &((struct sockaddr_in6 *)sap)->sin6_port;
-       break;
-    default:
-       return 0;
-    }
-
-    if (*rad == RAD_Accounting_Request)
-       *port = htons(ntohs(*port) + 1);
-    
-    if (sendto(server->sock, rad, len, 0, sap, conf->addrinfo->ai_addrlen) >= 0) {
-       debug(DBG_DBG, "clienradputudp: sent UDP of length %d to %s port %d", len, conf->host, ntohs(*port));
-       return 1;
-    }
-
-    debug(DBG_WARN, "clientradputudp: send failed");
-    return 0;
-}
-
 int radsign(unsigned char *rad, unsigned char *sec) {
     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
     static unsigned char first = 1;
@@ -2244,19 +2125,6 @@ int replyh(struct server *server, unsigned char *buf) {
     return 1;
 }
 
-void *udpclientrd(void *arg) {
-    struct server *server;
-    unsigned char *buf;
-    int *s = (int *)arg;
-    
-    for (;;) {
-       server = NULL;
-       buf = radudpget(*s, NULL, &server, NULL);
-       if (!replyh(server, buf))
-           free(buf);
-    }
-}
-
 /* code for removing state not finished */
 void *clientwr(void *arg) {
     struct server *server = (struct server *)arg;
@@ -2429,40 +2297,6 @@ void *clientwr(void *arg) {
     return NULL;
 }
 
-void *udpserverwr(void *arg) {
-    struct queue *replyq = udp_server_replyq;
-    struct reply *reply;
-    
-    for (;;) {
-       pthread_mutex_lock(&replyq->mutex);
-       while (!(reply = (struct reply *)list_shift(replyq->entries))) {
-           debug(DBG_DBG, "udp server writer, waiting for signal");
-           pthread_cond_wait(&replyq->cond, &replyq->mutex);
-           debug(DBG_DBG, "udp server writer, got signal");
-       }
-       pthread_mutex_unlock(&replyq->mutex);
-
-       if (sendto(reply->toudpsock, reply->buf, RADLEN(reply->buf), 0,
-                  (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
-           debug(DBG_WARN, "sendudp: send failed");
-       free(reply->buf);
-       free(reply);
-    }
-}
-
-void *udpserverrd(void *arg) {
-    struct request rq;
-    int *sp = (int *)arg;
-    
-    for (;;) {
-       memset(&rq, 0, sizeof(struct request));
-       rq.buf = radudpget(*sp, &rq.from, NULL, &rq.fromsa);
-       rq.fromudpsock = *sp;
-       radsrv(&rq);
-    }
-    free(sp);
-}
-
 void createlistener(uint8_t type, char *arg) {
     pthread_t th;
     struct clsrvconf *listenres;
@@ -3755,7 +3589,7 @@ int main(int argc, char **argv) {
     
     if (find_conf_type(RAD_UDP, clconfs, NULL)) {
        udp_server_replyq = newqueue();
-       if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
+       if (pthread_create(&udpserverwrth, NULL, udpserverwr, (void *)udp_server_replyq))
            debugx(1, DBG_ERR, "pthread_create failed");
        createlisteners(RAD_UDP, options.listenudp);
        if (options.listenaccudp)
diff --git a/tcp.c b/tcp.c
index e33e4c7..6f6fec8 100644 (file)
--- a/tcp.c
+++ b/tcp.c
@@ -25,7 +25,6 @@
 #include <regex.h>
 #include <pthread.h>
 #include <openssl/ssl.h>
-#include <openssl/err.h>
 #include "debug.h"
 #include "list.h"
 #include "util.h"
diff --git a/udp.c b/udp.c
new file mode 100644 (file)
index 0000000..470e6d8
--- /dev/null
+++ b/udp.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2006-2008 Stig Venaas <venaas@uninett.no>
+ *
+ * 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 <signal.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#ifdef SYS_SOLARIS9
+#include <fcntl.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <regex.h>
+#include <pthread.h>
+#include <openssl/ssl.h>
+#include "debug.h"
+#include "list.h"
+#include "util.h"
+#include "radsecproxy.h"
+#include "tls.h"
+
+/* 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 */
+unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
+    int cnt, len;
+    unsigned char buf[4], *rad = NULL;
+    struct sockaddr_storage from;
+    socklen_t fromlen = sizeof(from);
+    struct clsrvconf *p;
+    struct list_node *node;
+    fd_set readfds;
+    
+    for (;;) {
+       if (rad) {
+           free(rad);
+           rad = NULL;
+       }
+       FD_ZERO(&readfds);
+        FD_SET(s, &readfds);
+       if (select(s + 1, &readfds, NULL, NULL, NULL) < 1)
+           continue;
+       cnt = recvfrom(s, buf, 4, MSG_PEEK | MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
+       if (cnt == -1) {
+           debug(DBG_WARN, "radudpget: recv failed");
+           continue;
+       }
+       if (cnt < 20) {
+           debug(DBG_WARN, "radudpget: length too small");
+           recv(s, buf, 4, 0);
+           continue;
+       }
+       
+       p = client
+           ? find_clconf(RAD_UDP, (struct sockaddr *)&from, NULL)
+           : find_srvconf(RAD_UDP, (struct sockaddr *)&from, NULL);
+       if (!p) {
+           debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from, fromlen));
+           recv(s, buf, 4, 0);
+           continue;
+       }
+       
+       len = RADLEN(buf);
+       if (len < 20) {
+           debug(DBG_WARN, "radudpget: length too small");
+           recv(s, buf, 4, 0);
+           continue;
+       }
+           
+       rad = malloc(len);
+       if (!rad) {
+           debug(DBG_ERR, "radudpget: malloc failed");
+           recv(s, buf, 4, 0);
+           continue;
+       }
+       
+       cnt = recv(s, rad, len, MSG_TRUNC);
+       debug(DBG_DBG, "radudpget: got %d bytes from %s", cnt, addr2string((struct sockaddr *)&from, fromlen));
+
+       if (cnt < len) {
+           debug(DBG_WARN, "radudpget: packet smaller than length field in radius header");
+           continue;
+       }
+       if (cnt > len)
+           debug(DBG_DBG, "radudpget: packet was padded with %d bytes", cnt - len);
+
+       if (client) {
+           node = list_first(p->clients);
+           *client = node ? (struct client *)node->data : addclient(p);
+           if (!*client)
+               continue;
+       } else if (server)
+           *server = p->servers;
+       break;
+    }
+    if (sa)
+       *sa = from;
+    return rad;
+}
+
+int clientradputudp(struct server *server, unsigned char *rad) {
+    size_t len;
+    struct sockaddr_storage sa;
+    struct sockaddr *sap;
+    struct clsrvconf *conf = server->conf;
+    in_port_t *port = NULL;
+    
+    len = RADLEN(rad);
+    
+    if (*rad == RAD_Accounting_Request) {
+       sap = (struct sockaddr *)&sa;
+       memcpy(sap, conf->addrinfo->ai_addr, conf->addrinfo->ai_addrlen);
+    } else
+       sap = conf->addrinfo->ai_addr;
+    
+    switch (sap->sa_family) {
+    case AF_INET:
+       port = &((struct sockaddr_in *)sap)->sin_port;
+       break;
+    case AF_INET6:
+       port = &((struct sockaddr_in6 *)sap)->sin6_port;
+       break;
+    default:
+       return 0;
+    }
+
+    if (*rad == RAD_Accounting_Request)
+       *port = htons(ntohs(*port) + 1);
+    
+    if (sendto(server->sock, rad, len, 0, sap, conf->addrinfo->ai_addrlen) >= 0) {
+       debug(DBG_DBG, "clienradputudp: sent UDP of length %d to %s port %d", len, conf->host, ntohs(*port));
+       return 1;
+    }
+
+    debug(DBG_WARN, "clientradputudp: send failed");
+    return 0;
+}
+
+void *udpclientrd(void *arg) {
+    struct server *server;
+    unsigned char *buf;
+    int *s = (int *)arg;
+    
+    for (;;) {
+       server = NULL;
+       buf = radudpget(*s, NULL, &server, NULL);
+       if (!replyh(server, buf))
+           free(buf);
+    }
+}
+
+void *udpserverrd(void *arg) {
+    struct request rq;
+    int *sp = (int *)arg;
+    
+    for (;;) {
+       memset(&rq, 0, sizeof(struct request));
+       rq.buf = radudpget(*sp, &rq.from, NULL, &rq.fromsa);
+       rq.fromudpsock = *sp;
+       radsrv(&rq);
+    }
+    free(sp);
+}
+
+void *udpserverwr(void *arg) {
+    struct queue *replyq = (struct queue *)arg;
+    struct reply *reply;
+    
+    for (;;) {
+       pthread_mutex_lock(&replyq->mutex);
+       while (!(reply = (struct reply *)list_shift(replyq->entries))) {
+           debug(DBG_DBG, "udp server writer, waiting for signal");
+           pthread_cond_wait(&replyq->cond, &replyq->mutex);
+           debug(DBG_DBG, "udp server writer, got signal");
+       }
+       pthread_mutex_unlock(&replyq->mutex);
+
+       if (sendto(reply->toudpsock, reply->buf, RADLEN(reply->buf), 0,
+                  (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
+           debug(DBG_WARN, "sendudp: send failed");
+       free(reply->buf);
+       free(reply);
+    }
+}
diff --git a/udp.h b/udp.h
new file mode 100644 (file)
index 0000000..af375d6
--- /dev/null
+++ b/udp.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2006-2008 Stig Venaas <venaas@uninett.no>
+ *
+ * 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 clientradputudp(struct server *server, unsigned char *rad);
+void *udpclientrd(void *arg);
+void *udpserverrd(void *arg);
+void *udpserverwr(void *arg);