]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3204. [bug] When a master server that has been marked as
authorEvan Hunt <each@isc.org>
Fri, 4 Nov 2011 05:52:58 +0000 (05:52 +0000)
committerEvan Hunt <each@isc.org>
Fri, 4 Nov 2011 05:52:58 +0000 (05:52 +0000)
unreachable but sends a NOTIFY, mark it reachable
again. [RT #25960]

CHANGES
lib/dns/include/dns/zone.h
lib/dns/tests/zonemgr_test.c
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 9ab76a6883071dfe753cb643934ff0861c07056d..aa83ca2eeab00a22fc9b1ce6276f61ea42955911 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3204.  [bug]           When a master server that has been marked as
+                       unreachable but sends a NOTIFY, mark it reachable
+                       again. [RT #25960]
+
 3203.  [bug]           Increase log level to 'info' for validation failures
                        from expired or not-yet-valid RRSIGs. [RT #21796]
 
index 06f5a3de942259b6b93f41e6681a4ed3e5a1364e..6de650dcb5fca416898de1a1d9291e1cf6170d6b 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.h,v 1.160.50.10 2011/09/08 23:45:16 tbox Exp $ */
+/* $Id: zone.h,v 1.160.50.11 2011/11/04 05:52:58 each Exp $ */
 
 #ifndef DNS_ZONE_H
 #define DNS_ZONE_H 1
@@ -1520,6 +1520,32 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
  *\li  'local' to be a valid sockaddr.
  */
 
+isc_boolean_t
+dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
+                       isc_sockaddr_t *local, isc_time_t *now);
+/*%<
+ *     Returns ISC_TRUE if the given local/remote address pair
+ *     is found in the zone maanger's unreachable cache.
+ *
+ * Requires:
+ *\li  'zmgr' to be a valid zone manager.
+ *\li  'remote' to be a valid sockaddr.
+ *\li  'local' to be a valid sockaddr.
+ *\li  'now' != NULL
+ */
+
+void
+dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
+                          isc_sockaddr_t *local);
+/*%<
+ *     Remove the pair of addresses from the unreachable cache.
+ *
+ * Requires:
+ *\li  'zmgr' to be a valid zone manager.
+ *\li  'remote' to be a valid sockaddr.
+ *\li  'local' to be a valid sockaddr.
+ */
+
 void
 dns_zone_forcereload(dns_zone_t *zone);
 /*%<
index ab9f40a37cae6173f931694b62d462faf9802740..47d81f1ade1fe2df85619f0be9174965aeec16e7 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zonemgr_test.c,v 1.3.2.2 2011/09/05 07:19:27 each Exp $ */
+/* $Id: zonemgr_test.c,v 1.3.2.3 2011/11/04 05:52:58 each Exp $ */
 
 /*! \file */
 
@@ -145,12 +145,79 @@ ATF_TC_BODY(zonemgr_managezone, tc) {
        dns_test_end();
 }
 
+ATF_TC(zonemgr_unreachable);
+ATF_TC_HEAD(zonemgr_unreachable, tc) {
+       atf_tc_set_md_var(tc, "descr", "manage and release a zone");
+}
+ATF_TC_BODY(zonemgr_unreachable, tc) {
+       dns_zonemgr_t *zonemgr = NULL;
+       dns_zone_t *zone = NULL;
+       isc_sockaddr_t addr1, addr2;
+       struct in_addr in;
+       isc_result_t result;
+       isc_time_t now;
+
+       UNUSED(tc);
+
+       TIME_NOW(&now);
+
+       result = dns_test_begin(NULL, ISC_TRUE);
+
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+       result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr,
+                                   &zonemgr);
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+       result = dns_test_makezone("foo", &zone, NULL, ISC_FALSE);
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+       result = dns_zonemgr_setsize(zonemgr, 1);
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+       result = dns_zonemgr_managezone(zonemgr, zone);
+       ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+       in.s_addr = inet_addr("10.53.0.1");
+       isc_sockaddr_fromin(&addr1, &in, 2112);
+       in.s_addr = inet_addr("10.53.0.2");
+       isc_sockaddr_fromin(&addr2, &in, 5150);
+       ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+       dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now);
+       ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+
+       in.s_addr = inet_addr("10.53.0.3");
+       isc_sockaddr_fromin(&addr2, &in, 5150);
+       ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+       dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now);
+       ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+
+       dns_zonemgr_unreachabledel(zonemgr, &addr1, &addr2);
+       ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+
+       in.s_addr = inet_addr("10.53.0.2");
+       isc_sockaddr_fromin(&addr2, &in, 5150);
+       ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+       dns_zonemgr_unreachabledel(zonemgr, &addr1, &addr2);
+       ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now));
+
+       dns_zonemgr_releasezone(zonemgr, zone);
+       dns_zone_detach(&zone);
+       dns_zonemgr_shutdown(zonemgr);
+       dns_zonemgr_detach(&zonemgr);
+       ATF_REQUIRE_EQ(zonemgr, NULL);
+
+       dns_test_end();
+}
+
+
 /*
  * Main
  */
 ATF_TP_ADD_TCS(tp) {
        ATF_TP_ADD_TC(tp, zonemgr_create);
        ATF_TP_ADD_TC(tp, zonemgr_managezone);
+       ATF_TP_ADD_TC(tp, zonemgr_unreachable);
        return (atf_no_error());
 }
 
@@ -172,6 +239,4 @@ ATF_TP_ADD_TCS(tp) {
  *     - dns_zonemgr_dbdestroyed
  *     - dns_zonemgr_setserialqueryrate
  *     - dns_zonemgr_getserialqueryrate
- *     - dns_zonemgr_unreachable
- *     - dns_zonemgr_unreachableadd
  */
index 98d276f8cfa6babdb19704d7d76aff537410aca5..6a98797f8ef8ce0d210ac618f5c9dbb7769fbd66 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.483.36.41 2011/11/03 02:58:57 each Exp $ */
+/* $Id: zone.c,v 1.483.36.42 2011/11/04 05:52:57 each Exp $ */
 
 /*! \file */
 
@@ -615,10 +615,6 @@ static void zone_saveunique(dns_zone_t *zone, const char *path,
 static void zone_maintenance(dns_zone_t *zone);
 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
 static void dump_done(void *arg, isc_result_t result);
-static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr,
-                                            isc_sockaddr_t *remote,
-                                            isc_sockaddr_t *local,
-                                            isc_time_t *now);
 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
                                     isc_uint16_t keyid, isc_boolean_t delete);
 
@@ -7539,7 +7535,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
                                if (!dns_zonemgr_unreachable(zone->zmgr,
                                                             &zone->masteraddr,
                                                             &zone->sourceaddr,
-                                                            &now)) {
+                                                            &now))
+                               {
                                        LOCK_ZONE(zone);
                                        DNS_ZONE_SETFLAG(zone,
                                                     DNS_ZONEFLG_SOABEFOREAXFR);
@@ -7733,7 +7730,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
            DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
            isc_serial_gt(serial, oldserial)) {
                if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
-                                           &zone->sourceaddr, &now)) {
+                                           &zone->sourceaddr, &now))
+               {
                        dns_zone_log(zone, ISC_LOG_INFO,
                                     "refresh: skipping %s as master %s "
                                     "(source %s) is unreachable (cached)",
@@ -8812,6 +8810,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
        char fromtext[ISC_SOCKADDR_FORMATSIZE];
        int match = 0;
        isc_netaddr_t netaddr;
+       isc_sockaddr_t local, remote;
 
        REQUIRE(DNS_ZONE_VALID(zone));
 
@@ -8961,7 +8960,10 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
                return (ISC_R_SUCCESS);
        }
        zone->notifyfrom = *from;
+       local = zone->masteraddr;
+       remote = zone->sourceaddr;
        UNLOCK_ZONE(zone);
+       dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
        dns_zone_refresh(zone);
        return (ISC_R_SUCCESS);
 }
@@ -10145,7 +10147,8 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
 
        isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
        if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
-                                   &zone->sourceaddr, &now)) {
+                                   &zone->sourceaddr, &now))
+       {
                isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
                dns_zone_log(zone, ISC_LOG_INFO,
                             "got_transfer_quota: skipping zone transfer as "
@@ -11202,7 +11205,7 @@ dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
        return (zmgr->serialqueryrate);
 }
 
-static isc_boolean_t
+isc_boolean_t
 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
                        isc_sockaddr_t *local, isc_time_t *now)
 {
@@ -11231,6 +11234,43 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
        return (ISC_TF(i < UNREACH_CHACHE_SIZE));
 }
 
+void
+dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
+                          isc_sockaddr_t *local)
+{
+       unsigned int i;
+       isc_rwlocktype_t locktype;
+       isc_result_t result;
+
+       char master[ISC_SOCKADDR_FORMATSIZE];
+       char source[ISC_SOCKADDR_FORMATSIZE];
+
+       isc_sockaddr_format(remote, master, sizeof(master));
+       isc_sockaddr_format(local, source, sizeof(source));
+
+       REQUIRE(DNS_ZONEMGR_VALID(zmgr));
+
+       locktype = isc_rwlocktype_read;
+       RWLOCK(&zmgr->rwlock, locktype);
+       for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
+               if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
+                   isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
+                       result = isc_rwlock_tryupgrade(&zmgr->rwlock);
+                       if (result == ISC_R_SUCCESS) {
+                               locktype = isc_rwlocktype_write;
+                               zmgr->unreachable[i].expire = 0;
+                               isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+                                             DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
+                                             "master %s (source %s) deleted "
+                                             "from unreachable cache",
+                                             master, source);
+                       }
+                       break;
+               }
+       }
+       RWUNLOCK(&zmgr->rwlock, locktype);
+}
+
 void
 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
                           isc_sockaddr_t *local, isc_time_t *now)