]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2115. [bug] 'rndc reconfig' could trigger a INSIST if the
authorMark Andrews <marka@isc.org>
Thu, 7 Dec 2006 06:21:16 +0000 (06:21 +0000)
committerMark Andrews <marka@isc.org>
Thu, 7 Dec 2006 06:21:16 +0000 (06:21 +0000)
                        number of masters for a zone was reduced. [RT #16444]

CHANGES
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 421a95d1c93868f10e9bff18217c53a4060835ec..b04ac00b2553b29d8bd5a9511e83d77cfe1c5a61 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2115.  [bug]           'rndc reconfig' could trigger a INSIST if the
+                       number of masters for a zone was reduced. [RT #16444]
+
 2114.  [bug]           dig/host/nslookup: searches for names with multiple
                        labels were failing. [RT #16447]
 
index 1516f95d0b613219b461b590f95e0ad0fd117b36..5a73796399344fad5b0998e282964c1b4eb32982 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.410.18.46 2006/12/07 05:24:20 marka Exp $ */
+/* $Id: zone.c,v 1.410.18.47 2006/12/07 06:21:16 marka Exp $ */
 
 /*! \file */
 
@@ -2703,6 +2703,37 @@ dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
        return (result);
 }
 
+static isc_boolean_t
+same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
+            isc_uint32_t count)
+{
+       unsigned int i;
+
+       for (i = 0; i < count; i++)
+               if (!isc_sockaddr_equal(&old[i], &new[i]))
+                       return (ISC_FALSE);
+       return (ISC_TRUE);
+}
+
+static isc_boolean_t
+same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
+       unsigned int i;
+
+       if (old == NULL && new == NULL)
+               return (ISC_TRUE);
+       if (old == NULL || new == NULL)
+               return (ISC_FALSE);
+
+       for (i = 0; i < count; i++) {
+               if (old[i] == NULL && new[i] == NULL)
+                       continue;
+               if (old[i] == NULL || new[i] == NULL ||
+                    !dns_name_equal(old[i], new[i]))
+                       return (ISC_FALSE);
+       }
+       return (ISC_TRUE);
+}
+
 isc_result_t
 dns_zone_setmasterswithkeys(dns_zone_t *zone,
                            const isc_sockaddr_t *masters,
@@ -2722,6 +2753,19 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone,
        }
 
        LOCK_ZONE(zone);
+       /* 
+        * The refresh code assumes that 'masters' wouldn't change under it.
+        * If it will change then kill off any current refresh in progress
+        * and update the masters info.  If it won't change then we can just
+        * unlock and exit.
+        */
+       if (count != zone->masterscnt ||
+           !same_masters(zone->masters, masters, count) ||
+           !same_keynames(zone->masterkeynames, keynames, count)) {
+               if (zone->request != NULL)
+                       dns_request_cancel(zone->request);
+       } else
+               goto unlock;
        if (zone->masters != NULL) {
                isc_mem_put(zone->mctx, zone->masters,
                            zone->masterscnt * sizeof(*new));