]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Revert "General cleanup of dns_rpz implementation"
authorOndřej Surý <ondrej@isc.org>
Wed, 6 Apr 2022 08:41:49 +0000 (10:41 +0200)
committerOndřej Surý <ondrej@isc.org>
Wed, 6 Apr 2022 08:41:49 +0000 (10:41 +0200)
This reverts commit 84e62cece587dba9eebea274022696fb28525de2.

lib/dns/include/dns/rpz.h
lib/dns/rpz.c

index cf82275d2bca43032139ff5be33342fa4ad31a17..dfc5a12e5c2960f142c5d1830d13a382d0a49f34 100644 (file)
@@ -405,6 +405,14 @@ dns_rpz_attach_rpzs(dns_rpz_zones_t *source, dns_rpz_zones_t **target);
 void
 dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp);
 
+isc_result_t
+dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, dns_rpz_zones_t *rpzs,
+                 dns_rpz_num_t rpz_num) ISC_DEPRECATED;
+
+isc_result_t
+dns_rpz_ready(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **load_rpzsp,
+             dns_rpz_num_t rpz_num) ISC_DEPRECATED;
+
 isc_result_t
 dns_rpz_add(dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
            const dns_name_t *name);
index 60a6339fc2e2bf3ce608d8db2c94a2a65b02fd20..f59bffbddc53a1d64be5984ccd35d11de00f5105 100644 (file)
@@ -172,16 +172,31 @@ struct dns_rpz_nm_data {
        dns_rpz_nm_zbits_t wild;
 };
 
-static void
-rpz_attach(dns_rpz_zone_t *rpz, dns_rpz_zone_t **rpzp);
 static void
 rpz_detach(dns_rpz_zone_t **rpzp);
 
-static void
-rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp);
 static void
 rpz_detach_rpzs(dns_rpz_zones_t **rpzsp);
 
+#if 0
+/*
+ * Catch a name while debugging.
+ */
+static void
+catch_name(const dns_name_t *src_name, const char *tgt, const char *str) {
+       dns_fixedname_t tgt_namef;
+       dns_name_t *tgt_name;
+
+       tgt_name = dns_fixedname_initname(&tgt_namef);
+       dns_name_fromstring(tgt_name, tgt, DNS_NAME_DOWNCASE, NULL);
+       if (dns_name_equal(src_name, tgt_name)) {
+               isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
+                             DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
+                             "rpz hit failed: %s %s", str, tgt);
+       }
+}
+#endif /* if 0 */
+
 const char *
 dns_rpz_type2str(dns_rpz_type_t type) {
        switch (type) {
@@ -355,12 +370,13 @@ make_nm_set(dns_rpz_nm_zbits_t *tgt_set, dns_rpz_num_t rpz_num,
  */
 static void
 set_sum_pair(dns_rpz_cidr_node_t *cnode) {
+       dns_rpz_cidr_node_t *child;
        dns_rpz_addr_zbits_t sum;
 
        do {
-               dns_rpz_cidr_node_t *child = cnode->child[0];
                sum = cnode->set;
 
+               child = cnode->child[0];
                if (child != NULL) {
                        sum.client_ip |= child->sum.client_ip;
                        sum.ip |= child->sum.ip;
@@ -624,14 +640,13 @@ new_node(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *ip,
        int i, words, wlen;
 
        node = isc_mem_get(rpzs->mctx, sizeof(*node));
-       *node = (dns_rpz_cidr_node_t){
-               .prefix = prefix,
-       };
+       memset(node, 0, sizeof(*node));
 
        if (child != NULL) {
                node->sum = child->sum;
        }
 
+       node->prefix = prefix;
        words = prefix / DNS_RPZ_CIDR_WORD_BITS;
        wlen = prefix % DNS_RPZ_CIDR_WORD_BITS;
        i = 0;
@@ -652,11 +667,12 @@ new_node(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *ip,
 
 static void
 badname(int level, const dns_name_t *name, const char *str1, const char *str2) {
+       char namebuf[DNS_NAME_FORMATSIZE];
+
        /*
         * bin/tests/system/rpz/tests.sh looks for "invalid rpz".
         */
        if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) {
-               char namebuf[DNS_NAME_FORMATSIZE];
                dns_name_format(name, namebuf, sizeof(namebuf));
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
                              DNS_LOGMODULE_RBTDB, level,
@@ -682,10 +698,12 @@ ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix,
 #ifndef INET6_ADDRSTRLEN
 #define INET6_ADDRSTRLEN 46
 #endif /* ifndef INET6_ADDRSTRLEN */
+       int w[DNS_RPZ_CIDR_WORDS * 2];
        char str[1 + 8 + 1 + INET6_ADDRSTRLEN + 1];
        isc_buffer_t buffer;
        isc_result_t result;
-       int len;
+       int best_first, best_len, cur_first, cur_len;
+       int i, n, len;
 
        if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) {
                len = snprintf(str, sizeof(str), "%u.%u.%u.%u.%u",
@@ -697,19 +715,16 @@ ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix,
                        return (ISC_R_FAILURE);
                }
        } else {
-               int w[DNS_RPZ_CIDR_WORDS * 2];
-               int best_first, best_len, cur_first, cur_len;
-
                len = snprintf(str, sizeof(str), "%d", tgt_prefix);
                if (len < 0 || (size_t)len >= sizeof(str)) {
                        return (ISC_R_FAILURE);
                }
 
-               for (int n = 0; n < DNS_RPZ_CIDR_WORDS; n++) {
-                       w[n * 2 + 1] =
-                               ((tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - n] >> 16) &
+               for (i = 0; i < DNS_RPZ_CIDR_WORDS; i++) {
+                       w[i * 2 + 1] =
+                               ((tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - i] >> 16) &
                                 0xffff);
-                       w[n * 2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - n] &
+                       w[i * 2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - i] &
                                   0xffff;
                }
                /*
@@ -720,7 +735,7 @@ ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix,
                best_len = 0;
                cur_first = -1;
                cur_len = 0;
-               for (int n = 0; n <= 7; ++n) {
+               for (n = 0; n <= 7; ++n) {
                        if (w[n] != 0) {
                                cur_len = 0;
                                cur_first = -1;
@@ -735,9 +750,7 @@ ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix,
                        }
                }
 
-               for (int n = 0; n <= 7; ++n) {
-                       int i;
-
+               for (n = 0; n <= 7; ++n) {
                        INSIST(len > 0 && (size_t)len < sizeof(str));
                        if (n == best_first) {
                                i = snprintf(str + len, sizeof(str) - len,
@@ -800,10 +813,10 @@ name2ipkey(int log_level, const dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
           dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t *tgt_prefix,
           dns_rpz_addr_zbits_t *new_set) {
        dns_rpz_zone_t *rpz;
-       char ip_str[DNS_NAME_FORMATSIZE];
+       char ip_str[DNS_NAME_FORMATSIZE], ip2_str[DNS_NAME_FORMATSIZE];
        dns_offsets_t ip_name_offsets;
        dns_fixedname_t ip_name2f;
-       dns_name_t ip_name;
+       dns_name_t ip_name, *ip_name2;
        const char *prefix_str, *cp, *end;
        char *cp2;
        int ip_labels;
@@ -954,12 +967,11 @@ name2ipkey(int log_level, const dns_rpz_zones_t *rpzs, dns_rpz_num_t rpz_num,
                 * Convert the address back to a canonical domain name
                 * to ensure that the original name is in canonical form.
                 */
-               dns_name_t *ip_name2 = dns_fixedname_initname(&ip_name2f);
+               ip_name2 = dns_fixedname_initname(&ip_name2f);
                result = ip2name(tgt_ip, (dns_rpz_prefix_t)prefix_num, NULL,
                                 ip_name2);
                if (result != ISC_R_SUCCESS ||
                    !dns_name_equal(&ip_name, ip_name2)) {
-                       char ip2_str[DNS_NAME_FORMATSIZE];
                        dns_name_format(ip_name2, ip2_str, sizeof(ip2_str));
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
                                      DNS_LOGMODULE_RBTDB, log_level,
@@ -1119,6 +1131,7 @@ search(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *tgt_ip,
        dns_rpz_cidr_node_t *cur, *parent, *child, *new_parent, *sibling;
        dns_rpz_addr_zbits_t set;
        int cur_num, child_num;
+       dns_rpz_prefix_t dbit;
        isc_result_t find_result;
 
        set = *tgt_set;
@@ -1128,7 +1141,6 @@ search(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *tgt_ip,
        parent = NULL;
        cur_num = 0;
        for (;;) {
-               dns_rpz_prefix_t dbit;
                if (cur == NULL) {
                        /*
                         * No child so we cannot go down.
@@ -1437,71 +1449,67 @@ isc_result_t
 dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
                  isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
                  isc_timermgr_t *timermgr) {
-       dns_rpz_zones_t *rpzs;
+       dns_rpz_zones_t *zones;
        isc_result_t result = ISC_R_SUCCESS;
 
        REQUIRE(rpzsp != NULL && *rpzsp == NULL);
 
-       rpzs = isc_mem_get(mctx, sizeof(*rpzs));
-       *rpzs = (dns_rpz_zones_t){
-               .rps_cstr = rps_cstr,
-               .rps_cstr_size = rps_cstr_size,
-               .timermgr = timermgr,
-               .taskmgr = taskmgr,
-       };
+       zones = isc_mem_get(mctx, sizeof(*zones));
+       memset(zones, 0, sizeof(*zones));
 
-       isc_rwlock_init(&rpzs->search_lock, 0, 0);
-       isc_mutex_init(&rpzs->maint_lock);
-       isc_refcount_init(&rpzs->refs, 1);
-       isc_refcount_init(&rpzs->irefs, 1);
+       isc_rwlock_init(&zones->search_lock, 0, 0);
+       isc_mutex_init(&zones->maint_lock);
+       isc_refcount_init(&zones->refs, 1);
+       isc_refcount_init(&zones->irefs, 1);
 
+       zones->rps_cstr = rps_cstr;
+       zones->rps_cstr_size = rps_cstr_size;
 #ifdef USE_DNSRPS
        if (rps_cstr != NULL) {
-               result = dns_dnsrps_view_init(rpzs, rps_cstr);
-               if (result != ISC_R_SUCCESS) {
-                       goto cleanup_rbt;
-               }
+               result = dns_dnsrps_view_init(zones, rps_cstr);
        }
 #else  /* ifdef USE_DNSRPS */
-       INSIST(!rpzs->p.dnsrps_enabled);
+       INSIST(!zones->p.dnsrps_enabled);
 #endif /* ifdef USE_DNSRPS */
-       if (!rpzs->p.dnsrps_enabled) {
+       if (result == ISC_R_SUCCESS && !zones->p.dnsrps_enabled) {
                result = dns_rbt_create(mctx, rpz_node_deleter, mctx,
-                                       &rpzs->rbt);
+                                       &zones->rbt);
        }
 
        if (result != ISC_R_SUCCESS) {
                goto cleanup_rbt;
        }
 
-       result = isc_task_create(taskmgr, 0, &rpzs->updater);
+       result = isc_task_create(taskmgr, 0, &zones->updater);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_task;
        }
 
-       isc_mem_attach(mctx, &rpzs->mctx);
+       isc_mem_attach(mctx, &zones->mctx);
+       zones->timermgr = timermgr;
+       zones->taskmgr = taskmgr;
 
-       *rpzsp = rpzs;
+       *rpzsp = zones;
        return (ISC_R_SUCCESS);
 
 cleanup_task:
-       dns_rbt_destroy(&rpzs->rbt);
+       dns_rbt_destroy(&zones->rbt);
 
 cleanup_rbt:
-       isc_refcount_decrementz(&rpzs->irefs);
-       isc_refcount_destroy(&rpzs->irefs);
-       isc_refcount_decrementz(&rpzs->refs);
-       isc_refcount_destroy(&rpzs->refs);
-       isc_mutex_destroy(&rpzs->maint_lock);
-       isc_rwlock_destroy(&rpzs->search_lock);
-       isc_mem_put(mctx, rpzs, sizeof(*rpzs));
+       isc_refcount_decrementz(&zones->irefs);
+       isc_refcount_destroy(&zones->irefs);
+       isc_refcount_decrementz(&zones->refs);
+       isc_refcount_destroy(&zones->refs);
+       isc_mutex_destroy(&zones->maint_lock);
+       isc_rwlock_destroy(&zones->search_lock);
+       isc_mem_put(mctx, zones, sizeof(*zones));
 
        return (result);
 }
 
 isc_result_t
 dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
-       dns_rpz_zone_t *rpz;
+       dns_rpz_zone_t *zone;
        isc_result_t result;
 
        REQUIRE(rpzp != NULL && *rpzp == NULL);
@@ -1510,16 +1518,15 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
                return (ISC_R_NOSPACE);
        }
 
-       rpz = isc_mem_get(rpzs->mctx, sizeof(*rpz));
-       *rpz = (dns_rpz_zone_t){
-               .addsoa = true,
-       };
+       zone = isc_mem_get(rpzs->mctx, sizeof(*zone));
+
+       memset(zone, 0, sizeof(*zone));
+       isc_refcount_init(&zone->refs, 1);
 
-       isc_refcount_init(&rpz->refs, 1);
        result = isc_timer_create(rpzs->timermgr, isc_timertype_inactive, NULL,
                                  NULL, rpzs->updater,
-                                 dns_rpz_update_taskaction, rpz,
-                                 &rpz->updatetimer);
+                                 dns_rpz_update_taskaction, zone,
+                                 &zone->updatetimer);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_timer;
        }
@@ -1529,75 +1536,86 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
         * simplifies update_from_db
         */
 
-       isc_ht_init(&rpz->nodes, rpzs->mctx, 1);
-
-       dns_name_init(&rpz->origin, NULL);
-       dns_name_init(&rpz->client_ip, NULL);
-       dns_name_init(&rpz->ip, NULL);
-       dns_name_init(&rpz->nsdname, NULL);
-       dns_name_init(&rpz->nsip, NULL);
-       dns_name_init(&rpz->passthru, NULL);
-       dns_name_init(&rpz->drop, NULL);
-       dns_name_init(&rpz->tcp_only, NULL);
-       dns_name_init(&rpz->cname, NULL);
-
-       isc_time_settoepoch(&rpz->lastupdated);
-
-       rpz_attach_rpzs(rpzs, &rpz->rpzs);
-
-       ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0, NULL, 0,
-                      NULL, NULL, NULL, NULL, NULL);
+       isc_ht_init(&zone->nodes, rpzs->mctx, 1);
+
+       dns_name_init(&zone->origin, NULL);
+       dns_name_init(&zone->client_ip, NULL);
+       dns_name_init(&zone->ip, NULL);
+       dns_name_init(&zone->nsdname, NULL);
+       dns_name_init(&zone->nsip, NULL);
+       dns_name_init(&zone->passthru, NULL);
+       dns_name_init(&zone->drop, NULL);
+       dns_name_init(&zone->tcp_only, NULL);
+       dns_name_init(&zone->cname, NULL);
+
+       isc_time_settoepoch(&zone->lastupdated);
+       zone->updatepending = false;
+       zone->updaterunning = false;
+       zone->db = NULL;
+       zone->dbversion = NULL;
+       zone->updb = NULL;
+       zone->updbversion = NULL;
+       zone->updbit = NULL;
+       isc_refcount_increment(&rpzs->irefs);
+       zone->rpzs = rpzs;
+       zone->db_registered = false;
+       zone->addsoa = true;
+       ISC_EVENT_INIT(&zone->updateevent, sizeof(zone->updateevent), 0, NULL,
+                      0, NULL, NULL, NULL, NULL, NULL);
 
-       rpz->num = rpzs->p.num_zones++;
-       rpzs->zones[rpz->num] = rpz;
+       zone->num = rpzs->p.num_zones++;
+       rpzs->zones[zone->num] = zone;
 
-       *rpzp = rpz;
+       *rpzp = zone;
 
        return (ISC_R_SUCCESS);
 
 cleanup_timer:
-       isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
+       isc_refcount_decrementz(&zone->refs);
+       isc_refcount_destroy(&zone->refs);
+
+       isc_mem_put(rpzs->mctx, zone, sizeof(*zone));
 
        return (result);
 }
 
 isc_result_t
 dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
-       dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)fn_arg;
+       dns_rpz_zone_t *zone = (dns_rpz_zone_t *)fn_arg;
        isc_time_t now;
        uint64_t tdiff;
        isc_result_t result = ISC_R_SUCCESS;
        char dname[DNS_NAME_FORMATSIZE];
 
        REQUIRE(DNS_DB_VALID(db));
-       REQUIRE(rpz != NULL);
+       REQUIRE(zone != NULL);
 
-       LOCK(&rpz->rpzs->maint_lock);
+       LOCK(&zone->rpzs->maint_lock);
 
        /* New zone came as AXFR */
-       if (rpz->db != NULL && rpz->db != db) {
+       if (zone->db != NULL && zone->db != db) {
                /* We need to clean up the old DB */
-               if (rpz->dbversion != NULL) {
-                       dns_db_closeversion(rpz->db, &rpz->dbversion, false);
+               if (zone->dbversion != NULL) {
+                       dns_db_closeversion(zone->db, &zone->dbversion, false);
                }
-               dns_db_updatenotify_unregister(rpz->db,
-                                              dns_rpz_dbupdate_callback, rpz);
-               dns_db_detach(&rpz->db);
+               dns_db_updatenotify_unregister(zone->db,
+                                              dns_rpz_dbupdate_callback, zone);
+               dns_db_detach(&zone->db);
        }
 
-       if (rpz->db == NULL) {
-               RUNTIME_CHECK(rpz->dbversion == NULL);
-               dns_db_attach(db, &rpz->db);
+       if (zone->db == NULL) {
+               RUNTIME_CHECK(zone->dbversion == NULL);
+               dns_db_attach(db, &zone->db);
        }
 
-       if (!rpz->updatepending && !rpz->updaterunning) {
-               rpz->updatepending = true;
+       if (!zone->updatepending && !zone->updaterunning) {
+               zone->updatepending = true;
                isc_time_now(&now);
-               tdiff = isc_time_microdiff(&now, &rpz->lastupdated) / 1000000;
-               if (tdiff < rpz->min_update_interval) {
-                       uint64_t defer = rpz->min_update_interval - tdiff;
+               tdiff = isc_time_microdiff(&now, &zone->lastupdated) / 1000000;
+               if (tdiff < zone->min_update_interval) {
+                       uint64_t defer = zone->min_update_interval - tdiff;
                        isc_interval_t interval;
-                       dns_name_format(&rpz->origin, dname,
+                       dns_name_format(&zone->origin, dname,
                                        DNS_NAME_FORMATSIZE);
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                                      DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
@@ -1606,8 +1624,8 @@ dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
                                      "%" PRIu64 " seconds",
                                      dname, defer);
                        isc_interval_set(&interval, (unsigned int)defer, 0);
-                       dns_db_currentversion(rpz->db, &rpz->dbversion);
-                       result = isc_timer_reset(rpz->updatetimer,
+                       dns_db_currentversion(zone->db, &zone->dbversion);
+                       result = isc_timer_reset(zone->updatetimer,
                                                 isc_timertype_once, NULL,
                                                 &interval, true);
                        if (result != ISC_R_SUCCESS) {
@@ -1616,31 +1634,31 @@ dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
                } else {
                        isc_event_t *event;
 
-                       dns_db_currentversion(rpz->db, &rpz->dbversion);
-                       INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link));
-                       ISC_EVENT_INIT(&rpz->updateevent,
-                                      sizeof(rpz->updateevent), 0, NULL,
+                       dns_db_currentversion(zone->db, &zone->dbversion);
+                       INSIST(!ISC_LINK_LINKED(&zone->updateevent, ev_link));
+                       ISC_EVENT_INIT(&zone->updateevent,
+                                      sizeof(zone->updateevent), 0, NULL,
                                       DNS_EVENT_RPZUPDATED,
-                                      dns_rpz_update_taskaction, rpz, rpz,
+                                      dns_rpz_update_taskaction, zone, zone,
                                       NULL, NULL);
-                       event = &rpz->updateevent;
-                       isc_task_send(rpz->rpzs->updater, &event);
+                       event = &zone->updateevent;
+                       isc_task_send(zone->rpzs->updater, &event);
                }
        } else {
-               rpz->updatepending = true;
-               dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE);
+               zone->updatepending = true;
+               dns_name_format(&zone->origin, dname, DNS_NAME_FORMATSIZE);
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3),
                              "rpz: %s: update already queued or running",
                              dname);
-               if (rpz->dbversion != NULL) {
-                       dns_db_closeversion(rpz->db, &rpz->dbversion, false);
+               if (zone->dbversion != NULL) {
+                       dns_db_closeversion(zone->db, &zone->dbversion, false);
                }
-               dns_db_currentversion(rpz->db, &rpz->dbversion);
+               dns_db_currentversion(zone->db, &zone->dbversion);
        }
 
 cleanup:
-       UNLOCK(&rpz->rpzs->maint_lock);
+       UNLOCK(&zone->rpzs->maint_lock);
 
        return (result);
 }
@@ -1648,24 +1666,24 @@ cleanup:
 static void
 dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event) {
        isc_result_t result;
-       dns_rpz_zone_t *rpz;
+       dns_rpz_zone_t *zone;
 
        REQUIRE(event != NULL);
        REQUIRE(event->ev_arg != NULL);
 
        UNUSED(task);
-       rpz = (dns_rpz_zone_t *)event->ev_arg;
+       zone = (dns_rpz_zone_t *)event->ev_arg;
        isc_event_free(&event);
-       LOCK(&rpz->rpzs->maint_lock);
-       rpz->updatepending = false;
-       rpz->updaterunning = true;
-       dns_rpz_update_from_db(rpz);
-       result = isc_timer_reset(rpz->updatetimer, isc_timertype_inactive, NULL,
-                                NULL, true);
+       LOCK(&zone->rpzs->maint_lock);
+       zone->updatepending = false;
+       zone->updaterunning = true;
+       dns_rpz_update_from_db(zone);
+       result = isc_timer_reset(zone->updatetimer, isc_timertype_inactive,
+                                NULL, NULL, true);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
-       result = isc_time_now(&rpz->lastupdated);
+       result = isc_time_now(&zone->lastupdated);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
-       UNLOCK(&rpz->rpzs->maint_lock);
+       UNLOCK(&zone->rpzs->maint_lock);
 }
 
 static isc_result_t
@@ -2064,8 +2082,7 @@ dns_rpz_update_from_db(dns_rpz_zone_t *rpz) {
        REQUIRE(rpz->updbit == NULL);
        REQUIRE(rpz->newnodes == NULL);
 
-       rpz_attach(rpz, &(dns_rpz_zone_t *){ NULL });
-
+       isc_refcount_increment(&rpz->refs);
        dns_db_attach(rpz->db, &rpz->updb);
        rpz->updbversion = rpz->dbversion;
        rpz->dbversion = NULL;
@@ -2128,84 +2145,6 @@ cidr_free(dns_rpz_zones_t *rpzs) {
        }
 }
 
-static void
-rpz_attach(dns_rpz_zone_t *rpz, dns_rpz_zone_t **rpzp) {
-       REQUIRE(rpz != NULL);
-       REQUIRE(rpzp != NULL && *rpzp == NULL);
-
-       isc_refcount_increment(&rpz->refs);
-       *rpzp = rpz;
-}
-
-static void
-rpz_destroy(dns_rpz_zone_t *rpz) {
-       dns_rpz_zones_t *rpzs = rpz->rpzs;
-       rpz->rpzs = NULL;
-
-       isc_refcount_destroy(&rpz->refs);
-
-       if (dns_name_dynamic(&rpz->origin)) {
-               dns_name_free(&rpz->origin, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->client_ip)) {
-               dns_name_free(&rpz->client_ip, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->ip)) {
-               dns_name_free(&rpz->ip, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->nsdname)) {
-               dns_name_free(&rpz->nsdname, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->nsip)) {
-               dns_name_free(&rpz->nsip, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->passthru)) {
-               dns_name_free(&rpz->passthru, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->drop)) {
-               dns_name_free(&rpz->drop, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->tcp_only)) {
-               dns_name_free(&rpz->tcp_only, rpzs->mctx);
-       }
-       if (dns_name_dynamic(&rpz->cname)) {
-               dns_name_free(&rpz->cname, rpzs->mctx);
-       }
-       if (rpz->db != NULL) {
-               if (rpz->dbversion != NULL) {
-                       dns_db_closeversion(rpz->db, &rpz->dbversion, false);
-               }
-               dns_db_updatenotify_unregister(rpz->db,
-                                              dns_rpz_dbupdate_callback, rpz);
-               dns_db_detach(&rpz->db);
-       }
-       if (rpz->updaterunning) {
-               isc_task_purgeevent(rpzs->updater, &rpz->updateevent);
-               if (rpz->updbit != NULL) {
-                       dns_dbiterator_destroy(&rpz->updbit);
-               }
-               if (rpz->newnodes != NULL) {
-                       isc_ht_destroy(&rpz->newnodes);
-               }
-               if (rpz->updb != NULL) {
-                       if (rpz->updbversion != NULL) {
-                               dns_db_closeversion(rpz->updb,
-                                                   &rpz->updbversion, false);
-                       }
-                       dns_db_detach(&rpz->updb);
-               }
-       }
-
-       isc_timer_reset(rpz->updatetimer, isc_timertype_inactive, NULL, NULL,
-                       true);
-       isc_timer_detach(&rpz->updatetimer);
-
-       isc_ht_destroy(&rpz->nodes);
-
-       isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
-       rpz_detach_rpzs(&rpzs);
-}
-
 /*
  * Discard a response policy zone blob
  * before discarding the overall rpz structure.
@@ -2213,6 +2152,7 @@ rpz_destroy(dns_rpz_zone_t *rpz) {
 static void
 rpz_detach(dns_rpz_zone_t **rpzp) {
        dns_rpz_zone_t *rpz;
+       dns_rpz_zones_t *rpzs;
 
        REQUIRE(rpzp != NULL && *rpzp != NULL);
 
@@ -2220,7 +2160,73 @@ rpz_detach(dns_rpz_zone_t **rpzp) {
        *rpzp = NULL;
 
        if (isc_refcount_decrement(&rpz->refs) == 1) {
-               rpz_destroy(rpz);
+               isc_refcount_destroy(&rpz->refs);
+
+               rpzs = rpz->rpzs;
+               rpz->rpzs = NULL;
+
+               if (dns_name_dynamic(&rpz->origin)) {
+                       dns_name_free(&rpz->origin, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->client_ip)) {
+                       dns_name_free(&rpz->client_ip, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->ip)) {
+                       dns_name_free(&rpz->ip, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->nsdname)) {
+                       dns_name_free(&rpz->nsdname, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->nsip)) {
+                       dns_name_free(&rpz->nsip, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->passthru)) {
+                       dns_name_free(&rpz->passthru, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->drop)) {
+                       dns_name_free(&rpz->drop, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->tcp_only)) {
+                       dns_name_free(&rpz->tcp_only, rpzs->mctx);
+               }
+               if (dns_name_dynamic(&rpz->cname)) {
+                       dns_name_free(&rpz->cname, rpzs->mctx);
+               }
+               if (rpz->db != NULL) {
+                       if (rpz->dbversion != NULL) {
+                               dns_db_closeversion(rpz->db, &rpz->dbversion,
+                                                   false);
+                       }
+                       dns_db_updatenotify_unregister(
+                               rpz->db, dns_rpz_dbupdate_callback, rpz);
+                       dns_db_detach(&rpz->db);
+               }
+               if (rpz->updaterunning) {
+                       isc_task_purgeevent(rpzs->updater, &rpz->updateevent);
+                       if (rpz->updbit != NULL) {
+                               dns_dbiterator_destroy(&rpz->updbit);
+                       }
+                       if (rpz->newnodes != NULL) {
+                               isc_ht_destroy(&rpz->newnodes);
+                       }
+                       if (rpz->updb != NULL) {
+                               if (rpz->updbversion != NULL) {
+                                       dns_db_closeversion(rpz->updb,
+                                                           &rpz->updbversion,
+                                                           false);
+                               }
+                               dns_db_detach(&rpz->updb);
+                       }
+               }
+
+               isc_timer_reset(rpz->updatetimer, isc_timertype_inactive, NULL,
+                               NULL, true);
+               isc_timer_detach(&rpz->updatetimer);
+
+               isc_ht_destroy(&rpz->nodes);
+
+               isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
+               rpz_detach_rpzs(&rpzs);
        }
 }
 
@@ -2260,44 +2266,56 @@ dns_rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) {
 }
 
 static void
-rpz_attach_rpzs(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **rpzsp) {
-       REQUIRE(rpzs != NULL);
-       REQUIRE(rpzsp != NULL && *rpzsp == NULL);
-
-       isc_refcount_increment(&rpzs->irefs);
-
-       *rpzsp = rpzs;
-}
+rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) {
+       REQUIRE(rpzsp != NULL && *rpzsp != NULL);
+       dns_rpz_zones_t *rpzs = *rpzsp;
+       *rpzsp = NULL;
 
-static void
-rpz_destroy_rpzs(dns_rpz_zones_t *rpzs) {
-       if (rpzs->rps_cstr_size != 0) {
+       if (isc_refcount_decrement(&rpzs->irefs) == 1) {
+               if (rpzs->rps_cstr_size != 0) {
 #ifdef USE_DNSRPS
-               librpz->client_detach(&rpzs->rps_client);
+                       librpz->client_detach(&rpzs->rps_client);
 #endif /* ifdef USE_DNSRPS */
-               isc_mem_put(rpzs->mctx, rpzs->rps_cstr, rpzs->rps_cstr_size);
-       }
+                       isc_mem_put(rpzs->mctx, rpzs->rps_cstr,
+                                   rpzs->rps_cstr_size);
+               }
 
-       cidr_free(rpzs);
-       if (rpzs->rbt != NULL) {
-               dns_rbt_destroy(&rpzs->rbt);
+               cidr_free(rpzs);
+               if (rpzs->rbt != NULL) {
+                       dns_rbt_destroy(&rpzs->rbt);
+               }
+               isc_task_destroy(&rpzs->updater);
+               isc_mutex_destroy(&rpzs->maint_lock);
+               isc_rwlock_destroy(&rpzs->search_lock);
+               isc_refcount_destroy(&rpzs->refs);
+               isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs));
        }
-       isc_task_destroy(&rpzs->updater);
-       isc_mutex_destroy(&rpzs->maint_lock);
-       isc_rwlock_destroy(&rpzs->search_lock);
-       isc_refcount_destroy(&rpzs->refs);
-       isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs));
 }
 
-static void
-rpz_detach_rpzs(dns_rpz_zones_t **rpzsp) {
-       REQUIRE(rpzsp != NULL && *rpzsp != NULL);
-       dns_rpz_zones_t *rpzs = *rpzsp;
-       *rpzsp = NULL;
+/*
+ * Deprecated and removed.
+ */
+isc_result_t
+dns_rpz_beginload(dns_rpz_zones_t **load_rpzsp, dns_rpz_zones_t *rpzs,
+                 dns_rpz_num_t rpz_num) {
+       UNUSED(load_rpzsp);
+       UNUSED(rpzs);
+       UNUSED(rpz_num);
 
-       if (isc_refcount_decrement(&rpzs->irefs) == 1) {
-               rpz_destroy_rpzs(rpzs);
-       }
+       return (ISC_R_NOTIMPLEMENTED);
+}
+
+/*
+ * Deprecated and removed.
+ */
+isc_result_t
+dns_rpz_ready(dns_rpz_zones_t *rpzs, dns_rpz_zones_t **load_rpzsp,
+             dns_rpz_num_t rpz_num) {
+       UNUSED(rpzs);
+       UNUSED(load_rpzsp);
+       UNUSED(rpz_num);
+
+       return (ISC_R_NOTIMPLEMENTED);
 }
 
 /*