]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2705. [bug] Reconcile the XML stats version number with a later
authorEvan Hunt <each@isc.org>
Mon, 5 Oct 2009 21:57:42 +0000 (21:57 +0000)
committerEvan Hunt <each@isc.org>
Mon, 5 Oct 2009 21:57:42 +0000 (21:57 +0000)
                        BIND9 release, by adding a "name" attribute to
                        "cache" elements and increasing the version number
                        to 2.2.  (This is a minor version change, but may
                        affect XML parsers if they assume the cache element
                        doesn't take an attribute.)

2704. [bug] Serial of dynamic and stub zones could be inconsistent
with their SOA serial.  [RT #19387]

CHANGES
bin/named/statschannel.c
lib/dns/include/dns/zone.h
lib/dns/win32/libdns.def
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index b598f12f911471cdf9569ccfd451fc0086bc230e..be9d53e865ddc7ea31eac008c85abd49d45c584d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+2705.  [bug]           Reconcile the XML stats version number with a later
+                        BIND9 release, by adding a "name" attribute to
+                        "cache" elements and increasing the version number
+                        to 2.2.  (This is a minor version change, but may
+                        affect XML parsers if they assume the cache element
+                        doesn't take an attribute.)
+
+2704.  [bug]           Serial of dynamic and stub zones could be inconsistent
+                       with their SOA serial.  [RT #19387]
+
 2700.  [doc]           The match-mapped-addresses option is discouraged.
                        [RT #12252]
 
index 8d65935ffe1546afa19b33ec924b972080cf56ca..cebb4d2aa3c208163540073ea37f21aeb23c55ac 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: statschannel.c,v 1.2.2.19 2009/02/17 03:47:27 marka Exp $ */
+/* $Id: statschannel.c,v 1.2.2.20 2009/10/05 21:57:42 each Exp $ */
 
 /*! \file */
 
@@ -677,9 +677,11 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
        xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
        xmlTextWriterEndElement(writer);
 
-       serial = dns_zone_getserial(zone);
        xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial");
-       xmlTextWriterWriteFormatString(writer, "%u", serial);
+       if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS)
+               xmlTextWriterWriteFormatString(writer, "%u", serial);
+       else
+               xmlTextWriterWriteString(writer, ISC_XMLCHAR "-");
        xmlTextWriterEndElement(writer);
 
        zonestats = dns_zone_getrequeststats(zone);
@@ -728,7 +730,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "bind"));
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
        TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
-                                        ISC_XMLCHAR "2.0"));
+                                        ISC_XMLCHAR "2.2"));
 
        /* Set common fields for statistics dump */
        dumparg.type = statsformat_xml;
@@ -766,11 +768,15 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
 
                cachestats = dns_db_getrrsetstats(view->cachedb);
                if (cachestats != NULL) {
-                       xmlTextWriterStartElement(writer,
-                                                 ISC_XMLCHAR "cache");
+                       TRY0(xmlTextWriterStartElement(writer,
+                                                      ISC_XMLCHAR "cache"));
+                       TRY0(xmlTextWriterWriteAttribute(writer,
+                                                        ISC_XMLCHAR "name",
+                                                        ISC_XMLCHAR
+                                                        view->name));
                        dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
                                               &dumparg, 0);
-                       xmlTextWriterEndElement(writer); /* cache */
+                       TRY0(xmlTextWriterEndElement(writer)); /* cache */
                }
 
                xmlTextWriterEndElement(writer); /* view */
index 94953bcdea37424cc52207c723402c0fdb7b0da8..e5297b1ea0a679268a26a67bd34d0d0363050723 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.153.56.8 2009/07/11 04:28:14 marka Exp $ */
+/* $Id: zone.h,v 1.153.56.9 2009/10/05 21:57:42 each Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -147,13 +147,24 @@ dns_zone_getclass(dns_zone_t *zone);
  *\li  'zone' to be a valid zone.
  */
 
+isc_result_t
+dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp);
+
 isc_uint32_t
 dns_zone_getserial(dns_zone_t *zone);
 /*%<
- *     Returns the current serial number of the zone.
+ *     Returns the current serial number of the zone.  On success, the SOA
+ *     serial of the zone will be copied into '*serialp'.
+ *     dns_zone_getserial() cannot catch failure cases and is deprecated by
+ *     dns_zone_getserial2().
  *
  * Requires:
  *\li  'zone' to be a valid zone.
+ *\li  'serialp' to be non NULL
+ *
+ * Returns:
+ *\li  #ISC_R_SUCCESS
+ *\li  #DNS_R_NOTLOADED        zone DB is not loaded
  */
 
 void
index c6b92fdd8d9f97ace97a2f4878cd79d0b58d5dbc..6d3c4ed247ffdebae677ee14d5483f7b4d4352c1 100644 (file)
@@ -693,6 +693,7 @@ dns_zone_getorigin
 dns_zone_getqueryacl
 dns_zone_getrequeststats
 dns_zone_getserial
+dns_zone_getserial2
 dns_zone_getsigvalidityinterval
 dns_zone_getssutable
 dns_zone_getstatscounters
index 39c4a64bc7e251b1fa46f2aa5b1dd519e7dd5b5d..a4c42f1aaed9af0732aaf515375261d4443865be 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.470.12.12 2009/07/11 04:28:14 marka Exp $ */
+/* $Id: zone.c,v 1.470.12.13 2009/10/05 21:57:42 each Exp $ */
 
 /*! \file */
 
@@ -181,7 +181,6 @@ struct dns_zone {
        isc_time_t              dumptime;
        isc_time_t              loadtime;
        isc_time_t              notifytime;
-       isc_uint32_t            serial;
        isc_uint32_t            refresh;
        isc_uint32_t            retry;
        isc_uint32_t            expire;
@@ -629,7 +628,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        isc_time_settoepoch(&zone->dumptime);
        isc_time_settoepoch(&zone->loadtime);
        zone->notifytime = now;
-       zone->serial = 0;
        zone->refresh = DNS_ZONE_DEFAULTREFRESH;
        zone->retry = DNS_ZONE_DEFAULTRETRY;
        zone->expire = 0;
@@ -854,16 +852,35 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
        UNLOCK_ZONE(zone);
 }
 
-isc_uint32_t
-dns_zone_getserial(dns_zone_t *zone) {
-       isc_uint32_t serial;
+isc_result_t
+dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
+       isc_result_t result;
 
        REQUIRE(DNS_ZONE_VALID(zone));
+       REQUIRE(serialp != NULL);
 
        LOCK_ZONE(zone);
-       serial = zone->serial;
+       ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
+       if (zone->db != NULL) {
+               result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
+                                         NULL, NULL, NULL, NULL, NULL);
+       } else
+               result = DNS_R_NOTLOADED;
+       ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
        UNLOCK_ZONE(zone);
 
+       return (result);
+}
+
+isc_uint32_t
+dns_zone_getserial(dns_zone_t *zone) {
+       isc_result_t result;
+       isc_uint32_t serial;
+
+       result = dns_zone_getserial2(zone, &serial);
+       if (result != ISC_R_SUCCESS)
+               serial = 0; /* XXX: not really correct, but no other choice */
+
        return (serial);
 }
 
@@ -2039,7 +2056,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
        unsigned int soacount = 0;
        unsigned int nscount = 0;
        unsigned int errors = 0;
-       isc_uint32_t serial, refresh, retry, expire, minimum;
+       isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
        isc_time_t now;
        isc_boolean_t needdump = ISC_FALSE;
        isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
@@ -2164,14 +2181,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                         * This is checked in zone_replacedb() for slave zones
                         * as they don't reload from disk.
                         */
+                       result = zone_get_from_db(zone, zone->db, NULL, NULL,
+                                                 &oldserial, NULL, NULL, NULL,
+                                                 NULL, NULL);
+                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
                        if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
-                           !isc_serial_gt(serial, zone->serial)) {
+                           !isc_serial_gt(serial, oldserial)) {
                                isc_uint32_t serialmin, serialmax;
 
                                INSIST(zone->type == dns_zone_master);
 
-                               serialmin = (zone->serial + 1) & 0xffffffffU;
-                               serialmax = (zone->serial + 0x7fffffffU) &
+                               serialmin = (oldserial + 1) & 0xffffffffU;
+                               serialmax = (oldserial + 0x7fffffffU) &
                                             0xffffffffU;
                                dns_zone_log(zone, ISC_LOG_ERROR,
                                             "ixfr-from-differences: "
@@ -2180,16 +2201,15 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                                             serialmax);
                                result = DNS_R_BADZONE;
                                goto cleanup;
-                       } else if (!isc_serial_ge(serial, zone->serial))
+                       } else if (!isc_serial_ge(serial, oldserial))
                                dns_zone_log(zone, ISC_LOG_ERROR,
                                             "zone serial has gone backwards");
-                       else if (serial == zone->serial && !hasinclude)
+                       else if (serial == oldserial && !hasinclude)
                                dns_zone_log(zone, ISC_LOG_ERROR,
                                             "zone serial unchanged. "
                                             "zone may fail to transfer "
                                             "to slaves.");
                }
-               zone->serial = serial;
                zone->refresh = RANGE(refresh,
                                      zone->minrefresh, zone->maxrefresh);
                zone->retry = RANGE(retry,
@@ -2267,8 +2287,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
                zone_settimer(zone, &now);
 
        if (! dns_db_ispersistent(db))
-               dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
-                            zone->serial,
+               dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
                             dns_db_issecure(db) ? " (signed)" : "");
 
        return (result);
@@ -4543,7 +4562,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
        dns_rdata_t rdata = DNS_RDATA_INIT;
        dns_rdata_soa_t soa;
        isc_result_t result;
-       isc_uint32_t serial;
+       isc_uint32_t serial, oldserial;
        unsigned int j;
 
        zone = revent->ev_arg;
@@ -4766,12 +4785,17 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
 
        serial = soa.serial;
-
-       zone_debuglog(zone, me, 1, "serial: new %u, old %u",
-                     serial, zone->serial);
+       if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
+               result = dns_zone_getserial2(zone, &oldserial);
+               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+               zone_debuglog(zone, me, 1, "serial: new %u, old %u",
+                             serial, oldserial);
+       } else
+               zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
+                             serial);
        if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
            DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
-           isc_serial_gt(serial, zone->serial)) {
+           isc_serial_gt(serial, oldserial)) {
                if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
                                            &zone->sourceaddr, &now)) {
                        dns_zone_log(zone, ISC_LOG_INFO,
@@ -4795,7 +4819,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                }
                if (msg != NULL)
                        dns_message_destroy(&msg);
-       } else if (isc_serial_eq(soa.serial, zone->serial)) {
+       } else if (isc_serial_eq(soa.serial, oldserial)) {
                if (zone->masterfile != NULL) {
                        result = ISC_R_FAILURE;
                        if (zone->journal != NULL)
@@ -4828,7 +4852,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
                        dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
                                     "received from master %s < ours (%u)",
-                                    soa.serial, master, zone->serial);
+                                    soa.serial, master, oldserial);
                else
                        zone_debuglog(zone, me, 1, "ahead");
                zone->mastersok[zone->curmaster] = ISC_TRUE;
@@ -5926,13 +5950,21 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
                if (result == ISC_R_SUCCESS)
                        result = dns_rdataset_first(rdataset);
                if (result == ISC_R_SUCCESS) {
-                       isc_uint32_t serial = 0;
+                       isc_uint32_t serial = 0, oldserial;
 
                        dns_rdataset_current(rdataset, &rdata);
                        result = dns_rdata_tostruct(&rdata, &soa, NULL);
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
                        serial = soa.serial;
-                       if (isc_serial_le(serial, zone->serial)) {
+                       /*
+                        * The following should safely be performed without DB
+                        * lock and succeed in this context.
+                        */
+                       result = zone_get_from_db(zone, zone->db, NULL, NULL,
+                                                 &oldserial, NULL, NULL, NULL,
+                                                 NULL, NULL);
+                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+                       if (isc_serial_le(serial, oldserial)) {
                          dns_zone_log(zone, ISC_LOG_INFO,
                                             "notify from %s: "
                                             "zone is up to date",
@@ -6606,7 +6638,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
        if (zone->db != NULL && zone->journal != NULL &&
            DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
            !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
-               isc_uint32_t serial;
+               isc_uint32_t serial, oldserial;
 
                dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
 
@@ -6621,11 +6653,15 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
                /*
                 * This is checked in zone_postload() for master zones.
                 */
+               result = zone_get_from_db(zone, zone->db, NULL, NULL,
+                                         &oldserial, NULL, NULL, NULL, NULL,
+                                         NULL);
+               RUNTIME_CHECK(result == ISC_R_SUCCESS);
                if (zone->type == dns_zone_slave &&
-                   !isc_serial_gt(serial, zone->serial)) {
+                   !isc_serial_gt(serial, oldserial)) {
                        isc_uint32_t serialmin, serialmax;
-                       serialmin = (zone->serial + 1) & 0xffffffffU;
-                       serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
+                       serialmin = (oldserial + 1) & 0xffffffffU;
+                       serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
                        dns_zone_log(zone, ISC_LOG_ERROR,
                                     "ixfr-from-differences: failed: "
                                     "new serial (%u) out of range [%u - %u]",
@@ -6818,7 +6854,6 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
                                zone_unload(zone);
                                goto next_master;
                        }
-                       zone->serial = serial;
                        zone->refresh = RANGE(refresh, zone->minrefresh,
                                              zone->maxrefresh);
                        zone->retry = RANGE(retry, zone->minretry,
@@ -6856,7 +6891,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
                                buf[0] = '\0';
                        dns_zone_log(zone, ISC_LOG_INFO,
                                     "transferred serial %u%s",
-                                    zone->serial, buf);
+                                    serial, buf);
                }
 
                /*