]> 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:15 +0000 (06:21 +0000)
committerMark Andrews <marka@isc.org>
Thu, 7 Dec 2006 06:21:15 +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 f0404c281aaa046bf9c7db9c0b2bf6884587e709..e9aa3c0d8a7a8d8b7fba3a6235bb227a833d274a 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 dce4c71c95bbc1c6e0440d02146f2b7ac6234458..6513e77bf18fb030b13f650e3bf8e23949810229 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.333.2.45 2006/12/07 05:25:03 marka Exp $ */
+/* $Id: zone.c,v 1.333.2.46 2006/12/07 06:21:15 marka Exp $ */
 
 #include <config.h>
 
@@ -1874,6 +1874,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,
@@ -1892,6 +1923,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);