summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2008-09-24 08:21:16 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-09-24 08:21:16 +0000
commit8c898f4724bd7ba25725214a60f307c1e0944fa5 (patch)
tree28108408898218b06266924f23f3751a80744a6f
parent0aa4b1fb04dafb9767309afa5d6ad6805391670f (diff)
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
-rw-r--r--dtls.c1
-rw-r--r--radsecproxy.c95
-rw-r--r--radsecproxy.h6
-rw-r--r--tcp.c1
-rw-r--r--tls.c1
-rw-r--r--util.c46
-rw-r--r--util.h2
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);