Skip to content

Commit

Permalink
Merge 'blocking-startup' and update ChangeLog
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabian Mauchle committed May 3, 2021
2 parents 3d8e53c + 3890195 commit 1fcee6e
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 40 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ unreleased chanes
- Config option for DH-file
- Add rID and otherName options to certifcateAttributeCheck
- Allow multiple matchCertificateAttribute
- Option to start dynamic server in blocking mode

Misc:
- Move radsecproxy manpage to section 8
Expand Down
11 changes: 5 additions & 6 deletions dtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,16 +561,15 @@ int dtlsconnect(struct server *server, int timeout, char *text) {
server->ssl = NULL;

wait = connect_wait(start, server->connecttime, firsttry);
debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
sleep(wait);
firsttry = 0;

gettimeofday(&now, NULL);
if (timeout && (now.tv_sec - start.tv_sec) > timeout) {
debug(DBG_DBG, "tlsconnect: timeout");
if (timeout && (now.tv_sec - start.tv_sec) + wait > timeout) {
debug(DBG_DBG, "dtlsconnect: timeout");
if (source) freeaddrinfo(source);
return 0;
}
debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
sleep(wait);
firsttry = 0;

debug(DBG_INFO, "dtlsconnect: connecting to %s port %s", hp->host, hp->port);

Expand Down
81 changes: 52 additions & 29 deletions radsecproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <pthread.h>
#include <errno.h>
#include <assert.h>
#include <poll.h>
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/err.h>
Expand Down Expand Up @@ -1586,23 +1587,22 @@ void *clientwr(void *arg) {

#define ZZZ 900

server->state = RSP_SERVER_STATE_STARTUP;
if (server->state != RSP_SERVER_STATE_BLOCKING_STARTUP)
server->state = RSP_SERVER_STATE_STARTUP;
if (server->dynamiclookuparg && !dynamicconfig(server)) {
dynconffail = 1;
server->state = RSP_SERVER_STATE_FAILING;
debug(DBG_WARN, "%s: dynamicconfig(%s: %s) failed, sleeping %ds",
dynconffail = 1;
server->state = RSP_SERVER_STATE_FAILING;
debug(DBG_WARN, "%s: dynamicconfig(%s: %s) failed, sleeping %ds",
__func__, server->conf->name, server->dynamiclookuparg, ZZZ);
sleep(ZZZ);
goto errexit;
goto errexitwait;
}
/* FIXME: Is resolving not always done by compileserverconfig(),
* either as part of static configuration setup or by
* dynamicconfig() above? */
if (!resolvehostports(conf->hostports, conf->hostaf, conf->pdef->socktype)) {
debug(DBG_WARN, "%s: resolve failed, sleeping %ds", __func__, ZZZ);
server->state = RSP_SERVER_STATE_FAILING;
sleep(ZZZ);
goto errexit;
server->state = RSP_SERVER_STATE_FAILING;
goto errexitwait;
}

memset(&timeout, 0, sizeof(struct timespec));
Expand All @@ -1612,20 +1612,19 @@ void *clientwr(void *arg) {
laststatsrv = server->lastreply;

if (conf->pdef->connecter) {
if (!conf->pdef->connecter(server, server->dynamiclookuparg ? 5 : 0, "clientwr")) {
server->state = RSP_SERVER_STATE_FAILING;
if (server->dynamiclookuparg) {
debug(DBG_WARN, "%s: connect failed, sleeping %ds",
__func__, ZZZ);
sleep(ZZZ);
}
goto errexit;
}
if (pthread_create(&clientrdth, &pthread_attr, conf->pdef->clientconnreader, (void *)server)) {
debugerrno(errno, DBG_ERR, "clientwr: pthread_create failed");
server->state = RSP_SERVER_STATE_FAILING;
goto errexit;
}
if (!conf->pdef->connecter(server, server->dynamiclookuparg ? 5 : 0, "clientwr")) {
server->state = RSP_SERVER_STATE_FAILING;
if (server->dynamiclookuparg) {
debug(DBG_WARN, "%s: connect failed, sleeping %ds", __func__, ZZZ);
goto errexitwait;
}
goto errexit;
}
if (pthread_create(&clientrdth, &pthread_attr, conf->pdef->clientconnreader, (void *)server)) {
debugerrno(errno, DBG_ERR, "clientwr: pthread_create failed");
server->state = RSP_SERVER_STATE_FAILING;
goto errexit;
}
}
server->state = RSP_SERVER_STATE_CONNECTED;

Expand Down Expand Up @@ -1760,6 +1759,16 @@ void *clientwr(void *arg) {
}
}
}

errexitwait:
/* flush request queue so we don't block incoming retries by removing blocked duplicates*/
for (i=0; i < MAX_REQUESTS; i++) {
rqout = server->requests + i;
pthread_mutex_lock(rqout->lock);
freerqoutdata(rqout);
pthread_mutex_unlock(rqout->lock);
}
sleep(ZZZ);
errexit:
if (server->dynamiclookuparg) {
removeserversubrealms(realms, conf);
Expand Down Expand Up @@ -2059,7 +2068,7 @@ struct list *createsubrealmservers(struct realm *realm, struct list *srvconfs) {
* the srvconfs list. */
if (addserver(srvconf)) {
srvconf->servers->dynamiclookuparg = stringcopy(realm->name, 0);
srvconf->servers->state = RSP_SERVER_STATE_STARTUP;
srvconf->servers->state = srvconf->blockingstartup ? RSP_SERVER_STATE_BLOCKING_STARTUP : RSP_SERVER_STATE_STARTUP;
debug(DBG_DBG, "%s: new client writer for %s",
__func__, srvconf->servers->conf->name);
if (pthread_create(&clientth, &pthread_attr, clientwr, (void *)(srvconf->servers))) {
Expand Down Expand Up @@ -2117,10 +2126,12 @@ struct realm *adddynamicrealmserver(struct realm *realm, char *id) {
}

int dynamicconfig(struct server *server) {
int ok, fd[2], status;
int ok = 0, fd[2], status;
pid_t pid;
struct clsrvconf *conf = server->conf;
struct gconffile *cf = NULL;
struct pollfd fds[1];
FILE *pipein;

/* for now we only learn hostname/address */
debug(DBG_DBG, "dynamicconfig: need dynamic server config for %s", server->dynamiclookuparg);
Expand Down Expand Up @@ -2148,10 +2159,20 @@ int dynamicconfig(struct server *server) {
}

close(fd[1]);
pushgconffile(&cf, fdopen(fd[0], "r"), conf->dynamiclookupcommand);
ok = getgenericconfig(&cf, NULL, "Server", CONF_CBK, confserver_cb,
(void *) conf, NULL);
freegconf(&cf);
pipein = fdopen(fd[0], "r");
fds[0].fd = fd[0];
fds[0].events = POLLIN;
status = poll(fds, 1, 5000);
if (status < 0) {
debugerrno(errno, DBG_ERR, "dynamicconfig: error while waiting for command output");
} else if (status ==0) {
debug(DBG_WARN, "dynamicconfig: command did not return anything in time");
kill(pid, SIGKILL);
} else {
pushgconffile(&cf, pipein, conf->dynamiclookupcommand);
ok = getgenericconfig(&cf, NULL, "Server", CONF_CBK, confserver_cb, (void *) conf, NULL);
freegconf(&cf);
}

if (waitpid(pid, &status, 0) < 0) {
debugerrno(errno, DBG_ERR, "dynamicconfig: wait error");
Expand Down Expand Up @@ -2300,6 +2321,7 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
dst->retryinterval = src->retryinterval;
if (src->retrycount != 255)
dst->retrycount = src->retrycount;
dst->blockingstartup = src->blockingstartup;
return 1;
}

Expand Down Expand Up @@ -2573,6 +2595,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
"RetryCount", CONF_LINT, &retrycount,
"DynamicLookupCommand", CONF_STR, &conf->dynamiclookupcommand,
"LoopPrevention", CONF_BLN, &conf->loopprevention,
"BlockingStartup", CONF_BLN, &conf->blockingstartup,
NULL
)) {
debug(DBG_ERR, "configuration error");
Expand Down
11 changes: 11 additions & 0 deletions radsecproxy.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,17 @@ See section
\fBBASIC OPTIONS\fR for details on this option.
.RE

.BR "BlockingStartup (" on | off)
.RS
Start the dynamic server in blocking mode (default off), treating it as if it was already
connected and enqueue requests to this server. Queued requests will be sent out when the
connection is established. If however the dynamic lookup or the connection fails, the queued
requests will be lost.
(This is only considered for dynamic lookup servers. Ie when DynamicLookupCommand is specified)
Warning: when the dynamic lookup and connection process is slow, this wil block the
respective realm for that time.
.RE

The meaning and syntax of the following options are exactly the same as for the client
block. The details are not repeated here. Please refer to the definitions in the \fBCLIENT BLOCK\fR section.

Expand Down
2 changes: 2 additions & 0 deletions radsecproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ enum rsp_mac_type {

enum rsp_server_state {
RSP_SERVER_STATE_STARTUP = 0, /* default */
RSP_SERVER_STATE_BLOCKING_STARTUP,
RSP_SERVER_STATE_CONNECTED,
RSP_SERVER_STATE_RECONNECTING,
RSP_SERVER_STATE_FAILING
Expand Down Expand Up @@ -166,6 +167,7 @@ struct clsrvconf {
uint8_t addttl;
uint8_t keepalive;
uint8_t loopprevention;
uint8_t blockingstartup;
struct rewrite *rewritein;
struct rewrite *rewriteout;
pthread_mutex_t *lock; /* only used for updating clients so far */
Expand Down
11 changes: 6 additions & 5 deletions tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,17 @@ int tcpconnect(struct server *server, int timeout, char *text) {

pthread_mutex_unlock(&server->lock);
wait = connect_wait(start, server->connecttime, firsttry);
debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
sleep(wait);
firsttry = 0;

gettimeofday(&now, NULL);
if (timeout && (now.tv_sec - start.tv_sec) > timeout) {
if (timeout && (now.tv_sec - start.tv_sec) + wait > timeout) {
debug(DBG_DBG, "tcpconnect: timeout");
if (source) freeaddrinfo(source);
return 0;
}
debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
sleep(wait);
firsttry = 0;


pthread_mutex_lock(&server->lock);

debug(DBG_INFO, "tcpconnect: connecting to %s", server->conf->name);
Expand Down
6 changes: 6 additions & 0 deletions tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ int tlsconnect(struct server *server, int timeout, char *text) {
server->ssl = NULL;

wait = connect_wait(start, server->connecttime, firsttry);
gettimeofday(&now, NULL);
if (timeout && (now.tv_sec - start.tv_sec) + wait > timeout) {
debug(DBG_DBG, "tlsconnect: timeout");
if (source) freeaddrinfo(source);
return 0;
}
debug(DBG_INFO, "Next connection attempt to %s in %lds", server->conf->name, wait);
sleep(wait);
firsttry = 0;
Expand Down

0 comments on commit 1fcee6e

Please sign in to comment.