Lines Matching refs:catz
1 /* $NetBSD: catz.c,v 1.18 2026/06/19 20:09:59 christos Exp $ */
33 #include <dns/catz.h>
44 #define DNS_CATZ_ZONE_VALID(catz) ISC_MAGIC_VALID(catz, DNS_CATZ_ZONE_MAGIC)
113 dns__catz_timer_start(dns_catz_zone_t *catz);
123 catz_process_zones_entry(dns_catz_zone_t *catz, dns_rdataset_t *value,
126 catz_process_zones_suboption(dns_catz_zone_t *catz, dns_rdataset_t *value,
129 catz_entry_add_or_mod(dns_catz_zone_t *catz, isc_ht_t *ht, unsigned char *key,
265 catz_coo_detach(dns_catz_zone_t *catz, dns_catz_coo_t **coop) {
268 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
274 isc_mem_t *mctx = catz->catzs->mctx;
285 catz_coo_add(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
287 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
293 isc_result_t result = isc_ht_find(catz->coos, entry->name.ndata,
296 coo = catz_coo_new(catz->catzs->mctx, domain);
297 result = isc_ht_add(catz->coos, entry->name.ndata,
330 dns_catz_entry_copy(dns_catz_zone_t *catz, const dns_catz_entry_t *entry) {
331 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
334 dns_catz_entry_t *nentry = dns_catz_entry_new(catz->catzs->mctx,
337 dns_catz_options_copy(catz->catzs->mctx, &entry->opts, &nentry->opts);
352 dns_catz_entry_detach(dns_catz_zone_t *catz, dns_catz_entry_t **entryp) {
355 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
361 isc_mem_t *mctx = catz->catzs->mctx;
466 dns_catz_zone_getname(dns_catz_zone_t *catz) {
467 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
469 return &catz->name;
473 dns_catz_zone_getdefoptions(dns_catz_zone_t *catz) {
474 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
476 return &catz->defoptions;
480 dns_catz_zone_resetdefoptions(dns_catz_zone_t *catz) {
481 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
483 dns_catz_options_free(&catz->defoptions, catz->catzs->mctx);
484 dns_catz_options_init(&catz->defoptions);
488 * Merge 'newcatz' into 'catz', calling addzone/delzone/modzone
489 * (from catz->catzs->zmm) for appropriate member zones.
492 * \li 'catz' is a valid dns_catz_zone_t.
497 dns__catz_zones_merge(dns_catz_zone_t *catz, dns_catz_zone_t *newcatz) {
507 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
510 LOCK(&catz->lock);
514 addzone = catz->catzs->zmm->addzone;
515 modzone = catz->catzs->zmm->modzone;
516 delzone = catz->catzs->zmm->delzone;
518 /* Copy zoneoptions from newcatz into catz. */
520 dns_catz_options_free(&catz->zoneoptions, catz->catzs->mctx);
521 dns_catz_options_copy(catz->catzs->mctx, &newcatz->zoneoptions,
522 &catz->zoneoptions);
523 dns_catz_options_setdefault(catz->catzs->mctx, &catz->defoptions,
524 &catz->zoneoptions);
526 dns_name_format(&catz->name, czname, DNS_NAME_FORMATSIZE);
528 isc_ht_init(&toadd, catz->catzs->mctx, 1, ISC_HT_CASE_INSENSITIVE);
529 isc_ht_init(&tomod, catz->catzs->mctx, 1, ISC_HT_CASE_INSENSITIVE);
531 isc_ht_iter_create(catz->entries, &iter2);
575 "catz: iterating over '%s' from catalog '%s'",
577 dns_catz_options_setdefault(catz->catzs->mctx,
578 &catz->zoneoptions, &nentry->opts);
581 find_result = dns_view_findzone(catz->catzs->view,
593 if (parentcatz != NULL && parentcatz != catz) {
594 UNLOCK(&catz->lock);
602 dns_name_equal(&coo->name, &catz->name))
609 "catz: zone '%s' "
619 "catz: deleting zone '%s' "
626 LOCK(&catz->lock);
632 result = isc_ht_find(catz->entries, key, (uint32_t)keysize,
635 if (find_result == ISC_R_SUCCESS && parentcatz == catz)
652 "catz: zone '%s' unique label "
657 catz_entry_add_or_mod(catz, toadd, key, keysize, nentry,
665 "catz: zone '%s' was expected to exist "
668 catz_entry_add_or_mod(catz, toadd, key, keysize, nentry,
674 catz_entry_add_or_mod(catz, tomod, key, keysize, nentry,
684 dns_catz_entry_detach(catz, &oentry);
685 result = isc_ht_delete(catz->entries, key, (uint32_t)keysize);
701 result = delzone(entry, catz, catz->catzs->view,
702 catz->catzs->zmm->udata);
705 "catz: deleting zone '%s' from catalog '%s' - %s",
707 dns_catz_entry_detach(catz, &entry);
711 /* At this moment catz->entries has to be empty. */
712 INSIST(isc_ht_count(catz->entries) == 0);
713 isc_ht_destroy(&catz->entries);
722 result = addzone(entry, catz, catz->catzs->view,
723 catz->catzs->zmm->udata);
726 "catz: adding zone '%s' from catalog "
738 result = modzone(entry, catz, catz->catzs->view,
739 catz->catzs->zmm->udata);
742 "catz: modifying zone '%s' from catalog "
747 catz->entries = newcatz->entries;
754 if (catz->coos != NULL && newcatz->coos != NULL) {
757 isc_ht_iter_create(catz->coos, &iter);
764 catz_coo_detach(catz, &coo);
770 INSIST(isc_ht_count(catz->coos) == 0);
771 isc_ht_destroy(&catz->coos);
773 catz->coos = newcatz->coos;
784 UNLOCK(&catz->lock);
836 dns_catz_zone_t *catz = isc_mem_get(catzs->mctx, sizeof(*catz));
837 *catz = (dns_catz_zone_t){ .active = true,
841 dns_catz_zones_attach(catzs, &catz->catzs);
842 isc_mutex_init(&catz->lock);
843 isc_refcount_init(&catz->references, 1);
844 isc_ht_init(&catz->entries, catzs->mctx, 4, ISC_HT_CASE_INSENSITIVE);
845 isc_ht_init(&catz->coos, catzs->mctx, 4, ISC_HT_CASE_INSENSITIVE);
846 isc_time_settoepoch(&catz->lastupdated);
847 dns_catz_options_init(&catz->defoptions);
848 dns_catz_options_init(&catz->zoneoptions);
849 dns_name_init(&catz->name, NULL);
850 dns_name_dup(name, catzs->mctx, &catz->name);
852 return catz;
856 dns__catz_timer_start(dns_catz_zone_t *catz) {
861 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
864 tdiff = isc_time_microdiff(&now, &catz->lastupdated) / 1000000;
865 if (tdiff < catz->defoptions.min_update_interval) {
866 uint64_t defer = catz->defoptions.min_update_interval - tdiff;
869 dns_name_format(&catz->name, dname, DNS_NAME_FORMATSIZE);
872 "catz: %s: new zone version came "
881 catz->loop = isc_loop();
883 isc_timer_create(catz->loop, dns__catz_timer_cb, catz,
884 &catz->updatetimer);
885 isc_timer_start(catz->updatetimer, isc_timertype_once, &interval);
890 dns_catz_zone_t *catz = arg;
891 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
893 isc_timer_stop(catz->updatetimer);
894 isc_timer_destroy(&catz->updatetimer);
895 catz->loop = NULL;
897 dns_catz_zone_detach(&catz);
907 dns_catz_zone_t *catz = NULL;
913 ISC_LOG_DEBUG(3), "catz: dns_catz_zone_add %s", zname);
925 (void **)&catz);
928 INSIST(!catz->active);
929 catz->active = true;
933 catz = dns_catz_zone_new(catzs, name);
935 result = isc_ht_add(catzs->zones, catz->name.ndata,
936 catz->name.length, catz);
945 *catzp = catz;
974 dns__catz_zone_shutdown(dns_catz_zone_t *catz) {
976 if (catz->updatetimer != NULL) {
978 INSIST(catz->loop != NULL);
980 isc_async_run(catz->loop, dns__catz_timer_stop, catz);
982 dns_catz_zone_detach(&catz);
987 dns__catz_zone_destroy(dns_catz_zone_t *catz) {
988 isc_mem_t *mctx = catz->catzs->mctx;
990 if (catz->entries != NULL) {
993 isc_ht_iter_create(catz->entries, &iter);
1000 dns_catz_entry_detach(catz, &entry);
1006 INSIST(isc_ht_count(catz->entries) == 0);
1007 isc_ht_destroy(&catz->entries);
1009 if (catz->coos != NULL) {
1012 isc_ht_iter_create(catz->coos, &iter);
1019 catz_coo_detach(catz, &coo);
1025 INSIST(isc_ht_count(catz->coos) == 0);
1026 isc_ht_destroy(&catz->coos);
1028 catz->magic = 0;
1029 isc_mutex_destroy(&catz->lock);
1031 if (catz->updatetimer != NULL) {
1032 isc_timer_async_destroy(&catz->updatetimer);
1035 if (catz->db != NULL) {
1036 if (catz->dbversion != NULL) {
1037 dns_db_closeversion(catz->db, &catz->dbversion, false);
1040 catz->db, dns_catz_dbupdate_callback, catz->catzs);
1041 dns_db_detach(&catz->db);
1044 INSIST(!catz->updaterunning);
1046 dns_name_free(&catz->name, mctx);
1047 dns_catz_options_free(&catz->defoptions, mctx);
1048 dns_catz_options_free(&catz->zoneoptions, mctx);
1050 dns_catz_zones_detach(&catz->catzs);
1052 isc_mem_put(mctx, catz, sizeof(*catz));
1085 dns_catz_zone_t *catz = NULL;
1086 isc_ht_iter_current(iter, (void **)&catz);
1088 dns__catz_zone_shutdown(catz);
1111 CATZ_OPT_CUSTOM_START, /* CATZ custom properties must go below this */
1155 catz_process_zones(dns_catz_zone_t *catz, dns_rdataset_t *value,
1160 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1171 return catz_process_zones_entry(catz, value, &mhash);
1175 return catz_process_zones_suboption(catz, value, &mhash, &opt);
1180 catz_process_coo(dns_catz_zone_t *catz, dns_label_t *mhash,
1187 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1192 if (catz->version < 2) {
1203 "catz: 'coo' property PTR RRset contains "
1205 catz->broken = true;
1227 result = isc_ht_find(catz->entries, mhash->base, mhash->length,
1239 catz_coo_add(catz, entry, &ptr.ptr);
1248 catz_process_zones_entry(dns_catz_zone_t *catz, dns_rdataset_t *value,
1262 "catz: member zone PTR RRset contains "
1264 catz->broken = true;
1281 result = isc_ht_find(catz->entries, mhash->base, mhash->length,
1289 dns_name_dup(&ptr.ptr, catz->catzs->mctx, &entry->name);
1292 entry = dns_catz_entry_new(catz->catzs->mctx, &ptr.ptr);
1294 result = isc_ht_add(catz->entries, mhash->base, mhash->length,
1305 catz_process_version(dns_catz_zone_t *catz, dns_rdataset_t *value) {
1313 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1323 "catz: 'version' property TXT RRset contains "
1325 catz->broken = true;
1367 catz->version = tversion;
1375 "catz: invalid record for the catalog "
1377 catz->broken = true;
1383 catz_process_primaries(dns_catz_zone_t *catz, dns_ipkeylist_t *ipkl,
1397 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1403 mctx = catz->catzs->mctx;
1572 catz_process_apl(dns_catz_zone_t *catz, isc_buffer_t **aclbp,
1581 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1596 "catz: more than one APL entry for member zone, "
1603 result = dns_rdata_tostruct(&rdata, &rdata_apl, catz->catzs->mctx);
1607 isc_buffer_allocate(catz->catzs->mctx, &aclb, 16);
1654 catz_process_zones_suboption(dns_catz_zone_t *catz, dns_rdataset_t *value,
1663 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1678 if (catz->version >= 2 && opt >= CATZ_OPT_CUSTOM_START) {
1691 result = isc_ht_find(catz->entries, mhash->base, mhash->length,
1694 entry = dns_catz_entry_new(catz->catzs->mctx, NULL);
1695 result = isc_ht_add(catz->entries, mhash->base, mhash->length,
1704 return catz_process_coo(catz, mhash, value);
1706 return catz_process_primaries(catz, &entry->opts.masters, value,
1712 return catz_process_apl(catz, &entry->opts.allow_query, value);
1717 return catz_process_apl(catz, &entry->opts.allow_transfer,
1727 catz_entry_add_or_mod(dns_catz_zone_t *catz, isc_ht_t *ht, unsigned char *key,
1736 "catz: error %s zone '%s' from catalog '%s' - %s",
1740 dns_catz_entry_detach(catz, &oentry);
1741 result = isc_ht_delete(catz->entries, key, (uint32_t)keysize);
1747 catz_process_value(dns_catz_zone_t *catz, dns_name_t *name,
1754 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1768 if (catz->version >= 2 && opt >= CATZ_OPT_CUSTOM_START) {
1782 return catz_process_zones(catz, rdataset, &prefix);
1784 return catz_process_primaries(catz, &catz->zoneoptions.masters,
1790 return catz_process_apl(catz, &catz->zoneoptions.allow_query,
1796 return catz_process_apl(catz, &catz->zoneoptions.allow_transfer,
1802 return catz_process_version(catz, rdataset);
1809 * Process a single rdataset from a catalog zone 'catz' update, src_name is the
1813 * \li 'catz' is a valid dns_catz_zone_t.
1818 dns__catz_update_process(dns_catz_zone_t *catz, const dns_name_t *src_name,
1828 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1834 "catz: RR found which has a non-IN class");
1835 catz->broken = true;
1839 nrres = dns_name_fullcompare(src_name, &catz->name, &order, &nlabels);
1866 dns_name_split(src_name, catz->name.labels, &prefix, NULL);
1867 result = catz_process_value(catz, &prefix, rdataset);
1887 dns_catz_generate_masterfilename(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
1895 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
1899 isc_buffer_allocate(catz->catzs->mctx, &tbuf,
1900 strlen(catz->catzs->view->name) +
1903 isc_buffer_putstr(tbuf, catz->catzs->view->name);
1905 result = dns_name_totext(&catz->name, DNS_NAME_OMITFINALDOT, tbuf);
1983 dns_catz_generate_zonecfg(dns_catz_zone_t *catz, dns_catz_entry_t *entry,
1993 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
2001 isc_buffer_allocate(catz->catzs->mctx, &buffer, ISC_BUFFER_INCR);
2021 "catz: zone '%s' uses an invalid primary "
2056 result = dns_catz_generate_masterfilename(catz, entry, &buffer);
2088 dns_catz_zone_t *catz = (dns_catz_zone_t *)arg;
2090 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
2092 if (atomic_load(&catz->catzs->shuttingdown)) {
2096 LOCK(&catz->catzs->lock);
2098 INSIST(DNS_DB_VALID(catz->db));
2099 INSIST(catz->dbversion != NULL);
2100 INSIST(catz->updb == NULL);
2101 INSIST(catz->updbversion == NULL);
2103 catz->updatepending = false;
2104 catz->updaterunning = true;
2105 catz->updateresult = ISC_R_UNSET;
2107 dns_name_format(&catz->name, domain, DNS_NAME_FORMATSIZE);
2109 if (!catz->active) {
2112 "catz: %s: no longer active, reload is canceled",
2114 catz->updaterunning = false;
2115 catz->updateresult = ISC_R_CANCELED;
2119 dns_db_attach(catz->db, &catz->updb);
2120 catz->updbversion = catz->dbversion;
2121 catz->dbversion = NULL;
2124 ISC_LOG_INFO, "catz: %s: reload start", domain);
2126 dns_catz_zone_ref(catz);
2127 isc_work_enqueue(catz->loop, dns__catz_update_cb, dns__catz_done_cb,
2128 catz);
2131 isc_timer_destroy(&catz->updatetimer);
2132 catz->loop = NULL;
2134 catz->lastupdated = isc_time_now();
2136 UNLOCK(&catz->catzs->lock);
2142 dns_catz_zone_t *catz = NULL;
2161 result = isc_ht_find(catzs->zones, r.base, r.length, (void **)&catz);
2167 if (catz->db != NULL && catz->db != db) {
2169 if (catz->dbversion != NULL) {
2170 dns_db_closeversion(catz->db, &catz->dbversion, false);
2173 catz->db, dns_catz_dbupdate_callback, catz->catzs);
2174 dns_db_detach(&catz->db);
2176 if (catz->db == NULL) {
2178 dns_db_attach(db, &catz->db);
2180 catz->catzs);
2183 if (!catz->updatepending && !catz->updaterunning) {
2184 catz->updatepending = true;
2185 dns_db_currentversion(db, &catz->dbversion);
2186 dns__catz_timer_start(catz);
2190 catz->updatepending = true;
2191 dns_name_format(&catz->name, dname, DNS_NAME_FORMATSIZE);
2194 "catz: %s: update already queued or running",
2196 if (catz->dbversion != NULL) {
2197 dns_db_closeversion(catz->db, &catz->dbversion, false);
2199 dns_db_currentversion(catz->db, &catz->dbversion);
2232 * It creates a new catz, iterates over database to fill it with content, and
2233 * then merges new catz into old catz.
2237 dns_catz_zone_t *catz = (dns_catz_zone_t *)data;
2257 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
2258 REQUIRE(DNS_DB_VALID(catz->updb));
2259 REQUIRE(DNS_CATZ_ZONES_VALID(catz->catzs));
2261 updb = catz->updb;
2262 catzs = catz->catzs;
2272 * Create a new catz in the same context as current catz.
2288 "catz: zone '%s' not in config", bname);
2296 "catz: zone '%s' is no longer active", bname);
2306 "catz: zone '%s' has no SOA record (%s)", bname,
2313 "catz: updating catalog zone '%s' with serial %" PRIu32,
2320 "catz: failed to create DB iterator - %s",
2337 "catz: failed to create name from string - %s",
2347 "catz: zone '%s' has no 'version' record (%s) "
2369 "catz: failed to get db iterator - %s",
2392 "catz: failed to fetch rrdatasets - %s",
2437 "catz: invalid record in catalog "
2462 "catz: update_from_db: iteration finished: %s",
2474 "catz: zone '%s' version is not set", bname);
2479 "catz: zone '%s' unsupported version "
2491 "catz: new catalog zone '%s' is broken and "
2507 "catz: failed merging zones: %s",
2515 "catz: update_from_db: new zone merged");
2518 catz->updateresult = result;
2523 dns_catz_zone_t *catz = (dns_catz_zone_t *)data;
2526 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
2528 LOCK(&catz->catzs->lock);
2529 catz->updaterunning = false;
2531 dns_name_format(&catz->name, dname, DNS_NAME_FORMATSIZE);
2533 if (catz->updatepending && !atomic_load(&catz->catzs->shuttingdown)) {
2535 dns__catz_timer_start(catz);
2538 dns_db_closeversion(catz->updb, &catz->updbversion, false);
2539 dns_db_detach(&catz->updb);
2541 UNLOCK(&catz->catzs->lock);
2544 ISC_LOG_INFO, "catz: %s: reload done: %s", dname,
2545 isc_result_totext(catz->updateresult));
2547 dns_catz_zone_unref(catz);
2562 dns_catz_zone_t *catz = NULL;
2563 isc_ht_iter_current(iter, (void **)&catz);
2564 catz->active = false;
2582 dns_catz_zone_t *catz = NULL;
2584 isc_ht_iter_current(iter, (void **)&catz);
2585 if (!catz->active) {
2587 dns_name_format(&catz->name, cname,
2591 "catz: removing catalog zone %s", cname);
2597 newcatz = dns_catz_zone_new(catzs, &catz->name);
2598 dns__catz_zones_merge(catz, newcatz);
2602 INSIST(isc_ht_count(catz->entries) == 0);
2604 dns_catz_zone_detach(&catz);
2615 dns_catz_zone_prereconfig(dns_catz_zone_t *catz) {
2616 LOCK(&catz->lock);
2620 dns_catz_zone_postreconfig(dns_catz_zone_t *catz) {
2621 UNLOCK(&catz->lock);
2625 dns_catz_zone_for_each_entry2(dns_catz_zone_t *catz, dns_catz_entry_cb2 cb,
2627 REQUIRE(DNS_CATZ_ZONE_VALID(catz));
2632 LOCK(&catz->catzs->lock);
2633 isc_ht_iter_create(catz->entries, &iter);
2643 UNLOCK(&catz->catzs->lock);