chg: nil: change notify-cds to notify-cfg CDS

Change the notify configuration to be more flexible for other types of generalized DNS notifications.

Also allow for notify-cfg SOA.

Merge branch 'matthijs-notify-cfg' into 'main'

See merge request isc-projects/bind9!11384
This commit is contained in:
Matthijs Mekking 2025-12-29 09:41:43 +00:00
commit b47633ed42
19 changed files with 371 additions and 133 deletions

View file

@ -215,7 +215,6 @@ options {\n\
min-transfer-rate-in 10240 5;\n\
multi-master no;\n\
notify yes;\n\
notify-cds no;\n\
notify-defer 0;\n\
notify-delay 5;\n\
notify-to-soa no;\n\

View file

@ -62,6 +62,10 @@ typedef enum {
allow_update_forwarding
} acl_type_t;
#define MAPS_SIZE 6
#define NODEFAULT_MAPS_SIZE 5
#define NOOPTIONS_MAPS_SIZE 3
/*%
* Convenience function for configuring a single zone ACL.
*/
@ -71,7 +75,7 @@ configure_zone_acl(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
cfg_aclconfctx_t *aclctx, dns_zone_t *zone,
void (*setzacl)(dns_zone_t *, dns_acl_t *),
void (*clearzacl)(dns_zone_t *)) {
const cfg_obj_t *maps[6] = { 0 };
const cfg_obj_t *maps[MAPS_SIZE] = { 0 };
const cfg_obj_t *aclobj = NULL;
int i = 0;
dns_acl_t **aclp = NULL, *acl = NULL;
@ -819,8 +823,8 @@ isself(dns_view_t *myview, dns_tsigkey_t *mykey, const isc_sockaddr_t *srcaddr,
* default configuration.
*/
static dns_notifytype_t
process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
const char *zname, const cfg_obj_t **maps) {
process_notifysoatype(dns_notifytype_t ntype, dns_zonetype_t ztype,
const char *zname, const cfg_obj_t **maps) {
const cfg_obj_t *obj = NULL;
/*
@ -845,6 +849,105 @@ process_notifytype(dns_notifytype_t ntype, dns_zonetype_t ztype,
return dns_notifytype_explicit;
}
static void
process_notify_options(dns_rdatatype_t type, const cfg_obj_t **maps,
dns_zone_t *zone, dns_zone_t *raw, bool notifycfg) {
isc_result_t result;
const cfg_obj_t *obj = NULL;
/*
* "notify" for SOA is already inherited and set in
* named_zone_configure(), and for other types it can only be
* configured within "notify-cfg". Only look into first map
* to see if sending NOTIFY(type) messages are allowed.
*/
if (notifycfg) {
obj = NULL;
result = cfg_map_get(maps[0], "notify", &obj);
if (result == ISC_R_SUCCESS && obj != NULL) {
dns_zone_setnotifytype(zone, type,
cfg_obj_asboolean(obj));
} else {
dns_zone_setnotifytype(zone, type, dns_notifytype_no);
}
if (raw != NULL) {
dns_zone_setnotifytype(raw, type, dns_notifytype_no);
}
}
obj = NULL;
result = named_config_get(maps, "notify-delay", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifydelay(zone, type, cfg_obj_asuint32(obj));
obj = NULL;
result = named_config_get(maps, "notify-defer", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifydefer(zone, type, cfg_obj_asuint32(obj));
obj = NULL;
result = named_config_get(maps, "notify-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifysrc4(zone, type, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifysrc6(zone, type, cfg_obj_assockaddr(obj));
}
static isc_result_t
process_notify_cfg(const cfg_obj_t **maps, dns_zone_t *zone, dns_zone_t *raw) {
isc_result_t result;
const cfg_obj_t *obj = NULL;
result = named_config_get(maps, "notify-cfg", &obj);
if (result == ISC_R_SUCCESS && obj != NULL) {
CFG_LIST_FOREACH(obj, element) {
const cfg_obj_t *nmaps[MAPS_SIZE + 1];
const cfg_obj_t *map = cfg_listelt_value(element);
const char *name =
cfg_obj_asstring(cfg_map_getname(map));
isc_textregion_t tr;
dns_rdatatype_t rdtype = 0;
tr.base = UNCONST(name);
tr.length = strlen(name);
result = dns_rdatatype_fromtext(&rdtype, &tr);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(map, ISC_LOG_ERROR,
"%s is not a valid notify type",
name);
return result;
}
switch (rdtype) {
case dns_rdatatype_soa:
case dns_rdatatype_cds:
break;
default:
cfg_obj_log(map, ISC_LOG_ERROR,
"%s notify type is not supported",
name);
return ISC_R_NOTIMPLEMENTED;
}
/* Prepend the notify-cfg map. */
size_t i = 0;
nmaps[i] = map;
while (maps[i] != NULL) {
nmaps[i + 1] = maps[i];
i++;
}
INSIST(i <= MAPS_SIZE);
nmaps[i + 1] = NULL;
process_notify_options(rdtype, nmaps, zone, raw, true);
}
}
return ISC_R_SUCCESS;
}
isc_result_t
named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const cfg_obj_t *zconfig, cfg_aclconfctx_t *aclctx,
@ -854,9 +957,9 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
const char *zname;
dns_rdataclass_t zclass;
dns_rdataclass_t vclass;
const cfg_obj_t *maps[6];
const cfg_obj_t *nodefault[5];
const cfg_obj_t *nooptions[3];
const cfg_obj_t *maps[MAPS_SIZE];
const cfg_obj_t *nodefault[NODEFAULT_MAPS_SIZE];
const cfg_obj_t *nooptions[NOOPTIONS_MAPS_SIZE];
const cfg_obj_t *zoptions = NULL;
const cfg_obj_t *toptions = NULL;
const cfg_obj_t *options = NULL;
@ -1194,6 +1297,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
} else {
notifytype = dns_notifytype_no;
}
notifytype = cfg_obj_asboolean(obj);
} else {
const char *str = cfg_obj_asstring(obj);
if (strcasecmp(str, "explicit") == 0) {
@ -1206,24 +1310,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
UNREACHABLE();
}
}
notifytype = process_notifytype(notifytype, ztype, zname,
nodefault);
notifytype = process_notifysoatype(notifytype, ztype, zname,
nodefault);
if (raw != NULL) {
dns_zone_setnotifytype(raw, dns_rdatatype_soa,
dns_notifytype_no);
}
dns_zone_setnotifytype(zone, dns_rdatatype_soa, notifytype);
obj = NULL;
result = named_config_get(maps, "notify-cds", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
if (raw != NULL) {
dns_zone_setnotifytype(raw, dns_rdatatype_cds,
dns_notifytype_no);
}
dns_zone_setnotifytype(zone, dns_rdatatype_cds,
cfg_obj_asboolean(obj));
obj = NULL;
result = named_config_get(maps, "also-notify", &obj);
if (result == ISC_R_SUCCESS &&
@ -1255,16 +1349,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setparentalsrc6(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-source", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifysrc4(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-source-v6", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifysrc6(zone, cfg_obj_assockaddr(obj));
obj = NULL;
result = named_config_get(maps, "notify-to-soa", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
@ -1393,16 +1477,6 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
fail);
}
obj = NULL;
result = named_config_get(maps, "notify-delay", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifydelay(zone, cfg_obj_asuint32(obj));
obj = NULL;
result = named_config_get(maps, "notify-defer", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setnotifydefer(zone, cfg_obj_asuint32(obj));
obj = NULL;
result = named_config_get(maps, "check-sibling", &obj);
INSIST(result == ISC_R_SUCCESS && obj != NULL);
@ -1483,6 +1557,11 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setrad(zone, rad);
}
}
process_notify_options(dns_rdatatype_soa, maps, zone, raw,
false);
CHECK(process_notify_cfg(maps, zone, raw));
} else if (ztype == dns_zone_redirect) {
dns_zone_setnotifytype(zone, dns_rdatatype_soa,
dns_notifytype_no);
@ -2001,7 +2080,8 @@ named_zone_reusable(dns_zone_t *zone, const cfg_obj_t *zconfig,
bool
named_zone_inlinesigning(const cfg_obj_t *zconfig, const cfg_obj_t *vconfig,
const cfg_obj_t *config, dns_kasplist_t *kasplist) {
const cfg_obj_t *maps[5] = { 0 }, *noopts[3] = { 0 };
const cfg_obj_t *maps[NODEFAULT_MAPS_SIZE] = { 0 },
*noopts[NOOPTIONS_MAPS_SIZE] = { 0 };
const cfg_obj_t *signing = NULL;
const cfg_obj_t *policy = NULL;
const cfg_obj_t *toptions = NULL;

View file

@ -12,11 +12,11 @@
*/
/*
* Bad notify-cds type
* Bad notify-cfg CDS notify type
*/
zone dummy {
type primary;
file "xxxx";
notify-cds explicit;
notify-cfg CDS { notify explicit; };
};

View file

@ -0,0 +1,22 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*
* Bad notify-cfg TXT not supported
*/
zone dummy {
type primary;
file "xxxx";
notify-cfg TXT { notify yes; };
};

View file

@ -194,7 +194,16 @@ view "fourth" {
1.2.3.5;
};
dnssec-policy "test";
notify-cds no;
notify-cfg "SOA" {
notify yes;
notify-defer 1;
notify-delay 3;
notify-source 192.0.2.1;
notify-source-v6 2001:db8::1;
};
notify-cfg "CDS" {
notify no;
};
parental-source 10.10.10.10;
};
zone "dnssec-default" {
@ -204,7 +213,13 @@ view "fourth" {
"parents";
};
dnssec-policy "default";
notify-cds yes;
notify-cfg "CDS" {
notify yes;
notify-defer 0;
notify-delay 5;
notify-source 0.0.0.0;
notify-source-v6 ::;
};
};
zone "dnssec-inherit" {
type primary;

View file

@ -26,7 +26,7 @@ options {
allow-transfer { any; };
key-directory ".";
dnssec-validation yes;
notify-cds yes;
notify-cfg CDS { notify yes; };
};
key rndc_key {

View file

@ -26,7 +26,7 @@ options {
allow-transfer { any; };
key-directory ".";
dnssec-validation yes;
notify-cds yes;
notify-cfg cds { notify yes; };
};
key rndc_key {

View file

@ -30,7 +30,7 @@ options {
allow-transfer { any; };
recursion yes;
dnssec-validation @dnssec_validation@;
notify-cds yes;
notify-cfg CDS { notify yes; };
};
key rndc_key {

View file

@ -2115,21 +2115,40 @@ Boolean Options
statement. It would only be necessary to turn off this option if it
caused secondary zones to crash.
.. namedconf:statement:: notify-cds
.. namedconf:statement:: notify-cfg
:tags: dnssec
:short: Controls whether ``NOTIFY(CDS)`` messages are sent on zone changes.
:short: Controls generalized DNS notifications configuration.
If set to ``yes``, DNS NOTIFY(CDS) messages are sent when the CDS or CDNSKEY
RRset changes. The messages are sent to the servers listed in the parent
zone's matching DSYNC records. A DSYNC record matches if the owner name under
`_dsync` subdomain of the parent zone corresponds to the given zone. For
example, the zone `child.example` should have a DSYNC record at
`child._dsync.example`. In addition, the RRtype field of the record must be
`CDS` and the Scheme field must be 1 (NOTIFY).
This option can be used to override NOTIFY configuration options
for specific types. The following options can be set within a
:any:`notify-cfg` statement: :any:`notify-defer`, :any:`notify-delay`,
:any:`notify-source`, :any:`notify-source-v6`, and
:namedconf:ref:`notify`. The latter can only be set to
``yes`` or ``no``.
The default is ``no``. The :namedconf:ref:`notify-cds` option may also be
specified in the :any:`zone` statement, in which case it overrides the
``options notify-cds`` statement.
By default, only NOTIFY(SOA) messages are enabled. When configuring
notify configuration for other types you enable sending DNS notifications
for the given type. For example, to enable NOTIFY(CDS) messages, using a
specific source, you can add the following configuration:
::
notify-cfg CDS { notify yes; notify-source-v6 2001:DB8::1; };
If enabled, DNS NOTIFY(CDS) messages are sent when the CDS or CDNSKEY
RRset changes. The messages are sent to the servers listed in the parent
zone's matching DSYNC records. A DSYNC record matches if the owner name under
`_dsync` subdomain of the parent zone corresponds to the given zone. For
example, the zone `child.example` should have a DSYNC record at
`child._dsync.example`. In addition, the RRtype field of the record must be
`CDS` and the Scheme field must be 1 (NOTIFY).
The :any:`notify-defer` and :any:`notify-delay` options are not applicable
to NOTIFY(CDS) messages and they are ignored for that type.
The :namedconf:ref:`notify-cfg` option may also be specified in the
:any:`zone` statement, in which case it overrides the ``options notify-cfg``
statement. The only supported types are ``SOA`` and ``CDS``.
.. namedconf:statement:: notify-to-soa
:tags: transfer

View file

@ -29,7 +29,13 @@ zone <string> [ <class> ] {
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-cds <boolean>;
notify-cfg <string> {
notify <boolean>;
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
notify-source-v6 ( <ipv6_address> | * );
}; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );

View file

@ -210,7 +210,13 @@ options {
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-cds <boolean>;
notify-cfg <string> {
notify <boolean>;
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
notify-source-v6 ( <ipv6_address> | * );
}; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-rate <integer>;
@ -416,7 +422,13 @@ template <string> {
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-cds <boolean>;
notify-cfg <string> {
notify <boolean>;
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
notify-source-v6 ( <ipv6_address> | * );
}; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
@ -588,7 +600,13 @@ view <string> [ <class> ] {
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-cds <boolean>;
notify-cfg <string> {
notify <boolean>;
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
notify-source-v6 ( <ipv6_address> | * );
}; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );

View file

@ -44,7 +44,13 @@ zone <string> [ <class> ] {
max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> ); // deprecated
notify ( explicit | master-only | primary-only | <boolean> );
notify-cds <boolean>;
notify-cfg <string> {
notify <boolean>;
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
notify-source-v6 ( <ipv6_address> | * );
}; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );

View file

@ -41,7 +41,13 @@ zone <string> [ <class> ] {
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-cds <boolean>;
notify-cfg <string> {
notify <boolean>;
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );
notify-source-v6 ( <ipv6_address> | * );
}; // may occur multiple times
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * );

View file

@ -36,6 +36,8 @@ struct dns_notifyctx {
/* Configuration data. */
dns_notifytype_t notifytype;
uint32_t notifydefer;
uint32_t notifydelay;
isc_sockaddr_t notifysrc4;
isc_sockaddr_t notifysrc6;
};

View file

@ -900,47 +900,29 @@ dns_zone_getparentalsrc6(dns_zone_t *zone, isc_sockaddr_t *parentalsrc);
*/
void
dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
dns_zone_setnotifysrc4(dns_zone_t *zone, dns_rdatatype_t type,
const isc_sockaddr_t *notifysrc);
/*%<
* Set the source address to be used with IPv4 NOTIFY messages.
*
* Require:
*\li 'zone' to be a valid zone.
*\li 'type' to be a valid notify RRtype.
*\li 'notifysrc' to contain the address.
*/
void
dns_zone_getnotifysrc4(dns_zone_t *zone, isc_sockaddr_t *notifysrc);
/*%<
* Returns the source address set by a previous dns_zone_setnotifysrc4
* call, or the default of inaddr_any, port 0.
*
* Require:
*\li 'zone' to be a valid zone.
*\li 'notifysrc' to be non NULL.
*/
void
dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc);
dns_zone_setnotifysrc6(dns_zone_t *zone, dns_rdatatype_t type,
const isc_sockaddr_t *notifysrc);
/*%<
* Set the source address to be used with IPv6 NOTIFY messages.
*
* Require:
*\li 'zone' to be a valid zone.
*\li 'type' to be a valid notify RRtype.
*\li 'notifysrc' to contain the address.
*/
void
dns_zone_getnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc);
/*%<
* Returns the source address set by a previous dns_zone_setnotifysrc6
* call, or the default of in6addr_any, port 0.
*
* Require:
*\li 'zone' to be a valid zone.
*\li 'notifysrc' to be non NULL.
*/
void
dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl);
/*%<
@ -2123,22 +2105,24 @@ dns_zone_setcheckisservedby(dns_zone_t *zone,
*/
void
dns_zone_setnotifydefer(dns_zone_t *zone, uint32_t defer);
dns_zone_setnotifydefer(dns_zone_t *zone, dns_rdatatype_t type, uint32_t defer);
/*%<
* Set the wait/defer time (in seconds) before notify messages are sent when
* they are ready.
*
* Requires:
* 'zone' to be valid.
* 'type' to be a valid notify RRtype.
*/
void
dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay);
dns_zone_setnotifydelay(dns_zone_t *zone, dns_rdatatype_t type, uint32_t delay);
/*%<
* Set the minimum delay (in seconds) between sets of notify messages.
*
* Requires:
* 'zone' to be valid.
* 'type' to be a valid notify RRtype.
*/
void

View file

@ -44,6 +44,7 @@ dns_notifyctx_init(dns_notifyctx_t *nctx, dns_rdatatype_t type) {
dns_notifyctx_t ctx = {
.type = type,
.notifytype = dns_notifytype_yes,
.notifydelay = 5,
.notifies = ISC_LIST_INITIALIZER,
};
isc_sockaddr_any(&ctx.notifysrc4);

View file

@ -408,8 +408,6 @@ struct dns_zone {
isc_stats_t *requeststats;
dns_stats_t *rcvquerystats;
dns_stats_t *dnssecsignstats;
uint32_t notifydelay;
uint32_t notifydefer;
dns_isselffunc_t isself;
void *isselfarg;
@ -1068,7 +1066,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, isc_tid_t tid) {
.sigvalidityinterval = 30 * 24 * 3600,
.sigresigninginterval = 7 * 24 * 3600,
.statlevel = dns_zonestat_none,
.notifydelay = 5,
.signatures = 10,
.nodes = 100,
.privatetype = (dns_rdatatype_t)0xffffU,
@ -6353,46 +6350,42 @@ dns_zone_getparentalsrc6(dns_zone_t *zone, isc_sockaddr_t *parentalsrc) {
}
void
dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
dns_zone_setnotifysrc4(dns_zone_t *zone, dns_rdatatype_t type,
const isc_sockaddr_t *notifysrc) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(notifysrc != NULL);
LOCK_ZONE(zone);
zone->notifysoa.notifysrc4 = *notifysrc;
zone->notifycds.notifysrc4 = *notifysrc;
switch (type) {
case dns_rdatatype_soa:
zone->notifysoa.notifysrc4 = *notifysrc;
break;
case dns_rdatatype_cds:
zone->notifycds.notifysrc4 = *notifysrc;
break;
default:
UNREACHABLE();
}
UNLOCK_ZONE(zone);
}
void
dns_zone_getnotifysrc4(dns_zone_t *zone, isc_sockaddr_t *notifysrc) {
dns_zone_setnotifysrc6(dns_zone_t *zone, dns_rdatatype_t type,
const isc_sockaddr_t *notifysrc) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(notifysrc != NULL);
LOCK_ZONE(zone);
*notifysrc = zone->notifysoa.notifysrc4;
*notifysrc = zone->notifycds.notifysrc4;
UNLOCK_ZONE(zone);
}
void
dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(notifysrc != NULL);
LOCK_ZONE(zone);
zone->notifysoa.notifysrc6 = *notifysrc;
zone->notifycds.notifysrc6 = *notifysrc;
UNLOCK_ZONE(zone);
}
void
dns_zone_getnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(notifysrc != NULL);
LOCK_ZONE(zone);
*notifysrc = zone->notifysoa.notifysrc6;
*notifysrc = zone->notifycds.notifysrc6;
switch (type) {
case dns_rdatatype_soa:
zone->notifysoa.notifysrc6 = *notifysrc;
break;
case dns_rdatatype_cds:
zone->notifycds.notifysrc6 = *notifysrc;
break;
default:
UNREACHABLE();
}
UNLOCK_ZONE(zone);
}
@ -11403,7 +11396,7 @@ zone_maintenance(dns_zone_t *zone) {
* primaries after.
*/
LOCK_ZONE(zone);
if (zone->notifydefer != 0 &&
if (zone->notifysoa.notifydefer != 0 &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOTIFYNODEFER) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED))
{
@ -11411,7 +11404,8 @@ zone_maintenance(dns_zone_t *zone) {
zone->notifytime = now;
}
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED);
DNS_ZONE_TIME_ADD(&zone->notifytime, zone->notifydefer,
DNS_ZONE_TIME_ADD(&zone->notifytime,
zone->notifysoa.notifydefer,
&zone->notifytime);
}
notify = (zone->type == dns_zone_secondary ||
@ -12408,7 +12402,7 @@ dns_zone_notify(dns_zone_t *zone, bool nodefer) {
*/
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOTIFYDEFERRED);
DNS_ZONE_TIME_SUBTRACT(&zone->notifytime,
zone->notifydefer,
zone->notifysoa.notifydefer,
&zone->notifytime);
}
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOTIFYNODEFER);
@ -12449,7 +12443,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
DNS_ZONEFLG_NOTIFYNODEFER |
DNS_ZONEFLG_NOTIFYDEFERRED);
notifytype = zone->notifysoa.notifytype;
DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
DNS_ZONE_TIME_ADD(now, zone->notifysoa.notifydelay, &zone->notifytime);
UNLOCK_ZONE(zone);
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
@ -19441,20 +19435,42 @@ dns__zone_getisself(dns_zone_t *zone, dns_isselffunc_t *isself, void **arg) {
}
void
dns_zone_setnotifydefer(dns_zone_t *zone, uint32_t defer) {
dns_zone_setnotifydefer(dns_zone_t *zone, dns_rdatatype_t type,
uint32_t defer) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->notifydefer = defer;
switch (type) {
case dns_rdatatype_soa:
zone->notifysoa.notifydefer = defer;
break;
case dns_rdatatype_cds:
/* not applicable to NOTIFY(CDS), unused */
zone->notifycds.notifydefer = defer;
break;
default:
UNREACHABLE();
}
UNLOCK_ZONE(zone);
}
void
dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
dns_zone_setnotifydelay(dns_zone_t *zone, dns_rdatatype_t type,
uint32_t delay) {
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
zone->notifydelay = delay;
switch (type) {
case dns_rdatatype_soa:
zone->notifysoa.notifydelay = delay;
break;
case dns_rdatatype_cds:
/* not applicable to NOTIFY(CDS), unused */
zone->notifycds.notifydelay = delay;
break;
default:
UNREACHABLE();
}
UNLOCK_ZONE(zone);
}

View file

@ -3629,7 +3629,8 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
/*
* Primary, secondary, and mirror zones may have an "also-notify"
* field, but shouldn't if notify is disabled.
* field, but shouldn't if notify is disabled. Also check "notify-cfg"
* for valid types.
*/
if (ztype == CFG_ZONE_PRIMARY || ztype == CFG_ZONE_SECONDARY ||
ztype == CFG_ZONE_MIRROR)
@ -3674,6 +3675,47 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
result = tresult;
}
}
obj = NULL;
(void)get_zoneopt(zoptions, toptions, voptions, goptions,
"notify-cfg", &obj);
if (obj != NULL) {
CFG_LIST_FOREACH(obj, element) {
const cfg_obj_t *map =
cfg_listelt_value(element);
const char *name =
cfg_obj_asstring(cfg_map_getname(map));
isc_textregion_t tr;
dns_rdatatype_t rdtype = 0;
tr.base = UNCONST(name);
tr.length = strlen(name);
tresult = dns_rdatatype_fromtext(&rdtype, &tr);
if (tresult != ISC_R_SUCCESS &&
result == ISC_R_SUCCESS)
{
cfg_obj_log(
map, ISC_LOG_ERROR,
"%s is not a valid notify type",
name);
result = tresult;
}
switch (rdtype) {
case dns_rdatatype_soa:
case dns_rdatatype_cds:
break;
default:
if (result == ISC_R_SUCCESS) {
cfg_obj_log(map, ISC_LOG_ERROR,
"%s notify type is "
"not supported",
name);
result = ISC_R_NOTIMPLEMENTED;
}
}
}
}
}
/*

View file

@ -108,6 +108,7 @@ static cfg_type_t cfg_type_maxcachesize;
static cfg_type_t cfg_type_maxduration;
static cfg_type_t cfg_type_minimal;
static cfg_type_t cfg_type_nameportiplist;
static cfg_type_t cfg_type_notifycfg;
static cfg_type_t cfg_type_notifytype;
static cfg_type_t cfg_type_optional_allow;
static cfg_type_t cfg_type_optional_class;
@ -2685,8 +2686,10 @@ static cfg_clausedef_t zone_clauses[] = {
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB, NULL },
{ "notify", &cfg_type_notifytype,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR, NULL },
{ "notify-cds", &cfg_type_boolean,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR, NULL },
{ "notify-cfg", &cfg_type_notifycfg,
CFG_CLAUSEFLAG_MULTI | CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY |
CFG_ZONE_MIRROR,
NULL },
{ "notify-defer", &cfg_type_uint32,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR, NULL },
{ "notify-delay", &cfg_type_uint32,
@ -3399,6 +3402,25 @@ static cfg_type_t cfg_type_notifytype = {
doc_notify_type, &cfg_rep_string, notify_enums,
};
/*
* Generalized DNS Notifications.
*/
static cfg_clausedef_t notify_clauses[] = {
{ "notify", &cfg_type_boolean, 0, NULL }, /* this limits the options for
NOTIFY(SOA) */
{ "notify-defer", &cfg_type_uint32, 0, NULL },
{ "notify-delay", &cfg_type_uint32, 0, NULL },
{ "notify-source", &cfg_type_sockaddr4wild, 0, NULL },
{ "notify-source-v6", &cfg_type_sockaddr6wild, 0, NULL },
{ NULL, NULL, 0, NULL },
};
static cfg_clausedef_t *notify_clausesets[] = { notify_clauses, NULL };
static cfg_type_t cfg_type_notifycfg = { "notify-cfg", cfg_parse_named_map,
cfg_print_map, cfg_doc_map,
&cfg_rep_map, notify_clausesets };
static const char *minimal_enums[] = { "no-auth", "no-auth-recursive", NULL };
static isc_result_t
parse_minimal(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {