Clean up top dir.
[libradsec.git] / udp.c
diff --git a/udp.c b/udp.c
deleted file mode 100644 (file)
index 4740fd0..0000000
--- a/udp.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2006-2009 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 "list.h"
-#include "hostport.h"
-#include "radsecproxy.h"
-
-#ifdef RADPROT_UDP
-#include "debug.h"
-#include "util.h"
-
-static void setprotoopts(struct commonprotoopts *opts);
-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);
-void udpsetsrcres();
-void initextraudp();
-
-static const struct protodefs protodefs = {
-    "udp",
-    NULL, /* secretdefault */
-    SOCK_DGRAM, /* socktype */
-    "1812", /* portdefault */
-    REQUEST_RETRY_COUNT, /* retrycountdefault */
-    10, /* retrycountmax */
-    REQUEST_RETRY_INTERVAL, /* retryintervaldefault */
-    60, /* retryintervalmax */
-    DUPLICATE_INTERVAL, /* duplicateintervaldefault */
-    setprotoopts, /* setprotoopts */
-    getlistenerargs, /* getlistenerargs */
-    udpserverrd, /* listener */
-    NULL, /* connecter */
-    NULL, /* clientconnreader */
-    clientradputudp, /* clientradput */
-    addclientudp, /* addclient */
-    addserverextraudp, /* addserverextra */
-    udpsetsrcres, /* setsrcres */
-    initextraudp /* initextra */
-};
-
-static int client4_sock = -1;
-static int client6_sock = -1;
-static struct gqueue *server_replyq = NULL;
-
-static struct addrinfo *srcres = NULL;
-static uint8_t handle;
-static struct commonprotoopts *protoopts = NULL;
-
-const struct protodefs *udpinit(uint8_t h) {
-    handle = h;
-    return &protodefs;
-}
-
-static void setprotoopts(struct commonprotoopts *opts) {
-    protoopts = opts;
-}
-
-static char **getlistenerargs() {
-    return protoopts ? protoopts->listenargs : NULL;
-}
-
-void udpsetsrcres() {
-    if (!srcres)
-       srcres = resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, NULL, protodefs.socktype);
-}
-
-void removeudpclientfromreplyq(struct client *c) {
-    struct list_node *n;
-    struct request *r;
-
-    /* lock the common queue and remove replies for this client */
-    pthread_mutex_lock(&c->replyq->mutex);
-    for (n = list_first(c->replyq->entries); n; n = list_next(n)) {
-       r = (struct request *)n->data;
-       if (r->from == c)
-           r->from = NULL;
-    }
-    pthread_mutex_unlock(&c->replyq->mutex);
-}
-
-static int addr_equal(struct sockaddr *a, struct sockaddr *b) {
-    switch (a->sa_family) {
-    case AF_INET:
-       return !memcmp(&((struct sockaddr_in*)a)->sin_addr,
-                      &((struct sockaddr_in*)b)->sin_addr,
-                      sizeof(struct in_addr));
-    case AF_INET6:
-       return IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*)a)->sin6_addr,
-                                 &((struct sockaddr_in6*)b)->sin6_addr);
-    default:
-       /* Must not reach */
-       return 0;
-    }
-}
-
-uint16_t port_get(struct sockaddr *sa) {
-    switch (sa->sa_family) {
-    case AF_INET:
-       return ntohs(((struct sockaddr_in *)sa)->sin_port);
-    case AF_INET6:
-       return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
-    }
-    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, uint16_t *port) {
-    int cnt, len;
-    unsigned char buf[4], *rad = NULL;
-    struct sockaddr_storage from;
-    struct sockaddr *fromcopy;
-    socklen_t fromlen = sizeof(from);
-    struct clsrvconf *p;
-    struct list_node *node;
-    fd_set readfds;
-    struct client *c = NULL;
-    struct timeval now;
-
-    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;
-       }
-
-       p = client
-           ? find_clconf(handle, (struct sockaddr *)&from, NULL)
-           : find_srvconf(handle, (struct sockaddr *)&from, NULL);
-       if (!p) {
-           debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer %s, ignoring", addr2string((struct sockaddr *)&from));
-           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));
-
-       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) {
-           *client = NULL;
-           pthread_mutex_lock(p->lock);
-           for (node = list_first(p->clients); node;) {
-               c = (struct client *)node->data;
-               node = list_next(node);
-               if (s != c->sock)
-                   continue;
-               gettimeofday(&now, NULL);
-               if (!*client && addr_equal((struct sockaddr *)&from, c->addr)) {
-                   c->expiry = now.tv_sec + 60;
-                   *client = c;
-               }
-               if (c->expiry >= now.tv_sec)
-                   continue;
-
-               debug(DBG_DBG, "radudpget: removing expired client (%s)", addr2string(c->addr));
-               removeudpclientfromreplyq(c);
-               c->replyq = NULL; /* stop removeclient() from removing common udp replyq */
-               removelockedclient(c);
-               break;
-           }
-           if (!*client) {
-               fromcopy = addr_copy((struct sockaddr *)&from);
-               if (!fromcopy) {
-                   pthread_mutex_unlock(p->lock);
-                   continue;
-               }
-               c = addclient(p, 0);
-               if (!c) {
-                   free(fromcopy);
-                   pthread_mutex_unlock(p->lock);
-                   continue;
-               }
-               c->sock = s;
-               c->addr = fromcopy;
-               gettimeofday(&now, NULL);
-               c->expiry = now.tv_sec + 60;
-               *client = c;
-           }
-           pthread_mutex_unlock(p->lock);
-       } else if (server)
-           *server = p->servers;
-       break;
-    }
-    if (port)
-       *port = port_get((struct sockaddr *)&from);
-    return rad;
-}
-
-int clientradputudp(struct server *server, unsigned char *rad) {
-    size_t len;
-    struct clsrvconf *conf = server->conf;
-    struct addrinfo *ai;
-
-    len = RADLEN(rad);
-    ai = ((struct hostportres *)list_first(conf->hostports)->data)->addrinfo;
-    if (sendto(server->sock, rad, len, 0, ai->ai_addr, ai->ai_addrlen) >= 0) {
-       debug(DBG_DBG, "clienradputudp: sent UDP of length %d to %s port %d", len, addr2string(ai->ai_addr), port_get(ai->ai_addr));
-       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);
-       replyh(server, buf);
-    }
-}
-
-void *udpserverrd(void *arg) {
-    struct request *rq;
-    int *sp = (int *)arg;
-
-    for (;;) {
-       rq = newrequest();
-       if (!rq) {
-           sleep(5); /* malloc failed */
-           continue;
-       }
-       rq->buf = radudpget(*sp, &rq->from, NULL, &rq->udpport);
-       rq->udpsock = *sp;
-       radsrv(rq);
-    }
-    free(sp);
-    return NULL;
-}
-
-void *udpserverwr(void *arg) {
-    struct gqueue *replyq = (struct gqueue *)arg;
-    struct request *reply;
-    struct sockaddr_storage to;
-
-    for (;;) {
-       pthread_mutex_lock(&replyq->mutex);
-       while (!(reply = (struct request *)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");
-       }
-       /* do this with lock, udpserverrd may set from = NULL if from expires */
-       if (reply->from)
-           memcpy(&to, reply->from->addr, SOCKADDRP_SIZE(reply->from->addr));
-       pthread_mutex_unlock(&replyq->mutex);
-       if (reply->from) {
-           port_set((struct sockaddr *)&to, reply->udpport);
-           if (sendto(reply->udpsock, reply->replybuf, RADLEN(reply->replybuf), 0, (struct sockaddr *)&to, SOCKADDR_SIZE(to)) < 0)
-               debug(DBG_WARN, "udpserverwr: send failed");
-       }
-       debug(DBG_DBG, "udpserverwr: refcount %d", reply->refcount);
-       freerq(reply);
-    }
-}
-
-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");
-    }
-}
-
-void initextraudp() {
-    pthread_t cl4th, cl6th, srvth;
-
-    if (srcres) {
-       freeaddrinfo(srcres);
-       srcres = NULL;
-    }
-
-    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(handle, NULL)) {
-       server_replyq = newqueue();
-       if (pthread_create(&srvth, NULL, udpserverwr, (void *)server_replyq))
-           debugx(1, DBG_ERR, "pthread_create failed");
-    }
-}
-#else
-const struct protodefs *udpinit(uint8_t h) {
-    return NULL;
-}
-#endif
-
-/* Local Variables: */
-/* c-file-style: "stroustrup" */
-/* End: */