From: Mark Andrews Date: Sat, 21 Sep 2013 07:20:42 +0000 (+1000) Subject: 3651. [tuning] Adjust when a master server is deemed unreachable. X-Git-Tag: v9.6-ESV-R11b1~61 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=2b0066dc1a715b77b3b793420983b4fb466e424c;p=thirdparty%2Fbind9.git 3651. [tuning] Adjust when a master server is deemed unreachable. [RT #27075] (cherry picked from commit 97a2a26cd93e153dcf8fb1ea6bf2311426496251) --- diff --git a/CHANGES b/CHANGES index d27c9ddfcbc..8a13b5997d6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3651. [tuning] Adjust when a master server is deemed unreachable. + [RT #27075] + 3650. [tuning] Use separate rate limiting queues for refresh and notify requests. [RT #30589] diff --git a/lib/dns/tests/zonemgr_test.c b/lib/dns/tests/zonemgr_test.c index 77008bec900..104f491ed78 100644 --- a/lib/dns/tests/zonemgr_test.c +++ b/lib/dns/tests/zonemgr_test.c @@ -183,12 +183,23 @@ ATF_TC_BODY(zonemgr_unreachable, tc) { in.s_addr = inet_addr("10.53.0.2"); isc_sockaddr_fromin(&addr2, &in, 5150); ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + /* + * We require multiple unreachableadd calls to mark a server as + * unreachable. + */ + dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now); + 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)); + /* + * We require multiple unreachableadd calls to mark a server as + * unreachable. + */ + dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now); dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now); ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 3026af97cdb..92c1184a243 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -937,6 +937,8 @@ xfrin_connect_done(isc_task_t *task, isc_event_t *event) { isc_result_t result = cev->result; char sourcetext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_t sockaddr; + dns_zonemgr_t * zmgr; + isc_time_t now; REQUIRE(VALID_XFRIN(xfr)); @@ -951,16 +953,16 @@ xfrin_connect_done(isc_task_t *task, isc_event_t *event) { return; } - if (result != ISC_R_SUCCESS) { - dns_zonemgr_t * zmgr = dns_zone_getmgr(xfr->zone); - isc_time_t now; - - if (zmgr != NULL) { + zmgr = dns_zone_getmgr(xfr->zone); + if (zmgr != NULL) { + if (result != ISC_R_SUCCESS) { TIME_NOW(&now); dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr, &xfr->sourceaddr, &now); - } - goto failure; + goto failure; + } else + dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr, + &xfr->sourceaddr); } result = isc_socket_getsockname(xfr->socket, &sockaddr); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 982ff2047d8..187caf744cf 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -393,6 +393,7 @@ struct dns_unreachable { isc_sockaddr_t local; isc_uint32_t expire; isc_uint32_t last; + isc_uint32_t count; }; struct dns_zonemgr { @@ -11413,6 +11414,7 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_rwlocktype_t locktype; isc_result_t result; isc_uint32_t seconds = isc_time_seconds(now); + isc_uint32_t count = 0; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); @@ -11426,12 +11428,13 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; zmgr->unreachable[i].last = seconds; + count = zmgr->unreachable[i].count; } break; } } RWUNLOCK(&zmgr->urlock, locktype); - return (ISC_TF(i < UNREACH_CHACHE_SIZE)); + return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U)); } void @@ -11505,6 +11508,10 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, */ zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME; zmgr->unreachable[i].last = seconds; + if (zmgr->unreachable[i].expire < seconds) + zmgr->unreachable[i].count = 1; + else + zmgr->unreachable[i].count++; } else if (slot != UNREACH_CHACHE_SIZE) { /* * Found a empty slot. Add a new entry to the cache. @@ -11513,6 +11520,7 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, zmgr->unreachable[slot].last = seconds; zmgr->unreachable[slot].remote = *remote; zmgr->unreachable[slot].local = *local; + zmgr->unreachable[slot].count = 1; } else { /* * Replace the least recently used entry in the cache. @@ -11521,6 +11529,7 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, zmgr->unreachable[oldest].last = seconds; zmgr->unreachable[oldest].remote = *remote; zmgr->unreachable[oldest].local = *local; + zmgr->unreachable[oldest].count = 1; } RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); }