From 7e4229900d01c6f8db09daf1e473b477faa2e033 Mon Sep 17 00:00:00 2001 From: venaas Date: Wed, 19 Sep 2007 09:34:21 +0000 Subject: [PATCH] failover, use first configured server with connectionok and lowest loss of status server responses git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@162 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- radsecproxy.c | 35 +++++++++++++++++++++++++++++------ radsecproxy.h | 1 + 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/radsecproxy.c b/radsecproxy.c index 7471826..fcb654d 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -1286,6 +1286,26 @@ void respondreject(struct request *rq, char *message) { sendreply(rq->from, resp, rq->from->conf->type == 'U' ? &rq->fromsa : NULL); } +struct server *realm2server(struct realm *realm) { + struct list_node *entry; + struct server *server, *best = NULL; + + for (entry = list_first(realm->srvconfs); entry; entry = list_next(entry)) { + server = ((struct clsrvconf *)entry->data)->servers; + if (!server->connectionok) + continue; + if (!server->loststatsrv) + return server; + if (!best) { + best = server; + continue; + } + if (server->loststatsrv < best->loststatsrv) + best = server; + } + return best; +} + void radsrv(struct request *rq) { uint8_t code, id, *auth, *attrs, *attr; uint16_t len; @@ -1293,7 +1313,6 @@ void radsrv(struct request *rq) { char username[256]; unsigned char *buf, newauth[16]; struct realm *realm = NULL; - struct list_node *node; buf = rq->buf; code = *(uint8_t *)buf; @@ -1335,9 +1354,8 @@ void radsrv(struct request *rq) { free(buf); return; } - node = list_first(realm->srvconfs); - to = ((struct clsrvconf *)node->data)->servers; - + + to = realm2server(realm); if (to && rqinqueue(to, rq->from, id)) { debug(DBG_INFO, "radsrv: already got request from host %s with id %d, ignoring", rq->from->conf->host, id); free(buf); @@ -1415,7 +1433,8 @@ void *clientrd(void *arg) { } server->connectionok = 1; - + server->loststatsrv = 0; + i = buf[1]; /* i is the id */ switch (*buf) { @@ -1587,6 +1606,7 @@ void *clientwr(void *arg) { if (server->conf->type == 'U') { if ((server->sock = connecttoserver(server->conf->addrinfo)) < 0) debugx(1, DBG_ERR, "clientwr: connecttoserver failed"); + server->connectionok = 1; } else tlsconnect(server, NULL, "new client"); @@ -1653,8 +1673,11 @@ void *clientwr(void *arg) { if (rq->tries == (*rq->buf == RAD_Status_Server || server->conf->type == 'T' ? 1 : REQUEST_RETRIES)) { debug(DBG_DBG, "clientwr: removing expired packet from queue"); - if (*rq->buf == RAD_Status_Server) + if (*rq->buf == RAD_Status_Server) { debug(DBG_WARN, "clientwr: no status server response, %s dead?", server->conf->host); + if (server->loststatsrv < 255) + server->loststatsrv++; + } free(rq->buf); /* setting this to NULL means that it can be reused */ rq->buf = NULL; diff --git a/radsecproxy.h b/radsecproxy.h index 540db32..1c80a92 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -103,6 +103,7 @@ struct server { pthread_t clientth; struct timeval lastconnecttry; uint8_t connectionok; + uint8_t loststatsrv; int nextid; struct request *requests; uint8_t newrq; -- 2.1.4