diff --git a/CHANGES b/CHANGES index 323b684e6c..02e42282a4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +5069. [bug] Fix a hang on in RPZ when named is shutdown during RPZ + zone update. [GL !907] + +5068. [bug] Fix a race in RPZ with min-update-interval set to 0. + [GL #643] + 5067. [bug] Don't minimize qname when sending the query to a forwarder. [GL #361] diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 1f919e1201..38fd3bd2cd 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -1802,18 +1803,30 @@ finish_update(dns_rpz_zone_t *rpz) { * If there's an update pending schedule it */ if (rpz->updatepending == true) { - uint64_t defer = rpz->min_update_interval; - isc_interval_t interval; - dns_name_format(&rpz->origin, dname, - DNS_NAME_FORMATSIZE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTER, ISC_LOG_INFO, - "rpz: %s: new zone version came " - "too soon, deferring update for " - "%" PRIu64 " seconds", dname, defer); - isc_interval_set(&interval, (unsigned int)defer, 0); - isc_timer_reset(rpz->updatetimer, isc_timertype_once, - NULL, &interval, true); + if (rpz->min_update_interval > 0) { + uint64_t defer = rpz->min_update_interval; + isc_interval_t interval; + dns_name_format(&rpz->origin, dname, + DNS_NAME_FORMATSIZE); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTER, ISC_LOG_INFO, + "rpz: %s: new zone version came " + "too soon, deferring update for " + "%" PRIu64 " seconds", dname, defer); + isc_interval_set(&interval, (unsigned int)defer, 0); + isc_timer_reset(rpz->updatetimer, isc_timertype_once, + NULL, &interval, true); + } else { + isc_event_t *event; + INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link)); + ISC_EVENT_INIT(&rpz->updateevent, + sizeof(rpz->updateevent), 0, NULL, + DNS_EVENT_RPZUPDATED, + dns_rpz_update_taskaction, + rpz, rpz, NULL, NULL); + event = &rpz->updateevent; + isc_task_send(rpz->rpzs->updater, &event); + } } UNLOCK(&rpz->rpzs->maint_lock); @@ -2100,6 +2113,14 @@ rpz_detach(dns_rpz_zone_t **rpzp, dns_rpz_zones_t *rpzs) { } if (rpz->updaterunning) { isc_task_purgeevent(rpz->rpzs->updater, &rpz->updateevent); + if (rpz->updbit != NULL) { + dns_dbiterator_destroy(&rpz->updbit); + } + if (rpz->newnodes != NULL) { + isc_ht_destroy(&rpz->newnodes); + } + dns_db_closeversion(rpz->updb, &rpz->updbversion, false); + dns_db_detach(&rpz->updb); } isc_timer_reset(rpz->updatetimer, isc_timertype_inactive,