From: Mark Andrews Date: Tue, 26 Jun 2012 23:32:25 +0000 (+1000) Subject: 3342. [bug] Change #3314 broke saving of stub zones to disk X-Git-Tag: v9.8.3-P2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2773c56173086588e1df5a31cd3e80dbd60972f5;p=thirdparty%2Fbind9.git 3342. [bug] Change #3314 broke saving of stub zones to disk resulting in excessive cpu usage in some cases. [RT #29952] --- diff --git a/CHANGES b/CHANGES index 0b0d7c052fc..a018cd3bc4b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3342. [bug] Change #3314 broke saving of stub zones to disk + resulting in excessive cpu usage in some cases. + [RT #29952] + --- 9.8.3-P1 released --- 3331. [security] dns_rdataslab_fromrdataset could produce bad diff --git a/bin/tests/system/stub/tests.sh b/bin/tests/system/stub/tests.sh index b3001ba3750..573c5221b2a 100644 --- a/bin/tests/system/stub/tests.sh +++ b/bin/tests/system/stub/tests.sh @@ -21,14 +21,24 @@ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh status=0 +echo "I:check that the stub zone has been saved to disk" +for i in 1 2 3 4 5 6 7 8 9 20 +do + [ -f ns3/child.example.st ] && break + sleep 1 +done +[ -f ns3/child.example.st ] || { status=1; echo "I:failed"; } + +for pass in 1 2 +do -echo "I:trying an axfr that should be denied (NOTAUTH)" +echo "I:trying an axfr that should be denied (NOTAUTH) (pass=$pass)" ret=0 -$DIG +tcp data.child.example. @10.53.0.3 axfr -p 5300 > dig.out.ns3 || ret=1 +$DIG +tcp child.example. @10.53.0.3 axfr -p 5300 > dig.out.ns3 || ret=1 grep "; Transfer failed." dig.out.ns3 > /dev/null || ret=1 [ $ret = 0 ] || { status=1; echo "I:failed"; } -echo "I:look for stub zone data without recursion (should not be found)" +echo "I:look for stub zone data without recursion (should not be found) (pass=$pass)" for i in 1 2 3 4 5 6 7 8 9 do ret=0 @@ -41,11 +51,20 @@ done $PERL ../digcomp.pl knowngood.dig.out.norec dig.out.ns3 || ret=1 [ $ret = 0 ] || { status=1; echo "I:failed"; } -echo "I:look for stub zone data with recursion (should be found)" +echo "I:look for stub zone data with recursion (should be found) (pass=$pass)" ret=0 $DIG +tcp data.child.example. @10.53.0.3 txt -p 5300 > dig.out.ns3 || ret=1 $PERL ../digcomp.pl knowngood.dig.out.rec dig.out.ns3 || ret=1 [ $ret = 0 ] || { status=1; echo "I:failed"; } +[ $pass = 1 ] && { + echo "I:stopping stub server" + $PERL $SYSTEMTESTTOP/stop.pl . ns3 + + echo "I:re-starting stub server" + $PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns3 +} +done + echo "I:exit status: $status" exit $status diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 22870dc47b6..efe31ebf1b5 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -8027,13 +8027,14 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_master: case dns_zone_slave: case dns_zone_key: + case dns_zone_stub: LOCK_ZONE(zone); if (zone->masterfile != NULL && isc_time_compare(&now, &zone->dumptime) >= 0 && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) { dumping = was_dumping(zone); - } else + } else dumping = ISC_TRUE; UNLOCK_ZONE(zone); if (!dumping) { @@ -8386,7 +8387,7 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { goto fail; } - if (compact) { + if (compact && zone->type != dns_zone_stub) { dns_zone_t *dummy = NULL; LOCK_ZONE(zone); zone_iattach(zone, &dummy); @@ -9242,7 +9243,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = NULL; char master[ISC_SOCKADDR_FORMATSIZE]; char source[ISC_SOCKADDR_FORMATSIZE]; - isc_uint32_t nscnt, cnamecnt; + isc_uint32_t nscnt, cnamecnt, refresh, retry, expire; isc_result_t result; isc_time_t now; isc_boolean_t exiting = ISC_FALSE; @@ -9390,19 +9391,32 @@ stub_callback(isc_task_t *task, isc_event_t *event) { ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db == NULL) zone_attachdb(zone, stub->db); + result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh, + &retry, &expire, NULL, NULL); + if (result == ISC_R_SUCCESS) { + zone->refresh = RANGE(refresh, zone->minrefresh, + zone->maxrefresh); + zone->retry = RANGE(retry, zone->minretry, zone->maxretry); + zone->expire = RANGE(expire, zone->refresh + zone->retry, + DNS_MAX_EXPIRE); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); + } ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); dns_db_detach(&stub->db); - if (zone->masterfile != NULL) - zone_needdump(zone, 0); - dns_message_destroy(&msg); isc_event_free(&event); dns_request_destroy(&zone->request); + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); isc_interval_set(&i, zone->expire, 0); DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); + + if (zone->masterfile != NULL) + zone_needdump(zone, 0); + zone_settimer(zone, &now); goto free_stub;