Commit 883992d8 authored by Linus Nordberg's avatar Linus Nordberg
Browse files

Add client and server config options IPv4Only and IPv6Only.

Related to RADSECPROXY-37.

TODO: Add documentation.
parent 2f7eb5a9
...@@ -99,7 +99,9 @@ struct dtlsservernewparams { ...@@ -99,7 +99,9 @@ struct dtlsservernewparams {
void dtlssetsrcres() { void dtlssetsrcres() {
if (!srcres) if (!srcres)
srcres = resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, NULL, protodefs.socktype); srcres =
resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL,
AF_UNSPEC, NULL, protodefs.socktype);
} }
int udp2bio(int s, struct gqueue *q, int cnt) { int udp2bio(int s, struct gqueue *q, int cnt) {
......
...@@ -132,12 +132,12 @@ errexit: ...@@ -132,12 +132,12 @@ errexit:
return NULL; return NULL;
} }
int resolvehostport(struct hostportres *hp, int socktype, uint8_t passive) { int resolvehostport(struct hostportres *hp, int af, int socktype, uint8_t passive) {
struct addrinfo hints, *res; struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_socktype = socktype; hints.ai_socktype = socktype;
hints.ai_family = AF_UNSPEC; hints.ai_family = af;
if (passive) if (passive)
hints.ai_flags = AI_PASSIVE; hints.ai_flags = AI_PASSIVE;
...@@ -172,6 +172,7 @@ int resolvehostport(struct hostportres *hp, int socktype, uint8_t passive) { ...@@ -172,6 +172,7 @@ int resolvehostport(struct hostportres *hp, int socktype, uint8_t passive) {
} }
} }
} }
debug(DBG_DBG, "%s: %s -> %s", __func__, hp->host, addr2string(hp->addrinfo->ai_addr));
return 1; return 1;
errexit: errexit:
...@@ -213,22 +214,22 @@ void freehostports(struct list *hostports) { ...@@ -213,22 +214,22 @@ void freehostports(struct list *hostports) {
list_destroy(hostports); list_destroy(hostports);
} }
int resolvehostports(struct list *hostports, int socktype) { int resolvehostports(struct list *hostports, int af, int socktype) {
struct list_node *entry; struct list_node *entry;
struct hostportres *hp; struct hostportres *hp;
for (entry = list_first(hostports); entry; entry = list_next(entry)) { for (entry = list_first(hostports); entry; entry = list_next(entry)) {
hp = (struct hostportres *)entry->data; hp = (struct hostportres *)entry->data;
if (!hp->addrinfo && !resolvehostport(hp, socktype, 0)) if (!hp->addrinfo && !resolvehostport(hp, af, socktype, 0))
return 0; return 0;
} }
return 1; return 1;
} }
struct addrinfo *resolvepassiveaddrinfo(char *hostport, char *default_port, int socktype) { struct addrinfo *resolvepassiveaddrinfo(char *hostport, int af, char *default_port, int socktype) {
struct addrinfo *ai = NULL; struct addrinfo *ai = NULL;
struct hostportres *hp = newhostport(hostport, default_port, 0); struct hostportres *hp = newhostport(hostport, default_port, 0);
if (hp && resolvehostport(hp, socktype, 1)) { if (hp && resolvehostport(hp, af, socktype, 1)) {
ai = hp->addrinfo; ai = hp->addrinfo;
hp->addrinfo = NULL; hp->addrinfo = NULL;
} }
......
...@@ -17,9 +17,9 @@ struct hostportres *newhostport(char *hostport, char *default_port, uint8_t pref ...@@ -17,9 +17,9 @@ struct hostportres *newhostport(char *hostport, char *default_port, uint8_t pref
int addhostport(struct list **hostports, char **hostport, char *portdefault, uint8_t prefixok); int addhostport(struct list **hostports, char **hostport, char *portdefault, uint8_t prefixok);
void freehostport(struct hostportres *hp); void freehostport(struct hostportres *hp);
void freehostports(struct list *hostports); void freehostports(struct list *hostports);
int resolvehostport(struct hostportres *hp, int socktype, uint8_t passive); int resolvehostport(struct hostportres *hp, int af, int socktype, uint8_t passive);
int resolvehostports(struct list *hostports, int socktype); int resolvehostports(struct list *hostports, int af, int socktype);
struct addrinfo *resolvepassiveaddrinfo(char *hostport, char *default_port, int socktype); struct addrinfo *resolvepassiveaddrinfo(char *hostport, int af, char *default_port, int socktype);
int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport); int addressmatches(struct list *hostports, struct sockaddr *addr, uint8_t checkport);
int connecttcphostlist(struct list *hostports, struct addrinfo *src); int connecttcphostlist(struct list *hostports, struct addrinfo *src);
......
...@@ -1773,7 +1773,7 @@ void *clientwr(void *arg) { ...@@ -1773,7 +1773,7 @@ void *clientwr(void *arg) {
/* FIXME: Is resolving not always done by compileserverconfig(), /* FIXME: Is resolving not always done by compileserverconfig(),
* either as part of static configuration setup or by * either as part of static configuration setup or by
* dynamicconfig() above? */ * dynamicconfig() above? */
if (!resolvehostports(conf->hostports, conf->pdef->socktype)) { if (!resolvehostports(conf->hostports, conf->hostaf, conf->pdef->socktype)) {
debug(DBG_WARN, "%s: resolve failed, sleeping %ds", __func__, ZZZ); debug(DBG_WARN, "%s: resolve failed, sleeping %ds", __func__, ZZZ);
sleep(ZZZ); sleep(ZZZ);
goto errexit; goto errexit;
...@@ -1926,7 +1926,7 @@ void createlistener(uint8_t type, char *arg) { ...@@ -1926,7 +1926,7 @@ void createlistener(uint8_t type, char *arg) {
int s = -1, on = 1, *sp = NULL; int s = -1, on = 1, *sp = NULL;
struct hostportres *hp = newhostport(arg, protodefs[type]->portdefault, 0); struct hostportres *hp = newhostport(arg, protodefs[type]->portdefault, 0);
if (!hp || !resolvehostport(hp, protodefs[type]->socktype, 1)) if (!hp || !resolvehostport(hp, AF_UNSPEC, protodefs[type]->socktype, 1))
debugx(1, DBG_ERR, "createlistener: failed to resolve %s", arg); debugx(1, DBG_ERR, "createlistener: failed to resolve %s", arg);
for (res = hp->addrinfo; res; res = res->ai_next) { for (res = hp->addrinfo; res; res = res->ai_next) {
...@@ -2684,10 +2684,25 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) { ...@@ -2684,10 +2684,25 @@ int mergesrvconf(struct clsrvconf *dst, struct clsrvconf *src) {
return 1; return 1;
} }
int config_hostaf(const char *block, int ipv4only, int ipv6only, int *af) {
if (ipv4only && ipv6only) {
debug(DBG_ERR, "error in block %s, at most one of IPv4Only and "
"IPv6Only can be enabled", block);
return -1;
}
*af = AF_UNSPEC;
if (ipv4only)
*af = AF_INET;
if (ipv6only)
*af = AF_INET6;
return 0;
}
int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) { int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
struct clsrvconf *conf; struct clsrvconf *conf;
char *conftype = NULL, *rewriteinalias = NULL; char *conftype = NULL, *rewriteinalias = NULL;
long int dupinterval = LONG_MIN, addttl = LONG_MIN; long int dupinterval = LONG_MIN, addttl = LONG_MIN;
uint8_t ipv4only, ipv6only;
debug(DBG_DBG, "confclient_cb called for %s", block); debug(DBG_DBG, "confclient_cb called for %s", block);
...@@ -2701,6 +2716,8 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char ...@@ -2701,6 +2716,8 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
cf, block, cf, block,
"type", CONF_STR, &conftype, "type", CONF_STR, &conftype,
"host", CONF_MSTR, &conf->hostsrc, "host", CONF_MSTR, &conf->hostsrc,
"IPv4Only", CONF_BLN, &ipv4only,
"IPv6Only", CONF_BLN, &ipv6only,
"secret", CONF_STR, &conf->secret, "secret", CONF_STR, &conf->secret,
#if defined(RADPROT_TLS) || defined(RADPROT_DTLS) #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
"tls", CONF_STR, &conf->tls, "tls", CONF_STR, &conf->tls,
...@@ -2752,6 +2769,9 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char ...@@ -2752,6 +2769,9 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
} }
#endif #endif
if (config_hostaf(block, ipv4only, ipv6only, &conf->hostaf))
debugx(1, DBG_ERR, "error in block %s: ^", block);
if (dupinterval != LONG_MIN) { if (dupinterval != LONG_MIN) {
if (dupinterval < 0 || dupinterval > 255) if (dupinterval < 0 || dupinterval > 255)
debugx(1, DBG_ERR, "error in block %s, value of option DuplicateInterval is %d, must be 0-255", block, dupinterval); debugx(1, DBG_ERR, "error in block %s, value of option DuplicateInterval is %d, must be 0-255", block, dupinterval);
...@@ -2782,7 +2802,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char ...@@ -2782,7 +2802,7 @@ int confclient_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
} }
if (!addhostport(&conf->hostports, conf->hostsrc, conf->pdef->portdefault, 1) || if (!addhostport(&conf->hostports, conf->hostsrc, conf->pdef->portdefault, 1) ||
!resolvehostports(conf->hostports, conf->pdef->socktype)) !resolvehostports(conf->hostports, conf->hostaf, conf->pdef->socktype))
debugx(1, DBG_ERR, "%s: resolve failed, exiting", __func__); debugx(1, DBG_ERR, "%s: resolve failed, exiting", __func__);
if (!conf->secret) { if (!conf->secret) {
...@@ -2844,7 +2864,9 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) { ...@@ -2844,7 +2864,9 @@ int compileserverconfig(struct clsrvconf *conf, const char *block) {
return 0; return 0;
} }
if (!conf->dynamiclookupcommand && !resolvehostports(conf->hostports, conf->pdef->socktype)) { if (!conf->dynamiclookupcommand &&
!resolvehostports(conf->hostports, conf->hostaf,
conf->pdef->socktype)) {
debug(DBG_ERR, "%s: resolve failed", __func__); debug(DBG_ERR, "%s: resolve failed", __func__);
return 0; return 0;
} }
...@@ -2855,6 +2877,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char ...@@ -2855,6 +2877,7 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
struct clsrvconf *conf, *resconf; struct clsrvconf *conf, *resconf;
char *conftype = NULL, *rewriteinalias = NULL; char *conftype = NULL, *rewriteinalias = NULL;
long int retryinterval = LONG_MIN, retrycount = LONG_MIN, addttl = LONG_MIN; long int retryinterval = LONG_MIN, retrycount = LONG_MIN, addttl = LONG_MIN;
uint8_t ipv4only, ipv6only;
debug(DBG_DBG, "confserver_cb called for %s", block); debug(DBG_DBG, "confserver_cb called for %s", block);
...@@ -2875,6 +2898,8 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char ...@@ -2875,6 +2898,8 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
if (!getgenericconfig(cf, block, if (!getgenericconfig(cf, block,
"type", CONF_STR, &conftype, "type", CONF_STR, &conftype,
"host", CONF_MSTR, &conf->hostsrc, "host", CONF_MSTR, &conf->hostsrc,
"IPv4Only", CONF_BLN, &ipv4only,
"IPv6Only", CONF_BLN, &ipv6only,
"port", CONF_STR, &conf->portsrc, "port", CONF_STR, &conf->portsrc,
"secret", CONF_STR, &conf->secret, "secret", CONF_STR, &conf->secret,
#if defined(RADPROT_TLS) || defined(RADPROT_DTLS) #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
...@@ -2922,6 +2947,9 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char ...@@ -2922,6 +2947,9 @@ int confserver_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
free(conftype); free(conftype);
conftype = NULL; conftype = NULL;
if (config_hostaf(block, ipv4only, ipv6only, &conf->hostaf))
goto errexit;
conf->pdef = protodefs[conf->type]; conf->pdef = protodefs[conf->type];
if (!conf->confrewritein) if (!conf->confrewritein)
......
...@@ -106,6 +106,7 @@ struct clsrvconf { ...@@ -106,6 +106,7 @@ struct clsrvconf {
uint8_t type; /* RAD_UDP/RAD_TLS/RAD_TCP */ uint8_t type; /* RAD_UDP/RAD_TLS/RAD_TCP */
const struct protodefs *pdef; const struct protodefs *pdef;
char **hostsrc; char **hostsrc;
int hostaf;
char *portsrc; char *portsrc;
struct list *hostports; struct list *hostports;
char *secret; char *secret;
......
...@@ -78,7 +78,9 @@ static char **getlistenerargs() { ...@@ -78,7 +78,9 @@ static char **getlistenerargs() {
void tcpsetsrcres() { void tcpsetsrcres() {
if (!srcres) if (!srcres)
srcres = resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, NULL, protodefs.socktype); srcres =
resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL,
AF_UNSPEC, NULL, protodefs.socktype);
} }
int tcpconnect(struct server *server, struct timeval *when, int timeout, char *text) { int tcpconnect(struct server *server, struct timeval *when, int timeout, char *text) {
......
...@@ -82,7 +82,9 @@ static char **getlistenerargs() { ...@@ -82,7 +82,9 @@ static char **getlistenerargs() {
void tlssetsrcres() { void tlssetsrcres() {
if (!srcres) if (!srcres)
srcres = resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, NULL, protodefs.socktype); srcres =
resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL,
AF_UNSPEC, NULL, protodefs.socktype);
} }
int tlsconnect(struct server *server, struct timeval *when, int timeout, char *text) { int tlsconnect(struct server *server, struct timeval *when, int timeout, char *text) {
......
...@@ -86,7 +86,9 @@ static char **getlistenerargs() { ...@@ -86,7 +86,9 @@ static char **getlistenerargs() {
void udpsetsrcres() { void udpsetsrcres() {
if (!srcres) if (!srcres)
srcres = resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL, NULL, protodefs.socktype); srcres =
resolvepassiveaddrinfo(protoopts ? protoopts->sourcearg : NULL,
AF_UNSPEC, NULL, protodefs.socktype);
} }
void removeudpclientfromreplyq(struct client *c) { void removeudpclientfromreplyq(struct client *c) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment