cleaning up code
authorvenaas <venaas>
Wed, 17 Sep 2008 08:14:21 +0000 (08:14 +0000)
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>
Wed, 17 Sep 2008 08:14:21 +0000 (08:14 +0000)
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@383 e88ac4ed-0b26-0410-9574-a7f39faa03bf

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

diff --git a/dtls.c b/dtls.c
index 01725e4..38edcb3 100644 (file)
--- a/dtls.c
+++ b/dtls.c
@@ -213,7 +213,7 @@ void *dtlsserverwr(void *arg) {
     unsigned long error;
     struct client *client = (struct client *)arg;
     struct queue *replyq;
-    struct reply *reply;
+    struct request *reply;
     
     debug(DBG_DBG, "dtlsserverwr: starting for %s", client->conf->host);
     replyq = client->replyq;
@@ -233,17 +233,16 @@ void *dtlsserverwr(void *arg) {
                pthread_exit(NULL);
            }
        }
-       reply = (struct reply *)list_shift(replyq->entries);
+       reply = (struct request *)list_shift(replyq->entries);
        pthread_mutex_unlock(&replyq->mutex);
-       cnt = SSL_write(client->ssl, reply->buf, RADLEN(reply->buf));
+       cnt = SSL_write(client->ssl, reply->replybuf, RADLEN(reply->replybuf));
        if (cnt > 0)
            debug(DBG_DBG, "dtlsserverwr: sent %d bytes, Radius packet of length %d",
-                 cnt, RADLEN(reply->buf));
+                 cnt, RADLEN(reply->replybuf));
        else
            while ((error = ERR_get_error()))
                debug(DBG_ERR, "dtlsserverwr: SSL: %s", ERR_error_string(error, NULL));
-       free(reply->buf);
-       free(reply);
+       freerq(reply);
     }
 }
 
index 9e3cbe4..6e0c2c6 100644 (file)
@@ -279,16 +279,8 @@ int resolvepeer(struct clsrvconf *conf, int ai_flags) {
            debug(DBG_WARN, "resolvepeer: can't resolve (null) port (null)");
            return 0;
        }
-       for (res = addrinfo; res; res = res->ai_next) {
-           switch (res->ai_family) {
-           case AF_INET:
-               ((struct sockaddr_in *)res->ai_addr)->sin_port = 0;
-               break;
-           case AF_INET6:
-               ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = 0;
-               break;
-           }
-       }
+       for (res = addrinfo; res; res = res->ai_next)
+           port_set(res->ai_addr, 0);
     } else {
        if (slash)
            hints.ai_flags |= AI_NUMERICHOST;
@@ -541,7 +533,7 @@ void removequeue(struct queue *q) {
        return;
     pthread_mutex_lock(&q->mutex);
     for (entry = list_first(q->entries); entry; entry = list_next(entry))
-       free(((struct reply *)entry)->buf);
+       freerq((struct request *)entry);
     list_destroy(q->entries);
     pthread_cond_destroy(&q->cond);
     pthread_mutex_unlock(&q->mutex);
@@ -940,10 +932,10 @@ void freerq(struct request *rq) {
        free(rq->origusername);
     if (rq->buf)
        free(rq->buf);
-    if (rq->msg) {
+    if (rq->replybuf)
+       free(rq->replybuf);
+    if (rq->msg)
        radmsg_free(rq->msg);
-       rq->msg = NULL;
-    }
     free(rq);
 }
 
@@ -1013,38 +1005,26 @@ void sendrq(struct server *to, struct request *rq) {
     pthread_mutex_unlock(&to->newrq_mutex);
 }
 
-void sendreply(struct client *to, struct radmsg *msg, struct sockaddr_storage *tosa, int toudpsock) {
-    uint8_t *buf;
-    struct reply *reply;
+void sendreply(struct request *rq) {
     uint8_t first;
-
-    buf = radmsg2buf(msg, (uint8_t *)to->conf->secret);
-    radmsg_free(msg);
-    if (!buf) {
+    struct client *to = rq->from;
+    
+    if (!rq->replybuf)
+       rq->replybuf = radmsg2buf(rq->msg, (uint8_t *)to->conf->secret);
+    radmsg_free(rq->msg);
+    rq->msg = NULL;
+    if (!rq->replybuf) {
+       freerq(rq);
        debug(DBG_ERR, "sendreply: radmsg2buf failed");
        return;
     }
 
-    reply = malloc(sizeof(struct reply));
-    if (!reply) {
-       free(buf);
-       debug(DBG_ERR, "sendreply: malloc failed");
-       return;
-    }
-    memset(reply, 0, sizeof(struct reply));
-    reply->buf = buf;
-    if (tosa)
-       reply->tosa = *tosa;
-    reply->toudpsock = toudpsock;
-    
     pthread_mutex_lock(&to->replyq->mutex);
-
     first = list_first(to->replyq->entries) == NULL;
     
-    if (!list_push(to->replyq->entries, reply)) {
+    if (!list_push(to->replyq->entries, rq)) {
        pthread_mutex_unlock(&to->replyq->mutex);
-       free(reply);
-       free(buf);
+       freerq(rq);
        debug(DBG_ERR, "sendreply: malloc failed");
        return;
     }
@@ -1652,8 +1632,10 @@ void respondaccounting(struct request *rq) {
 
     msg = radmsg_init(RAD_Accounting_Response, rq->msg->id, rq->msg->auth);
     if (msg) {
+       radmsg_free(rq->msg);
+       rq->msg = msg;
        debug(DBG_DBG, "respondaccounting: responding to %s", rq->from->conf->host);
-       sendreply(rq->from, msg, &rq->fromsa, rq->fromudpsock);
+       sendreply(rq);
     } else     
        debug(DBG_ERR, "respondaccounting: malloc failed");
 }
@@ -1663,8 +1645,10 @@ void respondstatusserver(struct request *rq) {
 
     msg = radmsg_init(RAD_Access_Accept, rq->msg->id, rq->msg->auth);
     if (msg) {
+       radmsg_free(rq->msg);
+       rq->msg = msg;
        debug(DBG_DBG, "respondstatusserver: responding to %s", rq->from->conf->host);
-       sendreply(rq->from, msg, &rq->fromsa, rq->fromudpsock);
+       sendreply(rq);
     } else
        debug(DBG_ERR, "respondstatusserver: malloc failed");
 }
@@ -1688,8 +1672,10 @@ void respondreject(struct request *rq, char *message) {
        }
     }
 
+    radmsg_free(rq->msg);
+    rq->msg = msg;
     debug(DBG_DBG, "respondreject: responding to %s", rq->from->conf->host);
-    sendreply(rq->from, msg, &rq->fromsa, rq->fromudpsock);
+    sendreply(rq);
 }
 
 struct clsrvconf *choosesrvconf(struct list *srvconfs) {
@@ -1763,6 +1749,15 @@ int addclientrq(struct request *rq, uint8_t id) {
     r = rq->from->rqs[id];
     if (r) {
        if (now.tv_sec - r->created.tv_sec < r->from->conf->dupinterval) {
+#if 0
+           later           
+           if (r->replybuf) {
+               debug(DBG_INFO, "radsrv: already sent reply to request with id %d from %s, resending", id, r->from->conf->host);
+               r->refcount++;
+               sendreply(r);
+           } else
+#endif         
+               debug(DBG_INFO, "radsrv: already got request with id %d from %s, ignoring", id, r->from->conf->host);           
            pthread_mutex_unlock(&rq->from->lock);
            return 0;
        }
@@ -1813,10 +1808,8 @@ int radsrv(struct request *rq) {
        goto exit;
     }
     
-    if (!addclientrq(rq, msg->id)) {
-       debug(DBG_INFO, "radsrv: already got request with id %d from %s, ignoring", msg->id, from->conf->host);
+    if (!addclientrq(rq, msg->id))
        goto exit;
-    }
 
     if (msg->code == RAD_Status_Server) {
        respondstatusserver(rq);
@@ -2026,7 +2019,10 @@ void replyh(struct server *server, unsigned char *buf) {
     }
 
     debug(DBG_INFO, "replyh: passing reply to client %s", from->conf->name);
-    sendreply(from, msg, &rqout->rq->fromsa, rqout->rq->fromudpsock);
+    radmsg_free(rqout->rq->msg);
+    rqout->rq->msg = msg;
+    rqout->rq->refcount++;
+    sendreply(rqout->rq);
     freerqoutdata(rqout);
     pthread_mutex_unlock(rqout->lock);
     return;
index 5efe80b..a421c5e 100644 (file)
@@ -45,14 +45,14 @@ struct options {
 struct request {
     struct timeval created;
     uint8_t refcount;
-    uint8_t *buf;
+    uint8_t *buf, *replybuf;
     struct radmsg *msg;
     struct client *from;
-    struct sockaddr_storage fromsa; /* used by udpservwr */
-    int fromudpsock; /* used by udpservwr */
     char *origusername;
-    char origauth[16]; /* used by servwr */
-    uint8_t origid; /* used by servwr */
+    char origauth[16];
+    uint8_t origid;
+    int udpsock; /* only for UDP */
+    uint16_t udpport; /* only for UDP */
 };
 
 /* requests that our client will send */
@@ -63,13 +63,6 @@ struct rqout {
     struct timeval expiry;
 };
 
-/* replies that a server will send */
-struct reply {
-    unsigned char *buf;
-    struct sockaddr_storage tosa; /* used by udpservwr */
-    int toudpsock; /* used by udpservwr */
-};
-
 struct queue {
     struct list *entries;
     pthread_mutex_t mutex;
@@ -206,6 +199,10 @@ struct protodefs {
                             sizeof(struct sockaddr_in) : \
                             sizeof(struct sockaddr_in6))
 
+#define SOCKADDRP_SIZE(addr) ((addr)->sa_family == AF_INET ? \
+                            sizeof(struct sockaddr_in) : \
+                            sizeof(struct sockaddr_in6))
+
 struct addrinfo *getsrcprotores(uint8_t type);
 struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
 struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
diff --git a/tcp.c b/tcp.c
index d59efa5..24d75ae 100644 (file)
--- a/tcp.c
+++ b/tcp.c
@@ -190,7 +190,7 @@ void *tcpserverwr(void *arg) {
     int cnt;
     struct client *client = (struct client *)arg;
     struct queue *replyq;
-    struct reply *reply;
+    struct request *reply;
     
     debug(DBG_DBG, "tcpserverwr: starting for %s", client->conf->host);
     replyq = client->replyq;
@@ -209,16 +209,15 @@ void *tcpserverwr(void *arg) {
                pthread_exit(NULL);
            }
        }
-       reply = (struct reply *)list_shift(replyq->entries);
+       reply = (struct request *)list_shift(replyq->entries);
        pthread_mutex_unlock(&replyq->mutex);
-       cnt = write(client->sock, reply->buf, RADLEN(reply->buf));
+       cnt = write(client->sock, reply->replybuf, RADLEN(reply->replybuf));
        if (cnt > 0)
            debug(DBG_DBG, "tcpserverwr: sent %d bytes, Radius packet of length %d",
-                 cnt, RADLEN(reply->buf));
+                 cnt, RADLEN(reply->replybuf));
        else
            debug(DBG_ERR, "tcpserverwr: write error for %s", client->conf->host);
-       free(reply->buf);
-       free(reply);
+       freerq(reply);
     }
 }
 
diff --git a/tls.c b/tls.c
index a9f91b3..e532211 100644 (file)
--- a/tls.c
+++ b/tls.c
@@ -241,7 +241,7 @@ void *tlsserverwr(void *arg) {
     unsigned long error;
     struct client *client = (struct client *)arg;
     struct queue *replyq;
-    struct reply *reply;
+    struct request *reply;
     
     debug(DBG_DBG, "tlsserverwr: starting for %s", client->conf->host);
     replyq = client->replyq;
@@ -261,17 +261,16 @@ void *tlsserverwr(void *arg) {
                pthread_exit(NULL);
            }
        }
-       reply = (struct reply *)list_shift(replyq->entries);
+       reply = (struct request *)list_shift(replyq->entries);
        pthread_mutex_unlock(&replyq->mutex);
-       cnt = SSL_write(client->ssl, reply->buf, RADLEN(reply->buf));
+       cnt = SSL_write(client->ssl, reply->replybuf, RADLEN(reply->replybuf));
        if (cnt > 0)
            debug(DBG_DBG, "tlsserverwr: sent %d bytes, Radius packet of length %d",
-                 cnt, RADLEN(reply->buf));
+                 cnt, RADLEN(reply->replybuf));
        else
            while ((error = ERR_get_error()))
                debug(DBG_ERR, "tlsserverwr: SSL: %s", ERR_error_string(error, NULL));
-       free(reply->buf);
-       free(reply);
+       freerq(reply);
     }
 }
 
diff --git a/udp.c b/udp.c
index 617f3cd..be61b0b 100644 (file)
--- a/udp.c
+++ b/udp.c
@@ -38,7 +38,7 @@ static struct queue *server_replyq = NULL;
 /* exactly one of client and server must be non-NULL */
 /* return who we received from in *client or *server */
 /* return from in sa if not NULL */
-unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
+unsigned char *radudpget(int s, struct client **client, struct server **server, uint16_t *port) {
     int cnt, len;
     unsigned char buf[4], *rad = NULL;
     struct sockaddr_storage from;
@@ -128,8 +128,8 @@ unsigned char *radudpget(int s, struct client **client, struct server **server,
            *server = p->servers;
        break;
     }
-    if (sa)
-       *sa = from;
+    if (port)
+       *port = port_get((struct sockaddr *)&from);
     return rad;
 }
 
@@ -138,32 +138,20 @@ int clientradputudp(struct server *server, unsigned char *rad) {
     struct sockaddr_storage sa;
     struct sockaddr *sap;
     struct clsrvconf *conf = server->conf;
-    in_port_t *port = NULL;
+    uint16_t port;
     
     len = RADLEN(rad);
+    port = port_get(conf->addrinfo->ai_addr);
     
     if (*rad == RAD_Accounting_Request) {
        sap = (struct sockaddr *)&sa;
        memcpy(sap, conf->addrinfo->ai_addr, conf->addrinfo->ai_addrlen);
+       port_set(sap, ++port);
     } else
        sap = conf->addrinfo->ai_addr;
-    
-    switch (sap->sa_family) {
-    case AF_INET:
-       port = &((struct sockaddr_in *)sap)->sin_port;
-       break;
-    case AF_INET6:
-       port = &((struct sockaddr_in6 *)sap)->sin6_port;
-       break;
-    default:
-       return 0;
-    }
 
-    if (*rad == RAD_Accounting_Request)
-       *port = htons(ntohs(*port) + 1);
-    
     if (sendto(server->sock, rad, len, 0, sap, conf->addrinfo->ai_addrlen) >= 0) {
-       debug(DBG_DBG, "clienradputudp: sent UDP of length %d to %s port %d", len, conf->host, ntohs(*port));
+       debug(DBG_DBG, "clienradputudp: sent UDP of length %d to %s port %d", len, conf->host, port);
        return 1;
     }
 
@@ -193,8 +181,8 @@ void *udpserverrd(void *arg) {
            sleep(5); /* malloc failed */
            continue;
        }
-       rq->buf = radudpget(*sp, &rq->from, NULL, &rq->fromsa);
-       rq->fromudpsock = *sp;
+       rq->buf = radudpget(*sp, &rq->from, NULL, &rq->udpport);
+       rq->udpsock = *sp;
        radsrv(rq);
     }
     free(sp);
@@ -202,22 +190,23 @@ void *udpserverrd(void *arg) {
 
 void *udpserverwr(void *arg) {
     struct queue *replyq = (struct queue *)arg;
-    struct reply *reply;
+    struct request *reply;
+    struct sockaddr_storage to;
     
     for (;;) {
        pthread_mutex_lock(&replyq->mutex);
-       while (!(reply = (struct reply *)list_shift(replyq->entries))) {
+       while (!(reply = (struct request *)list_shift(replyq->entries))) {
            debug(DBG_DBG, "udp server writer, waiting for signal");
            pthread_cond_wait(&replyq->cond, &replyq->mutex);
            debug(DBG_DBG, "udp server writer, got signal");
        }
        pthread_mutex_unlock(&replyq->mutex);
 
-       if (sendto(reply->toudpsock, reply->buf, RADLEN(reply->buf), 0,
-                  (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
-           debug(DBG_WARN, "sendudp: send failed");
-       free(reply->buf);
-       free(reply);
+       memcpy(&to, reply->from->addr, SOCKADDRP_SIZE(reply->from->addr));
+       port_set((struct sockaddr *)&to, reply->udpport);
+       if (sendto(reply->udpsock, reply->replybuf, RADLEN(reply->replybuf), 0, (struct sockaddr *)&to, SOCKADDR_SIZE(to)) < 0)
+           debug(DBG_WARN, "udpserverwr: send failed");
+       freerq(reply);
     }
 }
 
diff --git a/util.c b/util.c
index 5dc5f34..02614eb 100644 (file)
--- a/util.c
+++ b/util.c
@@ -72,6 +72,27 @@ void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int
     printf("\n");
 }
 
+uint16_t port_get(struct sockaddr *sa) {
+    switch (sa->sa_family) {
+    case AF_INET:
+       return ntohs(((struct sockaddr_in *)sa)->sin_port);
+    case AF_INET6:
+       return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
+    }
+    return 0;
+}
+
+void port_set(struct sockaddr *sa, uint16_t port) {
+    switch (sa->sa_family) {
+    case AF_INET:
+       ((struct sockaddr_in *)sa)->sin_port = htons(port);
+       break;
+    case AF_INET6:
+       ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
+       break;
+    }
+}
+
 int addr_equal(struct sockaddr *a, struct sockaddr *b) {
     switch (a->sa_family) {
     case AF_INET:
diff --git a/util.h b/util.h
index 7bb8202..732902e 100644 (file)
--- a/util.h
+++ b/util.h
@@ -5,5 +5,8 @@ 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);
+uint16_t port_get(struct sockaddr *sa);
+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);