]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3684. [bug] The list of included files would grow on reload.
authorMark Andrews <marka@isc.org>
Fri, 6 Dec 2013 22:44:45 +0000 (09:44 +1100)
committerMark Andrews <marka@isc.org>
Fri, 6 Dec 2013 22:44:45 +0000 (09:44 +1100)
                        [RT 35090]

CHANGES
bin/tests/system/zonechecks/ns1/named.conf
bin/tests/system/zonechecks/setup.sh
bin/tests/system/zonechecks/tests.sh
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index ad8eb6a68c62ab75d7528ddc4be03430c4f3ddd2..4dbf17fdc462207ae19fa3fb9242be44c90d5d85 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3684.  [bug]           The list of included files would grow on reload.
+                       [RT 35090]
+
 3683.  [cleanup]       Add a more detailed "not found" message to rndc
                        commands which specify a zone name. [RT #35059]
 
index 7be4cee879aa69c51ee48ce0bfcf88e41f316460..6caed2ff79fcf62518c3b6ebf2c9c99bbbe87d5b 100644 (file)
@@ -51,3 +51,7 @@ zone "master.example" {
        auto-dnssec maintain;
 };
 
+zone "reload.example" {
+       type master;
+       file "reload.db";
+};
index a72fbdbbb5e9d5d91eecfe614460f6e9f26c3377..0c8a69829e31b34490e0c03552dd4df2073248b7 100644 (file)
@@ -26,4 +26,6 @@ echo '$INCLUDE "master.db.signed"' >> master.db
 $KEYGEN -r ../random.data -3q master.example > /dev/null 2>&1
 $KEYGEN -r ../random.data -3qfk master.example > /dev/null 2>&1
 $SIGNER -SD -o master.example master.db > /dev/null 2>&1
-
+echo '$INCLUDE "soa.db"' > reload.db
+echo '@ 0 NS .' >> reload.db
+echo '@ 0 SOA . . 1 0 0 0 0' > soa.db
index 32bd4b3fe04178d58c3e48a529e8814f04dc6518..97305f72f59ff6c5b54f5479db6a87289d8474e5 100644 (file)
@@ -204,6 +204,35 @@ checkfor "nodes: " rndc.out.slave
 checkfor "next refresh: " rndc.out.slave
 checkfor "expires: " rndc.out.slave
 checkfor "secure: yes" rndc.out.slave
+for i in 0 1 2 3 4 5 6 7 8 9
+do
+       $RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 zonestatus reload.example > rndc.out.prereload 2>&1
+       grep "zone not loaded" rndc.out.prereload > /dev/null || break
+       sleep 1
+done
+checkfor "files: reload.db, soa.db$" rndc.out.prereload
+echo "@ 0 SOA . . 2 0 0 0 0" > ns1/soa.db
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reload reload.example
+for i in 0 1 2 3 4 5 6 7 8 9
+do
+       $DIG reload.example SOA @10.53.0.1 -p 5300 > dig.out
+       grep " 2 0 0 0 0" dig.out >/dev/null && break
+       sleep 1
+done
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 zonestatus reload.example > rndc.out.postreload 2>&1
+checkfor "files: reload.db, soa.db$" rndc.out.postreload
+sleep 1
+echo "@ 0 SOA . . 3 0 0 0 0" > ns1/reload.db
+echo "@ 0 NS ." >> ns1/reload.db
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reload reload.example
+for i in 0 1 2 3 4 5 6 7 8 9
+do
+       $DIG reload.example SOA @10.53.0.1 -p 5300 > dig.out
+       grep " 3 0 0 0 0" dig.out >/dev/null && break
+       sleep 1
+done
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 zonestatus reload.example > rndc.out.removeinclude 2>&1
+checkfor "files: reload.db$" rndc.out.removeinclude
 
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
index 388f0cf48d7048d8ad0d04a8124b75d9d0a7e53e..f24aa33bad94efb30e3f836ce686ee45084bdeb6 100644 (file)
@@ -218,6 +218,7 @@ struct dns_zone {
        dns_name_t              origin;
        char                    *masterfile;
        ISC_LIST(dns_include_t) includes;       /* Include files */
+       ISC_LIST(dns_include_t) newincludes;    /* Loading */
        unsigned int            nincludes;
        dns_masterformat_t      masterformat;
        char                    *journal;
@@ -869,6 +870,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        zone->strviewname = NULL;
        zone->masterfile = NULL;
        ISC_LIST_INIT(zone->includes);
+       ISC_LIST_INIT(zone->newincludes);
        zone->nincludes = 0;
        zone->masterformat = dns_masterformat_none;
        zone->keydirectory = NULL;
@@ -1065,6 +1067,13 @@ zone_free(dns_zone_t *zone) {
                isc_mem_free(zone->mctx, include->name);
                isc_mem_put(zone->mctx, include, sizeof *include);
        }
+       for (include = ISC_LIST_HEAD(zone->newincludes);
+            include != NULL;
+            include = ISC_LIST_HEAD(zone->newincludes)) {
+               ISC_LIST_UNLINK(zone->newincludes, include, link);
+               isc_mem_free(zone->mctx, include->name);
+               isc_mem_put(zone->mctx, include, sizeof *include);
+       }
        if (zone->masterfile != NULL)
                isc_mem_free(zone->mctx, zone->masterfile);
        zone->masterfile = NULL;
@@ -2052,6 +2061,15 @@ zone_registerinclude(const char *filename, void *arg) {
        if (filename == NULL)
                return;
 
+       /*
+        * Suppress duplicates.
+        */
+       for (inc = ISC_LIST_HEAD(zone->newincludes);
+            inc != NULL;
+            inc = ISC_LIST_NEXT(inc, link))
+               if (strcmp(filename, inc->name) == 0)
+                       return;
+
        inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
        if (inc == NULL)
                return;
@@ -2066,8 +2084,7 @@ zone_registerinclude(const char *filename, void *arg) {
        if (result != ISC_R_SUCCESS)
                isc_time_settoepoch(&inc->filetime);
 
-       ISC_LIST_APPEND(zone->includes, inc, link);
-       zone->nincludes++;
+       ISC_LIST_APPEND(zone->newincludes, inc, link);
 }
 
 static void
@@ -4048,6 +4065,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
        isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
        isc_boolean_t nomaster = ISC_FALSE;
        unsigned int options;
+       dns_include_t *inc;
 
        INSIST(LOCKED_ZONE(zone));
        if (inline_raw(zone))
@@ -4472,6 +4490,29 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                zone_settimer(zone, &now);
        }
 
+       /*
+        * Clear old include list.
+        */
+       for (inc = ISC_LIST_HEAD(zone->includes);
+            inc != NULL;
+            inc = ISC_LIST_HEAD(zone->includes)) {
+               ISC_LIST_UNLINK(zone->includes, inc, link);
+               isc_mem_free(zone->mctx, inc->name);
+               isc_mem_put(zone->mctx, inc, sizeof(*inc));
+       }
+       zone->nincludes = 0;
+
+       /*
+        * Transfer new include list.
+        */
+       for (inc = ISC_LIST_HEAD(zone->newincludes);
+            inc != NULL;
+            inc = ISC_LIST_HEAD(zone->newincludes)) {
+               ISC_LIST_UNLINK(zone->newincludes, inc, link);
+               ISC_LIST_APPEND(zone->includes, inc, link);
+               zone->nincludes++;
+       }
+
        if (! dns_db_ispersistent(db))
                dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
                             dns_db_issecure(db) ? " (DNSSEC signed)" : "");
@@ -4481,6 +4522,13 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
        return (result);
 
  cleanup:
+       for (inc = ISC_LIST_HEAD(zone->newincludes);
+            inc != NULL;
+            inc = ISC_LIST_HEAD(zone->newincludes)) {
+               ISC_LIST_UNLINK(zone->newincludes, inc, link);
+               isc_mem_free(zone->mctx, inc->name);
+               isc_mem_put(zone->mctx, inc, sizeof(*inc));
+       }
        if (zone->type == dns_zone_slave ||
            zone->type == dns_zone_stub ||
            zone->type == dns_zone_key ||