X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=udp.c;h=efb5f09899a519ac2ee58f09c099b6891ff24873;hb=refs%2Fheads%2FRADSECPROXY-51;hp=2c8ca7fdc2f669dce89dde13b06b0ed8798a4b61;hpb=772a55eacedd6a21e484d372c6436d9ef5138934;p=libradsec.git diff --git a/udp.c b/udp.c index 2c8ca7f..efb5f09 100644 --- a/udp.c +++ b/udp.c @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2006-2008 Stig Venaas - * - * 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. - */ +/* Copyright (c) 2007-2009, UNINETT AS + * Copyright (c) 2012, NORDUnet A/S */ +/* See LICENSE for licensing information. */ #include #include @@ -24,8 +20,9 @@ #include #include #include -#include "list.h" +#include #include "radsecproxy.h" +#include "hostport.h" #ifdef RADPROT_UDP #include "debug.h" @@ -85,13 +82,15 @@ static char **getlistenerargs() { void udpsetsrcres() { if (!srcres) - srcres = resolve_hostport_addrinfo(handle, protoopts ? protoopts->sourcearg : NULL); + srcres = + resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, + AF_UNSPEC, 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)) { @@ -100,7 +99,7 @@ void removeudpclientfromreplyq(struct client *c) { r->from = NULL; } pthread_mutex_unlock(&c->replyq->mutex); -} +} static int addr_equal(struct sockaddr *a, struct sockaddr *b) { switch (a->sa_family) { @@ -141,7 +140,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, fd_set readfds; struct client *c = NULL; struct timeval now; - + for (;;) { if (rad) { free(rad); @@ -156,12 +155,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, 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(handle, (struct sockaddr *)&from, NULL) : find_srvconf(handle, (struct sockaddr *)&from, NULL); @@ -170,21 +164,21 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, 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)); @@ -210,7 +204,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, } 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 */ @@ -248,10 +242,12 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, int clientradputudp(struct server *server, unsigned char *rad) { size_t len; struct clsrvconf *conf = server->conf; - + struct addrinfo *ai; + len = RADLEN(rad); - if (sendto(server->sock, rad, len, 0, conf->addrinfo->ai_addr, conf->addrinfo->ai_addrlen) >= 0) { - debug(DBG_DBG, "clienradputudp: sent UDP of length %d to %s port %d", len, conf->host, port_get(conf->addrinfo->ai_addr)); + 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; } @@ -263,7 +259,7 @@ void *udpclientrd(void *arg) { struct server *server; unsigned char *buf; int *s = (int *)arg; - + for (;;) { server = NULL; buf = radudpget(*s, NULL, &server, NULL); @@ -274,7 +270,7 @@ void *udpclientrd(void *arg) { void *udpserverrd(void *arg) { struct request *rq; int *sp = (int *)arg; - + for (;;) { rq = newrequest(); if (!rq) { @@ -293,7 +289,7 @@ 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))) { @@ -320,12 +316,13 @@ void addclientudp(struct client *client) { } void addserverextraudp(struct clsrvconf *conf) { - switch (conf->addrinfo->ai_family) { + assert(list_first(conf->hostports) != NULL); + 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->host); + debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->name); } conf->servers->sock = client4_sock; break; @@ -333,7 +330,7 @@ void addserverextraudp(struct clsrvconf *conf) { 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->host); + debugx(1, DBG_ERR, "addserver: failed to create client socket for server %s", conf->name); } conf->servers->sock = client6_sock; break; @@ -349,7 +346,7 @@ void initextraudp() { freeaddrinfo(srcres); srcres = NULL; } - + if (client4_sock >= 0) if (pthread_create(&cl4th, NULL, udpclientrd, (void *)&client4_sock)) debugx(1, DBG_ERR, "pthread_create failed"); @@ -368,3 +365,7 @@ const struct protodefs *udpinit(uint8_t h) { return NULL; } #endif + +/* Local Variables: */ +/* c-file-style: "stroustrup" */ +/* End: */