]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix: Resolve interface names on control-interface too.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 26 Feb 2021 12:54:10 +0000 (13:54 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 26 Feb 2021 12:54:10 +0000 (13:54 +0100)
daemon/daemon.c
daemon/remote.c
doc/Changelog
services/listen_dnsport.c
services/listen_dnsport.h
smallapp/unbound-control.c
testcode/fake_event.c

index f5f0b88fe9fee5af0ba79649ba993bfc7d8fb262..6d666788325a1a4e416ae4ecea82b559202ac79a 100644 (file)
@@ -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
index 18d960c56f8742aca5c3d8a0e8474ccd3e21091c..7e432fe52bb4c78a7254ac32f725350365a059a1 100644 (file)
@@ -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; i<num_rcif; i++) {
+                       if(!add_open(rcif[i], cfg->control_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 &&
index 27e568aafb5376570680fb9e2eefc7b5b3eadb16..ca2182719014dfd7aa88b310d6cf611239b87f64 100644 (file)
@@ -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
index aed9cf78476beb2c3095df84206153a840fe3d5f..b8c04a3ec43c08f0313311e3e690b513c6d255ee 100644 (file)
@@ -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; i<cfg->num_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; i<num_ifs; i++) {
+                       if(!resolve_ifa_name(addrs, ifs[i], resif, num_resif)) {
+                               freeifaddrs(addrs);
+                               config_del_strarray(*resif, *num_resif);
+                               *resif = NULL;
+                               *num_resif = 0;
+                               return 0;
+                       }
                }
        }
+       if(list) {
+               struct config_strlist* p;
+               for(p = list; p; p = p->next) {
+                       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; i<num_ifs; i++) {
+                       (*resif)[i] = strdup(ifs[i]);
+                       if(!((*resif)[i])) {
+                               log_err("out of memory");
+                               config_del_strarray(*resif, *num_resif);
+                               *resif = NULL;
+                               *num_resif = 0;
+                               return 0;
+                       }
+               }
+       }
+       if(list) {
+               for(p = list; p; p = p->next) {
+                       (*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;
index cb614c834a637c5ae21ad16053d3c3da1ab65b32..1e51be9bfcabb6bc111fc505931881bf315f8e6a 100644 (file)
@@ -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.
index d58f1b2f9493f16247910eb1e9aed781e332afdd..5a6f0c560f74842572365485233cefac29fc5a56 100644 (file)
@@ -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;
 }
 
index 9508f322565ff1762ec1f58394705aba0e98f5f0..3ff933928e984eca6c029e8de611657873a8cb35 100644 (file)
@@ -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;
 }