#endif
#include <sys/time.h>
#include <sys/types.h>
-#include <sys/select.h>
#include <ctype.h>
#include <sys/wait.h>
#include <arpa/inet.h>
}
if (!resolvehostports(conf->hostports, conf->pdef->socktype)) {
- debug(DBG_WARN, "failed to resolve host %s port %s", conf->hostsrc ? conf->hostsrc : "(null)", conf->portsrc ? conf->portsrc : "(null)");
+ debug(DBG_WARN, "clientwr: resolve failed");
server->dynstartup = 0;
sleep(900);
goto errexit;
}
if (conf->pdef->connecter) {
- if (!conf->pdef->connecter(server, NULL, server->dynamiclookuparg ? 6 : 0, "clientwr")) {
+ if (!conf->pdef->connecter(server, NULL, server->dynamiclookuparg ? 5 : 0, "clientwr")) {
if (server->dynamiclookuparg) {
server->dynstartup = 0;
sleep(900);
void freeclsrvconf(struct clsrvconf *conf) {
free(conf->name);
- free(conf->hostsrc);
+ if (conf->hostsrc)
+ freegconfmstr(conf->hostsrc);
free(conf->portsrc);
free(conf->secret);
free(conf->tls);
return 1;
}
+char **mstringcopy(char **in) {
+ char **out;
+ int n;
+
+ if (!in)
+ return NULL;
+
+ for (n = 0; in[n]; n++);
+ out = malloc((n + 1) * sizeof(char *));
+ if (!out)
+ return NULL;
+ for (n = 0; in[n]; n++) {
+ out[n] = stringcopy(in[n], 0);
+ if (!out[n]) {
+ freegconfmstr(out);
+ return NULL;
+ }
+ }
+ out[n] = NULL;
+ return out;
+}
+
+int mergeconfmstring(char ***dst, char ***src) {
+ char **t;
+
+ if (*src) {
+ *dst = *src;
+ *src = NULL;
+ return 1;
+ }
+ if (*dst) {
+ t = mstringcopy(*dst);
+ if (!t) {
+ debug(DBG_ERR, "malloc failed");
+ return 0;
+ }
+ *dst = t;
+ }
+ return 1;
+}
+
/* assumes dst is a shallow copy */
int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
if (!mergeconfstring(&dst->name, &src->name) ||
- !mergeconfstring(&dst->hostsrc, &src->hostsrc) ||
+ !mergeconfmstring(&dst->hostsrc, &src->hostsrc) ||
!mergeconfstring(&dst->portsrc, &src->portsrc) ||
!mergeconfstring(&dst->secret, &src->secret) ||
!mergeconfstring(&dst->tls, &src->tls) ||
if (!getgenericconfig(cf, block,
"type", CONF_STR, &conftype,
- "host", CONF_STR, &conf->hostsrc,
+ "host", CONF_MSTR, &conf->hostsrc,
"secret", CONF_STR, &conf->secret,
#if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
"tls", CONF_STR, &conf->tls,
debugx(1, DBG_ERR, "configuration error");
conf->name = stringcopy(val, 0);
- if (!conf->hostsrc)
- conf->hostsrc = stringcopy(val, 0);
- if (!conf->name || !conf->hostsrc)
+ if (conf->name && !conf->hostsrc) {
+ conf->hostsrc = malloc(2 * sizeof(char *));
+ if (conf->hostsrc) {
+ conf->hostsrc[0] = stringcopy(val, 0);
+ conf->hostsrc[1] = NULL;
+ }
+ }
+ if (!conf->name || !conf->hostsrc || !conf->hostsrc[0])
debugx(1, DBG_ERR, "malloc failed");
if (!conftype)
if (!addhostport(&conf->hostports, conf->hostsrc, conf->pdef->portdefault, 1) ||
!resolvehostports(conf->hostports, conf->pdef->socktype))
- debugx(1, DBG_ERR, "failed to resolve %s, exiting", conf->hostsrc ? conf->hostsrc : "(null)");
+ debugx(1, DBG_ERR, "resolve failed, exiting");
if (!conf->secret) {
if (!conf->pdef->secretdefault)
}
if (!conf->dynamiclookupcommand && !resolvehostports(conf->hostports, conf->pdef->socktype)) {
- debug(DBG_ERR, "resolve host %s port %s, exiting", conf->hostsrc ? conf->hostsrc : "(null)", conf->portsrc ? conf->portsrc : "(null)");
+ debug(DBG_ERR, "resolve failed, exiting");
return 0;
}
return 1;
if (!getgenericconfig(cf, block,
"type", CONF_STR, &conftype,
- "host", CONF_STR, &conf->hostsrc,
+ "host", CONF_MSTR, &conf->hostsrc,
"port", CONF_STR, &conf->portsrc,
"secret", CONF_STR, &conf->secret,
#if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
}
conf->name = stringcopy(val, 0);
- if (!conf->name) {
+ if (conf->name && !conf->hostsrc) {
+ conf->hostsrc = malloc(2 * sizeof(char *));
+ if (conf->hostsrc) {
+ conf->hostsrc[0] = stringcopy(val, 0);
+ conf->hostsrc[1] = NULL;
+ }
+ }
+ if (!conf->name || !conf->hostsrc || !conf->hostsrc[0]) {
debug(DBG_ERR, "malloc failed");
goto errexit;
}
- if (!conf->hostsrc) {
- conf->hostsrc = stringcopy(val, 0);
- if (!conf->hostsrc) {
- debug(DBG_ERR, "malloc failed");
- goto errexit;
- }
- }
if (!conftype) {
debug(DBG_ERR, "error in block %s, option type missing", block);
setprotoopts(i, listenargs[i], sourcearg[i]);
}
-void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *pretend, uint8_t *loglevel, char **configfile) {
+void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *pretend, uint8_t *loglevel, char **configfile, char **pidfile) {
int c;
- while ((c = getopt(argc, argv, "c:d:fpv")) != -1) {
+ while ((c = getopt(argc, argv, "c:d:i:fpv")) != -1) {
switch (c) {
case 'c':
*configfile = optarg;
case 'f':
*foreground = 1;
break;
+ case 'i':
+ *pidfile = optarg;
+ break;
case 'p':
*pretend = 1;
break;
return;
usage:
- debugx(1, DBG_ERR, "Usage:\n%s [ -c configfile ] [ -d debuglevel ] [ -f ] [ -p ] [ -v ]", argv[0]);
+ debugx(1, DBG_ERR, "Usage:\n%s [ -c configfile ] [ -d debuglevel ] [ -f ] [ -i pidfile ] [ -p ] [ -v ]", argv[0]);
}
#ifdef SYS_SOLARIS9
for(;;) {
sigemptyset(&sigset);
+ sigaddset(&sigset, SIGHUP);
sigaddset(&sigset, SIGPIPE);
sigwait(&sigset, &sig);
- /* only get SIGPIPE right now, so could simplify below code */
switch (sig) {
case 0:
/* completely ignoring this */
break;
+ case SIGHUP:
+ debug(DBG_INFO, "sighandler: got SIGHUP");
+ debug_reopen_log();
+ break;
case SIGPIPE:
debug(DBG_WARN, "sighandler: got SIGPIPE, TLS write error?");
break;
}
}
+int createpidfile(const char *pidfile) {
+ int r;
+ FILE *f = fopen(pidfile, "w");
+ if (f)
+ r = fprintf(f, "%d\n", getpid());
+ return f && !fclose(f) && r >= 0;
+}
+
int main(int argc, char **argv) {
pthread_t sigth;
sigset_t sigset;
struct list_node *entry;
uint8_t foreground = 0, pretend = 0, loglevel = 0;
- char *configfile = NULL;
+ char *configfile = NULL, *pidfile = NULL;
struct clsrvconf *srvconf;
int i;
/* needed even if no TLS/DTLS transport */
sslinit();
- getargs(argc, argv, &foreground, &pretend, &loglevel, &configfile);
+ getargs(argc, argv, &foreground, &pretend, &loglevel, &configfile, &pidfile);
if (loglevel)
debug_set_level(loglevel);
getmainconfig(configfile ? configfile : CONFIG_MAIN);
debug_timestamp_on();
debug(DBG_INFO, "radsecproxy revision $Rev$ starting");
-
+ if (pidfile && !createpidfile(pidfile))
+ debugx(1, DBG_ERR, "failed to create pidfile %s: %s", pidfile, strerror(errno));
+
sigemptyset(&sigset);
- /* exit on all but SIGPIPE, ignore more? */
+ /* exit on all but SIGHUP|SIGPIPE, ignore more? */
+ sigaddset(&sigset, SIGHUP);
sigaddset(&sigset, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
pthread_create(&sigth, NULL, sighandler, NULL);