summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2008-09-14 17:16:03 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-09-14 17:16:03 +0000
commit52570225d77be0f9c751ab30e8ec6f98639be827 (patch)
tree2ca88824d8bb89a05d2a9e546dd292b9017fe6df
parent973eaceb232a0038d97cf21c13c53ae33a5e232b (diff)
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
-rw-r--r--dtls.c1
-rw-r--r--radsecproxy.c1
-rw-r--r--radsecproxy.h2
-rw-r--r--udp.c19
-rw-r--r--util.c37
-rw-r--r--util.h2
6 files changed, 57 insertions, 5 deletions
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);