From 6cd77933a3f113ea2bef7e4943f6dda6a26a39cb Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Fri, 26 Feb 2021 13:54:10 +0100 Subject: [PATCH] - Fix: Resolve interface names on control-interface too. --- daemon/daemon.c | 3 +- daemon/remote.c | 13 +++++-- doc/Changelog | 3 ++ services/listen_dnsport.c | 76 +++++++++++++++++++++++++++----------- services/listen_dnsport.h | 9 +++-- smallapp/unbound-control.c | 21 ++++++++++- testcode/fake_event.c | 5 ++- 7 files changed, 98 insertions(+), 32 deletions(-) diff --git a/daemon/daemon.c b/daemon/daemon.c index f5f0b88fe..6d6667883 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -320,7 +320,8 @@ daemon_open_shared_ports(struct daemon* daemon) free(daemon->ports); daemon->ports = NULL; } - if(!resolve_interface_names(daemon->cfg, &resif, &num_resif)) + if(!resolve_interface_names(daemon->cfg->ifs, + daemon->cfg->num_ifs, NULL, &resif, &num_resif)) return 0; /* see if we want to reuseport */ #ifdef SO_REUSEPORT diff --git a/daemon/remote.c b/daemon/remote.c index 18d960c56..7e432fe52 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -364,13 +364,20 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg) struct listen_port* l = NULL; log_assert(cfg->remote_control_enable && cfg->control_port); if(cfg->control_ifs.first) { - struct config_strlist* p; - for(p = cfg->control_ifs.first; p; p = p->next) { - if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) { + char** rcif = NULL; + int i, num_rcif = 0; + if(!resolve_interface_names(NULL, 0, cfg->control_ifs.first, + &rcif, &num_rcif)) { + return NULL; + } + for(i=0; icontrol_port, &l, 1, cfg)) { listening_ports_free(l); + config_del_strarray(rcif, num_rcif); return NULL; } } + config_del_strarray(rcif, num_rcif); } else { /* defaults */ if(cfg->do_ip6 && diff --git a/doc/Changelog b/doc/Changelog index 27e568aaf..ca2182719 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,9 @@ 26 February 2021: George - Fix for #367: rc_ports don't have ub_sock; skip cleaning up. +26 February 2021: Wouter + - Fix: Resolve interface names on control-interface too. + 25 February 2021: Wouter - Merge PR #367 : DNSTAP log local address. With code from PR #365 and fixes #368 : dnstap does not log the DNS message ID for diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index aed9cf784..b8c04a3ec 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -1528,13 +1528,12 @@ resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addres } #endif /* HAVE_GETIFADDRS */ -int resolve_interface_names(struct config_file* cfg, char*** resif, - int* num_resif) +int resolve_interface_names(char** ifs, int num_ifs, + struct config_strlist* list, char*** resif, int* num_resif) { #ifdef HAVE_GETIFADDRS - int i; struct ifaddrs *addrs = NULL; - if(cfg->num_ifs == 0) { + if(num_ifs == 0 && list == NULL) { *resif = NULL; *num_resif = 0; return 1; @@ -1545,38 +1544,71 @@ int resolve_interface_names(struct config_file* cfg, char*** resif, freeifaddrs(addrs); return 0; } - for(i=0; inum_ifs; i++) { - if(!resolve_ifa_name(addrs, cfg->ifs[i], resif, num_resif)) { - freeifaddrs(addrs); - config_del_strarray(*resif, *num_resif); - *resif = NULL; - *num_resif = 0; - return 0; + if(ifs) { + int i; + for(i=0; inext) { + if(!resolve_ifa_name(addrs, p->str, resif, num_resif)) { + freeifaddrs(addrs); + config_del_strarray(*resif, *num_resif); + *resif = NULL; + *num_resif = 0; + return 0; + } +} + } freeifaddrs(addrs); return 1; #else - int i; - if(cfg->num_ifs == 0) { + struct config_strlist* p; + if(num_ifs == 0 && list == NULL) { *resif = NULL; *num_resif = 0; return 1; } - *num_resif = cfg->num_ifs; + *num_resif = num_ifs; + for(p = list; p; p = p->next) { + *num_resif ++; + } *resif = calloc(*num_resif, sizeof(**resif)); if(!*resif) { log_err("out of memory"); return 0; } - for(i=0; i<*num_resif; i++) { - (*resif)[i] = strdup(cfg->ifs[i]); - if(!((*resif)[i])) { - log_err("out of memory"); - config_del_strarray(*resif, *num_resif); - *resif = NULL; - *num_resif = 0; - return 0; + if(ifs) { + int i; + for(i=0; inext) { + (*resif)[i] = strdup(p->str); + if(!((*resif)[i])) { + log_err("out of memory"); + config_del_strarray(*resif, *num_resif); + *resif = NULL; + *num_resif = 0; + return 0; + } } } return 1; diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h index cb614c834..1e51be9bf 100644 --- a/services/listen_dnsport.h +++ b/services/listen_dnsport.h @@ -150,16 +150,19 @@ struct listen_port* listening_ports_open(struct config_file* cfg, */ void listening_ports_free(struct listen_port* list); +struct config_strlist; /** * Resolve interface names in config and store result IP addresses - * @param cfg: config + * @param ifs: array of interfaces. The list of interface names, if not NULL. + * @param num_ifs: length of ifs array. + * @param list: if not NULL, this is used as the list of interface names. * @param resif: string array (malloced array of malloced strings) with * result. NULL if cfg has none. * @param num_resif: length of resif. Zero if cfg has zero num_ifs. * @return 0 on failure. */ -int resolve_interface_names(struct config_file* cfg, char*** resif, - int* num_resif); +int resolve_interface_names(char** ifs, int num_ifs, + struct config_strlist* list, char*** resif, int* num_resif); /** * Create commpoints with for this thread for the shared ports. diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index d58f1b2f9..5a6f0c560 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -63,6 +63,7 @@ #include "sldns/wire2str.h" #include "sldns/pkthdr.h" #include "services/rpz.h" +#include "services/listen_dnsport.h" #ifdef HAVE_SYS_IPC_H #include "sys/ipc.h" @@ -583,10 +584,27 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd) socklen_t addrlen; int addrfamily = 0, proto = IPPROTO_TCP; int fd, useport = 1; + char** rcif = NULL; + int num_rcif = 0; /* use svr or the first config entry */ if(!svr) { if(cfg->control_ifs.first) { - svr = cfg->control_ifs.first->str; + struct sockaddr_storage addr2; + socklen_t addrlen2; + if(extstrtoaddr(cfg->control_ifs.first->str, &addr2, + &addrlen2)) { + svr = cfg->control_ifs.first->str; + } else { + if(!resolve_interface_names(NULL, 0, + cfg->control_ifs.first, &rcif, + &num_rcif)) { + fatal_exit("could not resolve interface names"); + } + if(rcif == NULL || num_rcif == 0) { + fatal_exit("no control interfaces"); + } + svr = rcif[0]; + } } else if(cfg->do_ip4) { svr = "127.0.0.1"; } else { @@ -697,6 +715,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd) break; } fd_set_block(fd); + config_del_strarray(rcif, num_rcif); return fd; } diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 9508f3225..3ff933928 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -1306,8 +1306,9 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg) log_info("double delete of pending serviced query"); } -int resolve_interface_names(struct config_file* ATTR_UNUSED(cfg), - char*** ATTR_UNUSED(resif), int* ATTR_UNUSED(num_resif)) +int resolve_interface_names(char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs), + struct config_strlist* ATTR_UNUSED(list), char*** ATTR_UNUSED(resif), + int* ATTR_UNUSED(num_resif)) { return 1; } -- 2.47.2