Commit 8c898f47 authored by venaas's avatar venaas Committed by venaas

some code improvemetns, more efficiently removing outstanding requests when...

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
parent 0aa4b1fb
......@@ -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));
}
......
......@@ -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);
}
}
}
......
......@@ -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);
......@@ -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) {
......
......@@ -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));
}
......
......@@ -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;
}
......@@ -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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment