]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
support dns64 modules in multiple views
authorEvan Hunt <each@isc.org>
Sat, 3 Nov 2018 18:33:27 +0000 (11:33 -0700)
committerEvan Hunt <each@isc.org>
Fri, 30 Aug 2019 22:27:56 +0000 (15:27 -0700)
- add a test with two dns64 configurations in separate views.
- set up a single SDB _dns64 implementation only once on the first
  load of the dns64 module, and tear it down on the last unload;
  this prevents a failure when attempting to register the SDB twice.
- in zone_free(), detach the view after detachiing the zone database,
  to prevent an occasional shutdown race in which the SDB implementation
  was deleted before the zone was shut down.

bin/plugins/dns64.c
bin/tests/system/dns64/ns4/example.db [new file with mode: 0644]
bin/tests/system/dns64/ns4/named.conf.in [new file with mode: 0644]
bin/tests/system/dns64/setup.sh
bin/tests/system/dns64/tests.sh
lib/dns/zone.c

index 9a023fb812b7fd80bc857088e88b58799f8fc47f..1fcb2de2d329fa36e0ff8f39b12bf4bf898ecdb9 100644 (file)
@@ -145,16 +145,22 @@ typedef struct dns64_instance {
         */
        isc_ht_t *ht;
 
-       /*
-        * SDB DNS64 database implementation.
-        */
-       dns_sdbimplementation_t *dns64_impl;
-
        dns_acl_t *dns64_mapped;
        dns64list_t dns64list;
        unsigned int dns64cnt;
 } dns64_instance_t;
 
+/*
+ * SDB DNS64 database implementation.
+ */
+dns_sdbimplementation_t *dns64_impl = NULL;
+
+/*
+ * Increment when registering, decrement when shutting down, so we
+ * can tear down the SDB implementation only on the last shutdown.
+ */
+static unsigned int registrations = 0;
+
 static isc_result_t
 dns64_createentry(isc_mem_t *mctx, const isc_netaddr_t *prefix,
                  unsigned int prefixlen, const isc_netaddr_t *suffix,
@@ -406,8 +412,8 @@ cleanup:
 }
 
 static isc_result_t
-check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
-            cfg_aclconfctx_t *actx, ns_hookctx_t *hctx)
+check_syntax(cfg_obj_t *dmap, const cfg_obj_t *cfg,
+            isc_mem_t *mctx, isc_log_t *lctx, void *actx)
 {
        isc_result_t result = ISC_R_SUCCESS;
        static const unsigned char zeros[16];
@@ -435,7 +441,7 @@ check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
 
                cfg_obj_asnetprefix(obj, &na, &prefixlen);
                if (na.family != AF_INET6) {
-                       cfg_obj_log(map, hctx->lctx, ISC_LOG_ERROR,
+                       cfg_obj_log(map, lctx, ISC_LOG_ERROR,
                                    "dns64 requires an IPv6 prefix");
                        result = ISC_R_FAILURE;
                        continue;
@@ -452,7 +458,7 @@ check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
                if (prefixlen != 32 && prefixlen != 40 && prefixlen != 48 &&
                    prefixlen != 56 && prefixlen != 64 && prefixlen != 96)
                {
-                       cfg_obj_log(map, hctx->lctx, ISC_LOG_ERROR,
+                       cfg_obj_log(map, lctx, ISC_LOG_ERROR,
                                    "bad prefix length %u [32/40/48/56/64/96]",
                                    prefixlen);
                        result = ISC_R_FAILURE;
@@ -467,8 +473,8 @@ check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
                                isc_result_t tresult;
 
                                tresult = cfg_acl_fromconfig(obj, cfg,
-                                                            hctx->lctx, actx,
-                                                            hctx->mctx, 0,
+                                                            lctx, actx,
+                                                            mctx, 0,
                                                             &acl);
                                if (acl != NULL) {
                                        dns_acl_detach(&acl);
@@ -484,7 +490,7 @@ check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
                if (obj != NULL) {
                        isc_netaddr_fromsockaddr(&sa, cfg_obj_assockaddr(obj));
                        if (sa.family != AF_INET6) {
-                               cfg_obj_log(map, hctx->lctx, ISC_LOG_ERROR,
+                               cfg_obj_log(map, lctx, ISC_LOG_ERROR,
                                            "dns64 requires a IPv6 suffix");
                                result = ISC_R_FAILURE;
                                continue;
@@ -497,7 +503,7 @@ check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
                                char netaddrbuf[ISC_NETADDR_FORMATSIZE];
                                isc_netaddr_format(&sa, netaddrbuf,
                                                   sizeof(netaddrbuf));
-                               cfg_obj_log(obj, hctx->lctx, ISC_LOG_ERROR,
+                               cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
                                            "bad suffix '%s' leading "
                                            "%u octets not zeros",
                                            netaddrbuf, nbytes);
@@ -512,8 +518,8 @@ check_syntax(const cfg_obj_t *dmap, const cfg_obj_t *cfg,
 static isc_result_t
 parse_parameters(dns64_instance_t *inst, const char *parameters,
                 const void *cfg, const char *cfg_file, unsigned long cfg_line,
-                void *actx, isc_mem_t *mctx, isc_log_t *lctx,
-                dns_view_t *view)
+                isc_mem_t *mctx, isc_log_t *lctx, dns_view_t *view,
+                void *actx)
 {
        isc_result_t result = ISC_R_SUCCESS;
        cfg_parser_t *parser = NULL;
@@ -531,7 +537,8 @@ parse_parameters(dns64_instance_t *inst, const char *parameters,
        CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
                               &cfg_type_parameters, 0, &param_obj));
 
-       CHECK(check_syntax(param_obj, (const cfg_obj_t *) cfg, actx, hctx));
+       CHECK(check_syntax(param_obj, (const cfg_obj_t *) cfg,
+                          mctx, lctx, actx));
 
        CHECK(cfg_map_get(param_obj, "dns64", &dns64_obj));
 
@@ -1037,31 +1044,33 @@ plugin_register(const char *parameters,
 
        isc_log_write(lctx, NS_LOGCATEGORY_GENERAL,
                      NS_LOGMODULE_HOOKS, ISC_LOG_INFO,
-                     "registering 'dns64' "
+                     "configuring 'dns64' "
                      "module from %s:%lu, %s parameters",
-                     cfg_file, cfg_line, parameters != NULL ? "with" : "no");
+                     cfg_file, cfg_line,
+                     parameters != NULL ? "with" : "no");
 
        inst = isc_mem_get(mctx, sizeof(*inst));
        memset(inst, 0, sizeof(*inst));
        isc_mem_attach(mctx, &inst->mctx);
 
-       /*
-        * Set up dns64 SDB implementation.
-        */
-       RUNTIME_CHECK(dns_sdb_register("_dns64", &dns64_methods, NULL,
-                                      DNS_SDBFLAG_RELATIVEOWNER |
-                                      DNS_SDBFLAG_RELATIVERDATA |
-                                      DNS_SDBFLAG_DNS64,
-                                      mctx, &inst->dns64_impl)
-                     == ISC_R_SUCCESS);
+       if (registrations++ == 0) {
+               /*
+                * Set up dns64 SDB implementation.
+                */
+               RUNTIME_CHECK(dns_sdb_register("_dns64", &dns64_methods, NULL,
+                                              DNS_SDBFLAG_RELATIVEOWNER |
+                                              DNS_SDBFLAG_RELATIVERDATA |
+                                              DNS_SDBFLAG_DNS64,
+                                              mctx, &dns64_impl)
+                             == ISC_R_SUCCESS);
+       }
 
        /*
         * Parse parameters.
         */
        if (parameters != NULL) {
-               CHECK(parse_parameters(inst, parameters,
-                                      cfg, cfg_file, cfg_line,
-                                      actx, mctx, lctx, view));
+               CHECK(parse_parameters(inst, parameters, cfg, cfg_file,
+                                      cfg_line, mctx, lctx, view, actx));
        }
 
        CHECK(isc_mempool_create(mctx, sizeof(dns64_data_t),
@@ -1117,8 +1126,6 @@ plugin_destroy(void **instp) {
        dns64_instance_t *inst = (dns64_instance_t *) *instp;
        dns64_t *dns64 = NULL;
 
-       dns_sdb_unregister(&inst->dns64_impl);
-
        if (inst->ht != NULL) {
                isc_ht_destroy(&inst->ht);
        }
@@ -1142,6 +1149,13 @@ plugin_destroy(void **instp) {
        isc_mem_putanddetach(&inst->mctx, inst, sizeof(*inst));
        *instp = NULL;
 
+       /*
+        * We only unregister the SDB on the final dlclose()
+        */
+       if (--registrations == 0) {
+               dns_sdb_unregister(&dns64_impl);
+       }
+
        return;
 }
 
diff --git a/bin/tests/system/dns64/ns4/example.db b/bin/tests/system/dns64/ns4/example.db
new file mode 100644 (file)
index 0000000..4e01c04
--- /dev/null
@@ -0,0 +1,21 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 86400      ; 1 day
+@               SOA    example. noc.example. (
+                                1         ; serial
+                                86400      ; refresh (1 day)
+                                3600       ; retry (1 hour)
+                                2592000    ; expire (4 weeks 2 days)
+                                25200      ; minimum (7 hours)
+                                )
+                        NS      @
+                        IN A    10.53.0.4
+
+a-only         A       1.2.3.4
diff --git a/bin/tests/system/dns64/ns4/named.conf.in b/bin/tests/system/dns64/ns4/named.conf.in
new file mode 100644 (file)
index 0000000..e6677ed
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// NS4
+
+controls { /* empty */ };
+
+options {
+       query-source address 10.53.0.4;
+       notify-source 10.53.0.4;
+       transfer-source 10.53.0.4;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.4; };
+       listen-on-v6 { none; };
+       dnssec-enable yes;
+       dnssec-validation yes;
+};
+
+view us {
+       match-clients { 10.53.0.1; };
+       recursion yes;
+
+       plugin query "../../../../plugins/lib/dns64.so" {
+               dns64 2001:cccc::/96 {
+                       clients { any; };
+               };
+       };
+
+       zone "." {
+               type hint;
+               file "../../common/root.hint";
+       };
+};
+
+view them {
+       recursion no;
+
+       plugin query "../../../../plugins/lib/dns64.so" {
+               dns64 2001:dddd::/96 {
+                       clients { any; };
+               };
+       };
+
+       zone "example" {
+               type master;
+               file "example.db";
+       };
+};
index 9c2756d6147f4cf70f8e9d184add38fdce5a0cee..7e353f11b24c192102c88838963ae393d200cdfd 100644 (file)
@@ -17,5 +17,6 @@ $SHELL clean.sh
 copy_setports ns1/named.conf.in ns1/named.conf
 copy_setports ns2/named.conf.in ns2/named.conf
 copy_setports ns3/named.conf.in ns3/named.conf
+copy_setports ns4/named.conf.in ns4/named.conf
 
 cd ns1 && $SHELL sign.sh
index e9f55be5922fd25c911cdc8725196d54e3e243b4..bdc6103275687248bc1ccf3f49dc1ef4a6d72c10 100644 (file)
@@ -1396,5 +1396,18 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+echo_i "checking dns64 configured in separate views($n)"
+ret=0
+# recursive view
+$DIG $DIGOPTS aaaa a-only.example +rec @10.53.0.4 -b 10.53.0.1 > dig.out.ns4.test$n.1 || ret=1
+grep "flags:.* ra;" dig.out.ns4.test$n.1 > /dev/null || ret=1
+grep "2001:cccc::102:305" dig.out.ns4.test$n.1 > /dev/null || ret=1
+$DIG $DIGOPTS aaaa a-only.example +rec @10.53.0.4 -b 10.53.0.2 > dig.out.ns4.test$n.2 || ret=1
+grep "flags:.* rd;" dig.out.ns4.test$n.2 > /dev/null || ret=1
+grep "2001:dddd::102:304" dig.out.ns4.test$n.2 > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
index 24430e610a63205de3b22e284014f07fdf4a17b3..a171c2b5def57d75b33011d9ffbc0e38f890993b 100644 (file)
@@ -1122,12 +1122,6 @@ zone_free(dns_zone_t *zone) {
        if (zone->loadtask != NULL) {
                isc_task_detach(&zone->loadtask);
        }
-       if (zone->view != NULL) {
-               dns_view_weakdetach(&zone->view);
-       }
-       if (zone->prev_view != NULL) {
-               dns_view_weakdetach(&zone->prev_view);
-       }
 
        /* Unmanaged objects */
        while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
@@ -1250,6 +1244,13 @@ zone_free(dns_zone_t *zone) {
                isc_stats_detach(&zone->gluecachestats);
        }
 
+       if (zone->view != NULL) {
+               dns_view_weakdetach(&zone->view);
+       }
+       if (zone->prev_view != NULL) {
+               dns_view_weakdetach(&zone->prev_view);
+       }
+
        /* last stuff */
        ZONEDB_DESTROYLOCK(&zone->dblock);
        isc_mutex_destroy(&zone->lock);