Skip to content

Commit

Permalink
Merge branch 'statusserver-auto'
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabian Mauchle committed May 14, 2019
2 parents b5978c5 + 818d63f commit fcfb122
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 56 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
changes since 1.7.2
New features:
- Autodetect status-server capability of servers
- Minimalistic status-server

Misc:
- No longer require docbook2x tools, but include plain manpages
- Fail on startup if overlapping clients with different tls blocks
Expand Down
122 changes: 74 additions & 48 deletions radsecproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ void sendrq(struct request *rq) {
if (!to)
goto errexit;

start = to->conf->statusserver ? 1 : 0;
start = to->conf->statusserver == RSP_STATSRV_OFF ? 0 : 1;
pthread_mutex_lock(&to->newrq_mutex);
if (start && rq->msg->code == RAD_Status_Server) {
if (!_internal_sendrq(to, 0, rq)) {
Expand Down Expand Up @@ -1669,9 +1669,11 @@ void replyh(struct server *server, unsigned char *buf) {
gettimeofday(&server->lastrcv, NULL);

if (rqout->rq->msg->code == RAD_Status_Server) {
freerqoutdata(rqout);
debug(DBG_NOTICE, "replyh: got status server response from %s", server->conf->name);
goto errunlock;
freerqoutdata(rqout);
debug(DBG_NOTICE, "replyh: got status server response from %s", server->conf->name);
if (server->conf->statusserver == RSP_STATSRV_AUTO)
server->conf->statusserver = RSP_STATSRV_MINIMAL;
goto errunlock;
}

gettimeofday(&server->lastreply, NULL);
Expand Down Expand Up @@ -1784,7 +1786,7 @@ void *clientwr(void *arg) {
pthread_t clientrdth;
int i, dynconffail = 0;
time_t secs;
uint8_t rnd, do_resend = 0;
uint8_t rnd, do_resend = 0, statusserver_requested = 0;
struct timeval now, laststatsrv;
struct timespec timeout;
struct request *statsrvrq;
Expand Down Expand Up @@ -1816,11 +1818,9 @@ void *clientwr(void *arg) {

memset(&timeout, 0, sizeof(struct timespec));

if (conf->statusserver) {
gettimeofday(&server->lastrcv, NULL);
gettimeofday(&laststatsrv, NULL);
}
gettimeofday(&server->lastreply, NULL);
server->lastrcv = server->lastreply;
laststatsrv = server->lastreply;

if (conf->pdef->connecter) {
if (!conf->pdef->connecter(server, server->dynamiclookuparg ? 5 : 0, "clientwr")) {
Expand All @@ -1847,7 +1847,7 @@ void *clientwr(void *arg) {
/* random 0-7 seconds */
RAND_bytes(&rnd, 1);
rnd /= 32;
if (conf->statusserver) {
if (conf->statusserver != RSP_STATSRV_OFF) {
secs = server->lastrcv.tv_sec > laststatsrv.tv_sec ? server->lastrcv.tv_sec : laststatsrv.tv_sec;
if (now.tv_sec - secs > STATUS_SERVER_PERIOD)
secs = now.tv_sec;
Expand Down Expand Up @@ -1911,24 +1911,33 @@ void *clientwr(void *arg) {
continue;
}

if (rqout->tries == (*rqout->rq->buf == RAD_Status_Server ? 1 : conf->retrycount + 1)) {
debug(DBG_DBG, "clientwr: removing expired packet from queue");
replylog(rqout->rq->msg, server, rqout->rq);
if (conf->statusserver) {
if (*rqout->rq->buf == RAD_Status_Server) {
debug(DBG_WARN, "clientwr: no status server response, %s dead?", conf->name);
if (server->lostrqs < 255)
server->lostrqs++;
}
if (rqout->tries > 0 && now.tv_sec - server->lastrcv.tv_sec > conf->retryinterval)
statusserver_requested = 1;
if (rqout->tries == (*rqout->rq->buf == RAD_Status_Server ? 1 : conf->retrycount + 1)) {
debug(DBG_DBG, "clientwr: removing expired packet from queue");
replylog(rqout->rq->msg, server, rqout->rq);
if (conf->statusserver == RSP_STATSRV_ON || conf->statusserver == RSP_STATSRV_MINIMAL) {
if (*rqout->rq->buf == RAD_Status_Server) {
debug(DBG_WARN, "clientwr: no status server response, %s dead?", conf->name);
if (server->lostrqs < 255)
server->lostrqs++;
}
} else {
if (conf->statusserver == RSP_STATSRV_AUTO && *rqout->rq->buf == RAD_Status_Server) {
if (server->lastreply.tv_sec >= laststatsrv.tv_sec) {
debug(DBG_DBG, "clientwr: status server autodetect faild, disabling status server for %s", conf->name);
conf->statusserver = RSP_STATSRV_OFF;
}
} else {
debug(DBG_WARN, "clientwr: no server response, %s dead?", conf->name);
if (server->lostrqs < 255)
server->lostrqs++;
}
freerqoutdata(rqout);
pthread_mutex_unlock(rqout->lock);
continue;
}
debug(DBG_WARN, "clientwr: no server response, %s dead?", conf->name);
if (server->lostrqs < 255)
server->lostrqs++;
}
}
freerqoutdata(rqout);
pthread_mutex_unlock(rqout->lock);
continue;
}

rqout->expiry.tv_sec = now.tv_sec + conf->retryinterval;
if (!timeout.tv_sec || rqout->expiry.tv_sec < timeout.tv_sec)
Expand All @@ -1941,19 +1950,22 @@ void *clientwr(void *arg) {
pthread_mutex_unlock(rqout->lock);
}
do_resend = 0;
if (conf->statusserver && server->state == RSP_SERVER_STATE_CONNECTED) {
secs = server->lastrcv.tv_sec > laststatsrv.tv_sec ? server->lastrcv.tv_sec : laststatsrv.tv_sec;
gettimeofday(&now, NULL);
if (now.tv_sec - secs > STATUS_SERVER_PERIOD) {
laststatsrv = now;
statsrvrq = createstatsrvrq();
if (statsrvrq) {
statsrvrq->to = server;
debug(DBG_DBG, "clientwr: sending %s to %s", radmsgtype2string(RAD_Status_Server), conf->name);
sendrq(statsrvrq);
}
}
}
if (server->state == RSP_SERVER_STATE_CONNECTED && !conf->statusserver == RSP_STATSRV_OFF) {
gettimeofday(&now, NULL);
if ((conf->statusserver == RSP_STATSRV_ON && now.tv_sec - (laststatsrv.tv_sec ? server->lastrcv.tv_sec : laststatsrv.tv_sec) > STATUS_SERVER_PERIOD) ||
(conf->statusserver == RSP_STATSRV_MINIMAL && statusserver_requested && now.tv_sec - laststatsrv.tv_sec > STATUS_SERVER_PERIOD) ||
(conf->statusserver == RSP_STATSRV_AUTO && server->lastreply.tv_sec >= laststatsrv.tv_sec)) {

laststatsrv = now;
statsrvrq = createstatsrvrq();
if (statsrvrq) {
statsrvrq->to = server;
debug(DBG_DBG, "clientwr: sending %s to %s", radmsgtype2string(RAD_Status_Server), conf->name);
sendrq(statsrvrq);
}
statusserver_requested = 0;
}
}
}
errexit:
if (server->dynamiclookuparg) {
Expand Down Expand Up @@ -2955,7 +2967,7 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {

int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
struct clsrvconf *conf, *resconf;
char *conftype = NULL, *rewriteinalias = NULL;
char *conftype = NULL, *rewriteinalias = NULL, *statusserver = NULL;
long int retryinterval = LONG_MIN, retrycount = LONG_MIN, addttl = LONG_MIN;
uint8_t ipv4only = 0, ipv6only = 0, confmerged = 0;

Expand All @@ -2970,10 +2982,11 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
conf->loopprevention = UCHAR_MAX; /* Uninitialized. */
resconf = (struct clsrvconf *)arg;
if (resconf) {
conf->statusserver = resconf->statusserver;
conf->certnamecheck = resconf->certnamecheck;
} else
conf->certnamecheck = 1;
conf->statusserver = resconf->statusserver;
conf->certnamecheck = resconf->certnamecheck;
} else {
conf->certnamecheck = 1;
}

if (!getgenericconfig(cf, block,
"type", CONF_STR, &conftype,
Expand All @@ -2992,7 +3005,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
"rewrite", CONF_STR, &rewriteinalias,
"rewriteIn", CONF_STR, &conf->confrewritein,
"rewriteOut", CONF_STR, &conf->confrewriteout,
"StatusServer", CONF_BLN, &conf->statusserver,
"StatusServer", CONF_STR, &statusserver,
"RetryInterval", CONF_LINT, &retryinterval,
"RetryCount", CONF_LINT, &retrycount,
"DynamicLookupCommand", CONF_STR, &conf->dynamiclookupcommand,
Expand Down Expand Up @@ -3068,6 +3081,19 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
conf->addttl = (uint8_t)addttl;
}

if (statusserver) {
if (strcasecmp(statusserver, "Off") == 0)
conf->statusserver = RSP_STATSRV_OFF;
else if (strcasecmp(statusserver, "On") == 0)
conf->statusserver = RSP_STATSRV_ON;
else if (strcasecmp(statusserver, "Minimal") == 0)
conf->statusserver = RSP_STATSRV_MINIMAL;
else if (strcasecmp(statusserver, "Auto") == 0)
conf->statusserver = RSP_STATSRV_AUTO;
else
debugx(1, DBG_ERR, "config error in blocck %s: invalid StatusServer value: %s", block, statusserver);
}

if (resconf) {
if (!mergesrvconf(resconf, conf))
goto errexit;
Expand Down Expand Up @@ -3241,8 +3267,8 @@ void getmainconfig(const char *configfile) {
"FTicksKey", CONF_STR, &fticks_key_str,
"FTicksSyslogFacility", CONF_STR, &options.ftickssyslogfacility,
"FTicksPrefix", CONF_STR, &options.fticksprefix,
"IPv4Only", CONF_BLN, &options.ipv4only,
"IPv6Only", CONF_BLN, &options.ipv6only,
"IPv4Only", CONF_BLN, &options.ipv4only,
"IPv6Only", CONF_BLN, &options.ipv6only,
NULL
))
debugx(1, DBG_ERR, "configuration error");
Expand Down
19 changes: 12 additions & 7 deletions radsecproxy.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -543,13 +543,18 @@ for the realm and then the SRV records for each NAPTR matching
\&'x-eduroam:radius.tls' is provided in \fItools/naptr\-eduroam.sh\fR.
.RE

.BR "StatusServer (" on | off )
.RS
Enable the use of status-server messages for this server (default off). If
statusserver is enabled, the proxy will send regular status-server messages to
the server to verify that it is alive. Status tracking of the server will solely
depend on status-server message and ignore lost requests. This should only be
enabled if the server supports it.
.BR "StatusServer (" on | off | minimal | auto )
.RS
Enable the use of status-server messages for this server (default \fBoff\fR). If
statusserver is enabled (\fBon\fR), the proxy will send regular status-server
messages to the server to verify that it is alive. Status tracking of the server
will solely depend on status-server message and ignore lost requests. This
should only be enabled if the server supports it. With the option \fBminimal\fR
status-server messages are only sent when regular requests have been lost and no
other replies have been received.

The option \fBauto\fR tries to detect whether the other server supports
status-server. If so, status-server messages are enabled in \fBminimal\fR mode.
.RE

.BI "RetryCount " count
Expand Down
9 changes: 8 additions & 1 deletion radsecproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ enum rsp_server_state {
RSP_SERVER_STATE_FAILING
};

enum rsp_statsrv {
RSP_STATSRV_OFF = 0,
RSP_STATSRV_ON,
RSP_STATSRV_MINIMAL,
RSP_STATSRV_AUTO
};

struct options {
char *pidfile;
char *logdestination;
Expand Down Expand Up @@ -145,7 +152,7 @@ struct clsrvconf {
char *confrewriteusername;
struct modattr *rewriteusername;
char *dynamiclookupcommand;
uint8_t statusserver;
enum rsp_statsrv statusserver;
uint8_t retryinterval;
uint8_t retrycount;
uint8_t dupinterval;
Expand Down

0 comments on commit fcfb122

Please sign in to comment.