Commit a710bc2d authored by venaas's avatar venaas Committed by venaas

cleaning up code

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