diff options
| author | venaas <venaas> | 2008-09-14 17:16:03 +0000 | 
|---|---|---|
| committer | venaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf> | 2008-09-14 17:16:03 +0000 | 
| commit | 52570225d77be0f9c751ab30e8ec6f98639be827 (patch) | |
| tree | 2ca88824d8bb89a05d2a9e546dd292b9017fe6df | |
| parent | 973eaceb232a0038d97cf21c13c53ae33a5e232b (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.c | 1 | ||||
| -rw-r--r-- | radsecproxy.c | 1 | ||||
| -rw-r--r-- | radsecproxy.h | 2 | ||||
| -rw-r--r-- | udp.c | 19 | ||||
| -rw-r--r-- | util.c | 37 | ||||
| -rw-r--r-- | util.h | 2 | 
6 files changed, 57 insertions, 5 deletions
| @@ -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 { @@ -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; @@ -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; @@ -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); | 
