diff --git a/CHANGES b/CHANGES index 13c30ddb99..257179ad36 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 7decde0c9b..6265318639 100644 --- a/lib/dns/tests/zonemgr_test.c +++ b/lib/dns/tests/zonemgr_test.c @@ -188,12 +188,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 9ad8960a54..2ac65321ac 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -943,6 +943,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)); @@ -957,16 +959,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 bff6e3d820..a8440e78e0 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -455,6 +455,7 @@ struct dns_unreachable { isc_sockaddr_t local; isc_uint32_t expire; isc_uint32_t last; + isc_uint32_t count; }; struct dns_zonemgr { @@ -14994,6 +14995,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)); @@ -15007,12 +15009,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 @@ -15086,6 +15089,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. @@ -15094,6 +15101,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. @@ -15102,6 +15110,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); }