some code improvemetns, more efficiently removing outstanding requests when removing...
authorvenaas <venaas>
Wed, 24 Sep 2008 08:21:16 +0000 (08:21 +0000)
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>
Wed, 24 Sep 2008 08:21:16 +0000 (08:21 +0000)
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@399 e88ac4ed-0b26-0410-9574-a7f39faa03bf

dtls.c
radsecproxy.c
radsecproxy.h
tcp.c
tls.c
util.c
util.h

diff --git a/dtls.c b/dtls.c
index ed5e44e..51ec0cb 100644 (file)
--- 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));
 }
 
index 9c44328..280cb41 100644 (file)
@@ -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);
                }
            }
        }
index 4cb102b..21c02ec 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- 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);