#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;
void createlistener(uint8_t type, char *arg) {
pthread_t th;
- struct addrinfo *listenres, *res;
+ struct addrinfo *res;
int s = -1, on = 1, *sp = NULL;
-
- listenres = resolvepassiveaddrinfo(arg, protodefs[type]->portdefault, protodefs[type]->socktype);
- if (!listenres)
+ struct hostportres *hp = newhostport(arg, protodefs[type]->portdefault, 0);
+
+ if (!hp || !resolvehostport(hp, protodefs[type]->socktype, 1))
debugx(1, DBG_ERR, "createlistener: failed to resolve %s", arg);
- for (res = listenres; res; res = res->ai_next) {
+ for (res = hp->addrinfo; res; res = res->ai_next) {
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (s < 0) {
debug(DBG_WARN, "createlistener: socket failed");
if (!sp)
debugx(1, DBG_ERR, "createlistener: socket/bind failed");
- debug(DBG_WARN, "createlistener: listening for %s on %s", protodefs[type]->name, arg);
- freeaddrinfo(listenres);
+ debug(DBG_WARN, "createlistener: listening for %s on %s:%s", protodefs[type]->name, hp->host ? hp->host : "*", hp->port);
+ freehostport(hp);
}
void createlisteners(uint8_t type) {
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);