From: venaas Date: Sun, 14 Sep 2008 17:16:03 +0000 (+0000) Subject: changing to use a separate client structure for each udp client X-Git-Tag: radsecproxy-1.4-beta1~162 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=radsecproxy.git;a=commitdiff_plain;h=52570225d77be0f9c751ab30e8ec6f98639be827 changing to use a separate client structure for each udp client git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@378 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- diff --git a/dtls.c b/dtls.c index 6d605cb..a80c8fd 100644 --- a/dtls.c +++ b/dtls.c @@ -312,7 +312,6 @@ void *dtlsservernew(void *arg) { if (client) { client->sock = params->sock; client->rbios = params->sesscache->rbios; - client->addr = params->addr; client->ssl = ssl; dtlsserverrd(client); removeclient(client); diff --git a/radsecproxy.c b/radsecproxy.c index 2ffae31..cdf9fbb 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -581,6 +581,7 @@ void removeclient(struct client *client) { return; removequeue(client->replyq); list_removedata(client->conf->clients, client); + free(client->addr); free(client); } diff --git a/radsecproxy.h b/radsecproxy.h index eeefaed..d37967f 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -104,7 +104,7 @@ struct client { SSL *ssl; struct queue *replyq; struct queue *rbios; /* for dtls */ - struct sockaddr_storage addr; /* for dtls */ + struct sockaddr *addr; /* for udp */ }; struct server { diff --git a/udp.c b/udp.c index c2302d4..4d27425 100644 --- a/udp.c +++ b/udp.c @@ -42,6 +42,7 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, 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; @@ -101,10 +102,22 @@ unsigned char *radudpget(int s, struct client **client, struct server **server, 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) + for (node = list_first(p->clients); node; node = list_next(node)) + if (addr_equal((struct sockaddr *)&from, ((struct client *)node->data)->addr)) + break; + if (node) { + *client = (struct client *)node->data; + break; + } + fromcopy = addr_copy((struct sockaddr *)&from); + if (!fromcopy) continue; + *client = addclient(p); + if (!*client) { + free(fromcopy); + continue; + } + (*client)->addr = fromcopy; } else if (server) *server = p->servers; break; diff --git a/util.c b/util.c index d551cf0..5dc5f34 100644 --- a/util.c +++ b/util.c @@ -72,6 +72,43 @@ void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int printf("\n"); } +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; + } +} + +struct sockaddr *addr_copy(struct sockaddr *in) { + struct sockaddr *out = NULL; + + switch (in->sa_family) { + case AF_INET: + out = malloc(sizeof(struct sockaddr_in)); + if (out) { + memset(out, 0, sizeof(struct sockaddr_in)); + ((struct sockaddr_in *)out)->sin_addr = ((struct sockaddr_in *)in)->sin_addr; + } + break; + case AF_INET6: + out = malloc(sizeof(struct sockaddr_in6)); + if (out) { + memset(out, 0, sizeof(struct sockaddr_in6)); + ((struct sockaddr_in6 *)out)->sin6_addr = ((struct sockaddr_in6 *)in)->sin6_addr; + } + break; + } + return out; +} + char *addr2string(struct sockaddr *addr, socklen_t len) { struct sockaddr_in6 *sa6; struct sockaddr_in sa4; diff --git a/util.h b/util.h index c151b90..7bb8202 100644 --- a/util.h +++ b/util.h @@ -3,5 +3,7 @@ char *stringcopy(const char *s, int len); char *addr2string(struct sockaddr *addr, socklen_t len); +int addr_equal(struct sockaddr *a, struct sockaddr *b); +struct sockaddr *addr_copy(struct sockaddr *in); void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len); int connectport(int type, char *host, char *port);