From d9826419637bab4349d89bbe1e690a62424d7e21 Mon Sep 17 00:00:00 2001 From: venaas Date: Mon, 21 Jul 2008 09:38:08 +0000 Subject: only count lost normal rqs when not statusserver, restructured udp code a bit, preparing for multiple udp listeners git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@311 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- radsecproxy.c | 95 +++++++++++++++++++++++++++++------------------------------ radsecproxy.h | 7 +++++ 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/radsecproxy.c b/radsecproxy.c index f381c79..58a1e7f 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -72,8 +72,6 @@ static struct addrinfo *srcudpres = NULL; static struct addrinfo *srctcpres = NULL; static struct replyq *udp_server_replyq = NULL; -static int udp_server_sock = -1; -static int udp_accserver_sock = -1; static int udp_client4_sock = -1; static int udp_client6_sock = -1; static pthread_mutex_t *ssl_locks; @@ -1282,7 +1280,7 @@ void sendrq(struct server *to, struct request *rq) { pthread_mutex_unlock(&to->newrq_mutex); } -void sendreply(struct client *to, unsigned char *buf, struct sockaddr_storage *tosa) { +void sendreply(struct client *to, unsigned char *buf, struct sockaddr_storage *tosa, int toudpsock) { struct reply *reply; uint8_t first; @@ -1302,6 +1300,7 @@ void sendreply(struct client *to, unsigned char *buf, struct sockaddr_storage *t reply->buf = buf; if (tosa) reply->tosa = *tosa; + reply->toudpsock = toudpsock; pthread_mutex_lock(&to->replyq->mutex); @@ -1915,7 +1914,7 @@ void respondaccounting(struct request *rq) { resp[2] = 0; resp[3] = 20; debug(DBG_DBG, "respondaccounting: responding to %s", rq->from->conf->host); - sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL); + sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL, rq->fromudpsock); } void respondstatusserver(struct request *rq) { @@ -1931,7 +1930,7 @@ void respondstatusserver(struct request *rq) { resp[2] = 0; resp[3] = 20; debug(DBG_DBG, "respondstatusserver: responding to %s", rq->from->conf->host); - sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL); + sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL, rq->fromudpsock); } void respondreject(struct request *rq, char *message) { @@ -1954,7 +1953,7 @@ void respondreject(struct request *rq, char *message) { resp[21] = len - 20; memcpy(resp + 22, message, len - 22); } - sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL); + sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL, rq->fromudpsock); } struct clsrvconf *choosesrvconf(struct list *srvconfs) { @@ -2300,7 +2299,7 @@ int replyh(struct server *server, unsigned char *buf) { rq->received = 1; debug(DBG_INFO, "replyh: passing reply to client %s", from->conf->name); - sendreply(from, buf, from->conf->type == 'U' ? &fromsa : NULL); + sendreply(from, buf, from->conf->type == 'U' ? &fromsa : NULL, rq->fromudpsock); pthread_mutex_unlock(&server->newrq_mutex); return 1; } @@ -2465,9 +2464,17 @@ void *clientwr(void *arg) { if (rq->tries == (*rq->buf == RAD_Status_Server || conf->type == 'T' ? 1 : conf->retrycount + 1)) { debug(DBG_DBG, "clientwr: removing expired packet from queue"); - debug(DBG_WARN, "clientwr: no server response, %s dead?", conf->host); - if (server->lostrqs < 255) - server->lostrqs++; + if (conf->statusserver) { + if (*rq->buf == RAD_Status_Server) { + debug(DBG_WARN, "clientwr: no status server response, %s dead?", conf->host); + if (server->lostrqs < 255) + server->lostrqs++; + } + } else { + debug(DBG_WARN, "clientwr: no server response, %s dead?", conf->host); + if (server->lostrqs < 255) + server->lostrqs++; + } freerqdata(rq); /* setting this to NULL means that it can be reused */ rq->buf = NULL; @@ -2530,8 +2537,7 @@ void *udpserverwr(void *arg) { } pthread_mutex_unlock(&replyq->mutex); - if (sendto(*(uint8_t *)reply->buf == RAD_Accounting_Response ? udp_accserver_sock : udp_server_sock, - reply->buf, RADLEN(reply->buf), 0, + 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); @@ -2541,49 +2547,42 @@ void *udpserverwr(void *arg) { void *udpserverrd(void *arg) { struct request rq; - pthread_t udpserverwrth; - struct clsrvconf *listenres; - - listenres = resolve_hostport('U', options.listenudp, DEFAULT_UDP_PORT); - if ((udp_server_sock = bindtoaddr(listenres->addrinfo, AF_UNSPEC, 1, 0)) < 0) - debugx(1, DBG_ERR, "udpserverrd: socket/bind failed"); - - debug(DBG_WARN, "udpserverrd: listening for UDP on %s:%s", - listenres->host ? listenres->host : "*", listenres->port); - freeclsrvres(listenres); - - if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL)) - debugx(1, DBG_ERR, "pthread_create failed"); + struct udpserverrdarg *rdarg = (struct udpserverrdarg *)arg; for (;;) { memset(&rq, 0, sizeof(struct request)); - rq.buf = radudpget(udp_server_sock, &rq.from, NULL, &rq.fromsa); + rq.buf = radudpget(rdarg->s, &rq.from, NULL, &rq.fromsa); + if (rdarg->acconly && *(uint8_t *)rq.buf != RAD_Accounting_Request) { + debug(DBG_INFO, "udpserverrd: got something other than accounting-request, ignoring"); + freerqdata(&rq); + continue; + } + rq.fromudpsock = rdarg->s; radsrv(&rq); } } -void *udpaccserverrd(void *arg) { - struct request rq; +void createudplisteners(char *arg, uint8_t acconly) { + pthread_t th; struct clsrvconf *listenres; - - listenres = resolve_hostport('U', options.listenaccudp, DEFAULT_UDP_PORT); - if ((udp_accserver_sock = bindtoaddr(listenres->addrinfo, AF_UNSPEC, 1, 0)) < 0) - debugx(1, DBG_ERR, "udpserverrd: socket/bind failed"); + struct udpserverrdarg *rdarg; + + rdarg = malloc(sizeof(struct udpserverrdarg)); + if (!rdarg) + debugx(1, DBG_ERR, "malloc failed"); - debug(DBG_WARN, "udpaccserverrd: listening for UDP on %s:%s", + listenres = resolve_hostport('U', arg, DEFAULT_UDP_PORT); + if ((rdarg->s = bindtoaddr(listenres->addrinfo, AF_UNSPEC, 1, 0)) < 0) + debugx(1, DBG_ERR, "createudplisteners: socket/bind failed"); + + debug(DBG_WARN, "createudplisteners: listening for UDP on %s:%s", listenres->host ? listenres->host : "*", listenres->port); freeclsrvres(listenres); - - for (;;) { - memset(&rq, 0, sizeof(struct request)); - rq.buf = radudpget(udp_accserver_sock, &rq.from, NULL, &rq.fromsa); - if (*(uint8_t *)rq.buf == RAD_Accounting_Request) { - radsrv(&rq); - continue; - } - debug(DBG_INFO, "udpaccserverrd: got something other than accounting-request, ignoring"); - freerqdata(&rq); - } + + rdarg->acconly = acconly; + if (pthread_create(&th, NULL, udpserverrd, (void *)rdarg)) + debugx(1, DBG_ERR, "pthread_create failed"); + pthread_detach(th); } void *tlsserverwr(void *arg) { @@ -3806,7 +3805,7 @@ void *sighandler(void *arg) { } int main(int argc, char **argv) { - pthread_t sigth, udpserverth, udpaccserverth, udpclient4rdth, udpclient6rdth; + pthread_t sigth, udpclient4rdth, udpclient6rdth, udpserverwrth; sigset_t sigset; struct list_node *entry; uint8_t foreground = 0, pretend = 0, loglevel = 0; @@ -3850,11 +3849,11 @@ int main(int argc, char **argv) { if (client_udp_count) { udp_server_replyq = newreplyq(); - if (pthread_create(&udpserverth, NULL, udpserverrd, NULL)) + if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL)) debugx(1, DBG_ERR, "pthread_create failed"); + createudplisteners(options.listenudp, 0); if (options.listenaccudp) - if (pthread_create(&udpaccserverth, NULL, udpaccserverrd, NULL)) - debugx(1, DBG_ERR, "pthread_create failed"); + createudplisteners(options.listenaccudp, 1); } for (entry = list_first(srvconfs); entry; entry = list_next(entry)) { diff --git a/radsecproxy.h b/radsecproxy.h index 5a0b3e0..0a711d1 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -62,12 +62,14 @@ struct request { uint8_t origid; /* used by servwr */ char origauth[16]; /* used by servwr */ struct sockaddr_storage fromsa; /* used by udpservwr */ + int fromudpsock; /* used by udpservwr */ }; /* replies that a server will send */ struct reply { unsigned char *buf; struct sockaddr_storage tosa; /* used by udpservwr */ + int toudpsock; /* used by udpservwr */ }; struct replyq { @@ -76,6 +78,11 @@ struct replyq { pthread_cond_t cond; }; +struct udpserverrdarg { + int s; + uint8_t acconly; +}; + struct clsrvconf { char *name; char *conftype; -- cgit v1.1