From 8c898f4724bd7ba25725214a60f307c1e0944fa5 Mon Sep 17 00:00:00 2001 From: venaas Date: Wed, 24 Sep 2008 08:21:16 +0000 Subject: some code improvemetns, more efficiently removing outstanding requests when removing client, also taking care of dynamic servers, need to look into server removal git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@399 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- dtls.c | 1 - radsecproxy.c | 95 ++++++++++++++++------------------------------------------- radsecproxy.h | 6 ++-- tcp.c | 1 - tls.c | 1 - util.c | 46 +++++++++++++++++++++++++++++ util.h | 2 ++ 7 files changed, 76 insertions(+), 76 deletions(-) diff --git a/dtls.c b/dtls.c index ed5e44e..51ec0cb 100644 --- a/dtls.c +++ b/dtls.c @@ -286,7 +286,6 @@ void dtlsserverrd(struct client *client) { pthread_mutex_unlock(&client->replyq->mutex); debug(DBG_DBG, "dtlsserverrd: waiting for writer to end"); pthread_join(dtlsserverwrth, NULL); - removeclientrqs(client); debug(DBG_DBG, "dtlsserverrd: reader for %s exiting", addr2string(client->addr)); } diff --git a/radsecproxy.c b/radsecproxy.c index 9c44328..280cb41 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -390,52 +390,6 @@ void freeclsrvres(struct clsrvconf *res) { free(res); } -int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) { - int s, on = 1; - struct addrinfo *res; - - for (res = addrinfo; res; res = res->ai_next) { - if (family != AF_UNSPEC && family != res->ai_family) - continue; - s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (s < 0) { - debug(DBG_WARN, "bindtoaddr: socket failed"); - continue; - } - if (reuse) - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); -#ifdef IPV6_V6ONLY - if (v6only) - setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); -#endif - if (!bind(s, res->ai_addr, res->ai_addrlen)) - return s; - debug(DBG_WARN, "bindtoaddr: bind failed"); - close(s); - } - return -1; -} - -int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src) { - int s; - struct addrinfo *res; - - s = -1; - for (res = addrinfo; res; res = res->ai_next) { - s = bindtoaddr(src, res->ai_family, 1, 1); - if (s < 0) { - debug(DBG_WARN, "connecttoserver: socket failed"); - continue; - } - if (connect(s, res->ai_addr, res->ai_addrlen) == 0) - break; - debug(DBG_WARN, "connecttoserver: connect failed"); - close(s); - s = -1; - } - return s; -} - /* returns 1 if the len first bits are equal, else 0 */ int prefixmatch(void *a1, void *a2, uint8_t len) { static uint8_t mask[] = { 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe }; @@ -590,6 +544,24 @@ struct client *addclient(struct clsrvconf *conf, uint8_t lock) { return new; } +void removeclientrqs(struct client *client) { + struct request *rq; + struct rqout *rqout; + int i; + + for (i = 0; i < MAX_REQUESTS; i++) { + rq = client->rqs[i]; + if (!rq) + continue; + rqout = rq->to->requests + rq->newid; + pthread_mutex_lock(rqout->lock); + if (rqout->rq == rq) /* still pointing to our request */ + freerqoutdata(rqout); + pthread_mutex_unlock(rqout->lock); + freerq(rq); + } +} + void removeclient(struct client *client) { struct clsrvconf *conf; @@ -598,6 +570,7 @@ void removeclient(struct client *client) { conf = client->conf; pthread_mutex_lock(conf->lock); if (conf->clients) { + removeclientrqs(client); removequeue(client->replyq); list_removedata(conf->clients, client); free(client->addr); @@ -606,26 +579,6 @@ void removeclient(struct client *client) { pthread_mutex_unlock(conf->lock); } -void removeclientrqs(struct client *client) { - struct list_node *entry; - struct server *server; - struct rqout *rqout; - int i; - - for (entry = list_first(srvconfs); entry; entry = list_next(entry)) { - server = ((struct clsrvconf *)entry->data)->servers; - if (!server) - continue; - for (i = 0; i < MAX_REQUESTS; i++) { - rqout = server->requests + i; - pthread_mutex_lock(rqout->lock); - if (rqout->rq && rqout->rq->from == client) - freerqoutdata(rqout); - pthread_mutex_unlock(rqout->lock); - } - } -} - void freeserver(struct server *server, uint8_t destroymutex) { struct rqout *rqout, *end; @@ -955,8 +908,9 @@ void freerqoutdata(struct rqout *rqout) { memset(&rqout->expiry, 0, sizeof(struct timeval)); } -void sendrq(struct server *to, struct request *rq) { +void sendrq(struct request *rq) { int i, start; + struct server *to = rq->to; start = to->conf->statusserver ? 1 : 0; pthread_mutex_lock(&to->newrq_mutex); @@ -995,6 +949,7 @@ void sendrq(struct server *to, struct request *rq) { } } } + rq->newid = (uint8_t)i; rq->msg->id = (uint8_t)i; rq->buf = radmsg2buf(rq->msg, (uint8_t *)to->conf->secret); if (!rq->buf) { @@ -1884,7 +1839,8 @@ int radsrv(struct request *rq) { goto rmclrqexit; free(userascii); - sendrq(to, rq); + rq->to = to; + sendrq(rq); return 1; rmclrqexit: @@ -2193,8 +2149,9 @@ void *clientwr(void *arg) { laststatsrv = now; statsrvrq = createstatsrvrq(); if (statsrvrq) { + statsrvrq->to = server; debug(DBG_DBG, "clientwr: sending status server to %s", conf->host); - sendrq(server, statsrvrq); + sendrq(statsrvrq); } } } diff --git a/radsecproxy.h b/radsecproxy.h index 4cb102b..21c02ec 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -48,9 +48,11 @@ struct request { uint8_t *buf, *replybuf; struct radmsg *msg; struct client *from; + struct server *to; char *origusername; uint8_t rqid; uint8_t rqauth[16]; + uint8_t newid; int udpsock; /* only for UDP */ uint16_t udpport; /* only for UDP */ }; @@ -203,9 +205,7 @@ struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_ struct clsrvconf *find_clconf_type(uint8_t type, struct list_node **cur); struct client *addclient(struct clsrvconf *conf, uint8_t lock); void removeclient(struct client *client); -void removeclientrqs(struct client *client); struct queue *newqueue(); -void removequeue(struct queue *q); void freebios(struct queue *q); struct request *newrequest(); void freerq(struct request *rq); @@ -213,6 +213,4 @@ int radsrv(struct request *rq); X509 *verifytlscert(SSL *ssl); int verifyconfcert(X509 *cert, struct clsrvconf *conf); void replyh(struct server *server, unsigned char *buf); -int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src); -int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only); SSL_CTX *tlsgetctx(uint8_t type, struct tls *t); diff --git a/tcp.c b/tcp.c index 2a4a799..62c335e 100644 --- a/tcp.c +++ b/tcp.c @@ -258,7 +258,6 @@ void tcpserverrd(struct client *client) { pthread_mutex_unlock(&client->replyq->mutex); debug(DBG_DBG, "tcpserverrd: waiting for writer to end"); pthread_join(tcpserverwrth, NULL); - removeclientrqs(client); debug(DBG_DBG, "tcpserverrd: reader for %s exiting", addr2string(client->addr)); } void *tcpservernew(void *arg) { diff --git a/tls.c b/tls.c index 836f3aa..5014b46 100644 --- a/tls.c +++ b/tls.c @@ -318,7 +318,6 @@ void tlsserverrd(struct client *client) { pthread_mutex_unlock(&client->replyq->mutex); debug(DBG_DBG, "tlsserverrd: waiting for writer to end"); pthread_join(tlsserverwrth, NULL); - removeclientrqs(client); debug(DBG_DBG, "tlsserverrd: reader for %s exiting", addr2string(client->addr)); } diff --git a/util.c b/util.c index 3ba212c..d9e2709 100644 --- a/util.c +++ b/util.c @@ -150,3 +150,49 @@ int connectport(int type, char *host, char *port) { freeaddrinfo(res0); return s; } + +int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) { + int s, on = 1; + struct addrinfo *res; + + for (res = addrinfo; res; res = res->ai_next) { + if (family != AF_UNSPEC && family != res->ai_family) + continue; + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s < 0) { + debug(DBG_WARN, "bindtoaddr: socket failed"); + continue; + } + if (reuse) + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + #ifdef IPV6_V6ONLY + if (v6only) + setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); + #endif + if (!bind(s, res->ai_addr, res->ai_addrlen)) + return s; + debug(DBG_WARN, "bindtoaddr: bind failed"); + close(s); + } + return -1; +} + +int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src) { + int s; + struct addrinfo *res; + + s = -1; + for (res = addrinfo; res; res = res->ai_next) { + s = bindtoaddr(src, res->ai_family, 1, 1); + if (s < 0) { + debug(DBG_WARN, "connecttoserver: socket failed"); + continue; + } + if (connect(s, res->ai_addr, res->ai_addrlen) == 0) + break; + debug(DBG_WARN, "connecttoserver: connect failed"); + close(s); + s = -1; + } + return s; +} diff --git a/util.h b/util.h index 3280379..9565584 100644 --- a/util.h +++ b/util.h @@ -18,3 +18,5 @@ void port_set(struct sockaddr *sa, uint16_t port); void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len); int connectport(int type, char *host, char *port); +int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only); +int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src); -- cgit v1.1