]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add a function to set NOTIFY(CDS) endpoints
authorMatthijs Mekking <matthijs@isc.org>
Thu, 30 Oct 2025 08:17:32 +0000 (09:17 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 19 Dec 2025 13:08:15 +0000 (14:08 +0100)
This is similar to setting remote endpoints for primaries, secondaries
(NOTIFY(SOA)), and parental agents.

lib/dns/include/dns/zone.h
lib/dns/zone.c

index ef95a57243b75e360956b31f59dcf63f707fc17c..11a9daed4ce0575b1bdf8c77548c4cf10f9f5651 100644 (file)
@@ -682,6 +682,20 @@ dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses,
  *\li  'count' to be the number of notifiees.
  */
 
+void
+dns_zone_setcdsendpoints(dns_zone_t *zone, isc_sockaddr_t *addresses,
+                        isc_sockaddr_t *sources, dns_name_t **keynames,
+                        dns_name_t **tlsnames, uint32_t count);
+/*%<
+ *     Set the list of servers to be notified when the zone changes
+ *     its CDS/CDNSKEY RRset. To clear the list use 'count = 0'.
+ *
+ * Require:
+ *\li  'zone' to be a valid zone.
+ *\li  'addresses' to be non-NULL if count != 0.
+ *\li  'count' to be the number of notifiees.
+ */
+
 void
 dns_zone_unload(dns_zone_t *zone);
 /*%<
index ee632cef0a77900d569382342e4ace0c500d999c..71df6192a3164971b652c922ca4f0fff3e168ffa 100644 (file)
@@ -341,6 +341,8 @@ struct dns_zone {
 
        dns_remote_t alsonotify;
        dns_notifyctx_t notifysoa;
+
+       dns_remote_t cds_endpoints;
        dns_notifyctx_t notifycds;
 
        isc_sockaddr_t parentalsrc4;
@@ -1102,6 +1104,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, isc_tid_t tid) {
        zone->primaries = r;
        zone->parentals = r;
        zone->alsonotify = r;
+       zone->cds_endpoints = r;
        zone->defaultkasp = NULL;
        ISC_LIST_INIT(zone->keyring);
 
@@ -1240,6 +1243,7 @@ dns__zone_free(dns_zone_t *zone) {
        dns_zone_setparentals(zone, NULL, NULL, NULL, NULL, 0);
        dns_zone_setprimaries(zone, NULL, NULL, NULL, NULL, 0);
        dns_zone_setalsonotify(zone, NULL, NULL, NULL, NULL, 0);
+       dns_zone_setcdsendpoints(zone, NULL, NULL, NULL, NULL, 0);
 
        zone->check_names = dns_severity_ignore;
        if (zone->update_acl != NULL) {
@@ -6389,46 +6393,6 @@ dns_zone_getnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc) {
        UNLOCK_ZONE(zone);
 }
 
-void
-dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses,
-                      isc_sockaddr_t *sources, dns_name_t **keynames,
-                      dns_name_t **tlsnames, uint32_t count) {
-       dns_remote_t remote;
-
-       REQUIRE(DNS_ZONE_VALID(zone));
-
-       LOCK_ZONE(zone);
-
-       remote.magic = DNS_REMOTE_MAGIC;
-       remote.addresses = addresses;
-       remote.sources = sources;
-       remote.keynames = keynames;
-       remote.tlsnames = tlsnames;
-       remote.addrcnt = count;
-
-       if (dns_remote_equal(&zone->alsonotify, &remote)) {
-               goto unlock;
-       }
-
-       dns_remote_clear(&zone->alsonotify);
-
-       /*
-        * If count == 0, don't allocate any space for servers to notify.
-        */
-       if (count == 0) {
-               goto unlock;
-       }
-
-       /*
-        * Now set up the notify address and key lists.
-        */
-       dns_remote_init(&zone->alsonotify, count, addresses, sources, keynames,
-                       tlsnames, true, zone->mctx);
-
-unlock:
-       UNLOCK_ZONE(zone);
-}
-
 static bool
 has_pf(isc_sockaddr_t *addresses, size_t count, int pf) {
        for (size_t i = 0; i < count; i++) {
@@ -6455,101 +6419,107 @@ report_no_active_addresses(dns_zone_t *zone, isc_sockaddr_t *addresses,
        }
 }
 
-void
-dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses,
-                     isc_sockaddr_t *sources, dns_name_t **keynames,
-                     dns_name_t **tlsnames, uint32_t count) {
-       dns_remote_t remote;
+static void
+setremote(dns_zone_t *zone, dns_remote_t *remote, const char *remotestr,
+         isc_sockaddr_t *addresses, isc_sockaddr_t *sources,
+         dns_name_t **keynames, dns_name_t **tlsnames, bool refresh,
+         bool report, uint32_t count) {
+       dns_remote_t newremote;
 
        REQUIRE(DNS_ZONE_VALID(zone));
+       REQUIRE(DNS_REMOTE_VALID(remote));
 
-       LOCK_ZONE(zone);
+       newremote.magic = DNS_REMOTE_MAGIC;
+       newremote.addresses = addresses;
+       newremote.sources = sources;
+       newremote.keynames = keynames;
+       newremote.tlsnames = tlsnames;
+       newremote.addrcnt = count;
 
-       remote.magic = DNS_REMOTE_MAGIC;
-       remote.addresses = addresses;
-       remote.sources = sources;
-       remote.keynames = keynames;
-       remote.tlsnames = tlsnames;
-       remote.addrcnt = count;
+       if (dns_remote_equal(remote, &newremote)) {
+               return;
+       }
 
        /*
-        * The refresh code assumes that 'primaries' wouldn't change under it.
+        * The refresh code assumes that 'servers' wouldn't change under it.
         * If it will change then kill off any current refresh in progress
         * and update the primaries info.  If it won't change then we can just
         * unlock and exit.
         */
-       if (!dns_remote_equal(&zone->primaries, &remote)) {
-               if (zone->request != NULL) {
-                       dns_request_cancel(zone->request);
-               }
-       } else {
-               goto unlock;
+       if (zone->request != NULL && refresh) {
+               dns_request_cancel(zone->request);
        }
 
-       dns_remote_clear(&zone->primaries);
+       dns_remote_clear(remote);
 
        /*
-        * If count == 0, don't allocate any space for primaries.
+        * If count == 0, don't allocate any space for servers.
         */
        if (count == 0) {
-               goto unlock;
+               return;
        }
 
-       report_no_active_addresses(zone, addresses, count, "primaries");
-
        /*
-        * Now set up the primaries and primary key lists.
+        * Now set up the address and key lists.
         */
-       dns_remote_init(&zone->primaries, count, addresses, sources, keynames,
-                       tlsnames, true, zone->mctx);
+       if (report) {
+               report_no_active_addresses(zone, addresses, count, remotestr);
+       }
 
-       DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES);
+       dns_remote_init(remote, count, addresses, sources, keynames, tlsnames,
+                       true, zone->mctx);
+}
 
-unlock:
+void
+dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses,
+                      isc_sockaddr_t *sources, dns_name_t **keynames,
+                      dns_name_t **tlsnames, uint32_t count) {
+       bool refresh = false;
+       bool report = false;
+
+       LOCK_ZONE(zone);
+       setremote(zone, &zone->alsonotify, "also-notify", addresses, sources,
+                 keynames, tlsnames, refresh, report, count);
        UNLOCK_ZONE(zone);
 }
 
 void
-dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses,
+dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses,
                      isc_sockaddr_t *sources, dns_name_t **keynames,
                      dns_name_t **tlsnames, uint32_t count) {
-       dns_remote_t remote;
-
-       REQUIRE(DNS_ZONE_VALID(zone));
+       bool refresh = true;
+       bool report = true;
 
        LOCK_ZONE(zone);
+       setremote(zone, &zone->primaries, "primaries", addresses, sources,
+                 keynames, tlsnames, refresh, report, count);
+       DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES);
+       UNLOCK_ZONE(zone);
+}
 
-       remote.magic = DNS_REMOTE_MAGIC;
-       remote.addresses = addresses;
-       remote.sources = sources;
-       remote.keynames = keynames;
-       remote.tlsnames = tlsnames;
-       remote.addrcnt = count;
-
-       if (dns_remote_equal(&zone->parentals, &remote)) {
-               goto unlock;
-       }
-
-       dns_remote_clear(&zone->parentals);
-
-       /*
-        * If count == 0, don't allocate any space for parentals.
-        */
-       if (count == 0) {
-               goto unlock;
-       }
-
-       report_no_active_addresses(zone, addresses, count, "parental-agents");
+void
+dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses,
+                     isc_sockaddr_t *sources, dns_name_t **keynames,
+                     dns_name_t **tlsnames, uint32_t count) {
+       bool refresh = false;
+       bool report = true;
 
-       /*
-        * Now set up the parentals and parental key lists.
-        */
-       dns_remote_init(&zone->parentals, count, addresses, sources, keynames,
-                       tlsnames, true, zone->mctx);
+       LOCK_ZONE(zone);
+       setremote(zone, &zone->parentals, "parental-agents", addresses, sources,
+                 keynames, tlsnames, refresh, report, count);
+       UNLOCK_ZONE(zone);
+}
 
-       dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count);
+void
+dns_zone_setcdsendpoints(dns_zone_t *zone, isc_sockaddr_t *addresses,
+                        isc_sockaddr_t *sources, dns_name_t **keynames,
+                        dns_name_t **tlsnames, uint32_t count) {
+       bool refresh = false;
+       bool report = false;
 
-unlock:
+       LOCK_ZONE(zone);
+       setremote(zone, &zone->cds_endpoints, "cds-endpoints", addresses,
+                 sources, keynames, tlsnames, refresh, report, count);
        UNLOCK_ZONE(zone);
 }