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) {
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);
}
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
}
}
......
......@@ -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);
}
}
......
......@@ -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);
}
}
......
......@@ -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:
......
......@@ -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);
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