notify yes;\n\
notify-delay 5;\n\
notify-to-soa no;\n\
+# send-report-channel <none>\n\
serial-update-method increment;\n\
sig-signing-nodes 100;\n\
sig-signing-signatures 10;\n\
INSIST(result == ISC_R_SUCCESS && obj != NULL);
dns_zone_setoption(zone, DNS_ZONEOPT_NSEC3TESTZONE,
cfg_obj_asboolean(obj));
+
+ obj = NULL;
+ (void)cfg_map_get(zoptions, "send-report-channel", &obj);
+ if (obj != NULL) {
+ dns_fixedname_t fixed;
+ dns_name_t *rad = dns_fixedname_initname(&fixed);
+ CHECK(dns_name_fromstring(rad, cfg_obj_asstring(obj),
+ dns_rootname, 0, mctx));
+ dns_zone_setrad(zone, rad);
+ } else {
+ dns_zone_setrad(zone, NULL);
+ }
} else if (ztype == dns_zone_redirect) {
dns_zone_setnotifytype(zone, dns_notifytype_no);
zone example.com {
type primary;
file "example.com.db";
+ send-report-channel "rad.example.com";
};
};
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
+n=$((n + 1))
+echo_i "check that a zone-level Report-Channel EDNS option is added to responses ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.1 example.com >dig.out.test$n
+grep "; Report-Channel: rad.example.com" dig.out.test$n >/dev/null || ret=1
+[ $ret -eq 0 ] || echo_i "failed"
+status=$((status + ret))
+
n=$((n + 1))
echo_i "check that error report queries are logged and no Report-Channel option is present in the response ($n)"
ret=0
problems with resolution or validation elsewhere (for example,
expired DNSSEC signatures).
- When :any:`send-report-channel` is set in :namedconf:ref:`options`, or
- :namedconf:ref:`view` :iscman:`named` adds a Report-Channel option to
- authoritative responses, using the specified domain name as the
- Agent-Domain. :iscman:`named` also logs any TXT queries received for
- names matching the prescribed error-reporting format
+ When :any:`send-report-channel` is set in :namedconf:ref:`options`,
+ :namedconf:ref:`view`, or :namedconf:ref:`zone`, :iscman:`named` adds a
+ Report-Channel option to authoritative responses, using the specified
+ domain name as the Agent-Domain.
+
+ When it is set in :namedconf:ref:`options` or :namedconf:ref:`view` (but
+ *not* :namedconf:ref:`zone`), :iscman:`named` also logs any TXT queries
+ received for names matching the prescribed error-reporting format
(_er.<type>.<name>.<extended-rcode>._er.<agent-domain>) to the
``dns-reporting-agent`` logging category at level ``info``.
parental-agents [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
parental-source ( <ipv4_address> | * );
parental-source-v6 ( <ipv6_address> | * );
+ send-report-channel <string>;
serial-update-method ( date | increment | unixtime );
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
request-expire <boolean>;
request-ixfr <boolean>;
request-ixfr-max-diffs <integer>;
+ send-report-channel <string>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
* \li ISC_R_SUCCESS if there were no errors loading the SKR.
*/
+void
+dns_zone_setrad(dns_zone_t *zone, dns_name_t *name);
+/**<
+ * \brief Set the per zone RAD
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ * \li 'name' is NULL or a valid name.
+ */
+
+isc_result_t
+dns_zone_getrad(dns_zone_t *zone, dns_name_t *name);
+/**<
+ * \brief get the per zone RAD
+ *
+ * Requires:
+ * \li 'zone' to be a valid zone.
+ * \li 'name' is a valid name with a buffer.
+ */
+
#if DNS_ZONE_TRACE
#define dns_zone_ref(ptr) dns_zone__ref(ptr, __func__, __FILE__, __LINE__)
#define dns_zone_unref(ptr) dns_zone__unref(ptr, __func__, __FILE__, __LINE__)
isc_timer_t *timer;
isc_refcount_t irefs;
dns_name_t origin;
+ dns_name_t rad;
char *masterfile;
const FILE *stream; /* loading from a stream? */
ISC_LIST(dns_include_t) includes; /* Include files */
isc_refcount_init(&zone->references, 1);
isc_refcount_init(&zone->irefs, 0);
dns_name_init(&zone->origin, NULL);
+ dns_name_init(&zone->rad, NULL);
isc_sockaddr_any(&zone->notifysrc4);
isc_sockaddr_any6(&zone->notifysrc6);
isc_sockaddr_any(&zone->parentalsrc4);
if (dns_name_dynamic(&zone->origin)) {
dns_name_free(&zone->origin, zone->mctx);
}
+ if (dns_name_dynamic(&zone->rad)) {
+ dns_name_free(&zone->rad, zone->mctx);
+ }
if (zone->strnamerd != NULL) {
isc_mem_free(zone->mctx, zone->strnamerd);
}
return (result);
}
+
+isc_result_t
+dns_zone_getrad(dns_zone_t *zone, dns_name_t *name) {
+ isc_result_t result = ISC_R_NOTFOUND;
+
+ REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(DNS_NAME_VALID(name));
+
+ LOCK_ZONE(zone);
+ if (dns_name_dynamic(&zone->rad)) {
+ dns_name_copy(&zone->rad, name);
+ result = ISC_R_SUCCESS;
+ }
+ UNLOCK_ZONE(zone);
+ return (result);
+}
+
+void
+dns_zone_setrad(dns_zone_t *zone, dns_name_t *name) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(name == NULL || DNS_NAME_VALID(name));
+
+ LOCK_ZONE(zone);
+ if (dns_name_dynamic(&zone->rad)) {
+ dns_name_free(&zone->rad, zone->mctx);
+ }
+ if (name != NULL) {
+ dns_name_dup(name, zone->mctx, &zone->rad);
+ }
+ UNLOCK_ZONE(zone);
+}
{ "queryport-pool-updateinterval", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "rate-limit", &cfg_type_rrl, 0 },
{ "recursion", &cfg_type_boolean, 0 },
- { "send-report-channel", &cfg_type_astring, 0 },
{ "request-nsid", &cfg_type_boolean, 0 },
{ "request-sit", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "require-server-cookie", &cfg_type_boolean, 0 },
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
{ "parental-source-v6", &cfg_type_sockaddr6wild,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
+ { "send-report-channel", &cfg_type_astring,
+ CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
{ "request-expire", &cfg_type_boolean,
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR },
{ "request-ixfr", &cfg_type_boolean,
client->extflags = 0;
client->ednsversion = -1;
client->additionaldepth = 0;
+ if (dns_name_dynamic(&client->rad)) {
+ dns_name_free(&client->rad, client->manager->mctx);
+ }
dns_ecs_init(&client->ecs);
dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
count++;
}
- if (WANTRC(client) && view != NULL && view->rad != NULL &&
- !dns_name_equal(view->rad, dns_rootname))
- {
- INSIST(count < DNS_EDNSOPTIONS);
- ednsopts[count].code = DNS_OPT_REPORT_CHANNEL;
- ednsopts[count].length = view->rad->length;
- ednsopts[count].value = view->rad->ndata;
- count++;
+ if (WANTRC(client)) {
+ dns_name_t *rad = NULL;
+ if (dns_name_dynamic(&client->rad)) {
+ rad = &client->rad;
+ } else if (view != NULL && view->rad != NULL) {
+ rad = view->rad;
+ }
+ if (rad != NULL && !dns_name_equal(rad, dns_rootname)) {
+ INSIST(count < DNS_EDNSOPTIONS);
+ ednsopts[count].code = DNS_OPT_REPORT_CHANNEL;
+ ednsopts[count].length = rad->length;
+ ednsopts[count].value = rad->ndata;
+ count++;
+ }
}
/* Padding must be added last */
client->udpsize = 512;
client->ednsversion = -1;
dns_name_init(&client->signername, NULL);
+ dns_name_init(&client->rad, NULL);
dns_ecs_init(&client->ecs);
isc_sockaddr_any(&client->formerrcache.addr);
client->formerrcache.time = 0;
isc_buffer_t *buffer;
isc_buffer_t tbuffer;
+ dns_name_t rad; /* Zone rad domain */
+
isc_sockaddr_t peeraddr;
bool peeraddr_valid;
isc_netaddr_t destaddr;
if (qctx->is_zone) {
qctx->authoritative = true;
if (qctx->zone != NULL) {
- if (dns_zone_gettype(qctx->zone) == dns_zone_mirror) {
+ dns_fixedname_t fixed;
+ dns_name_t *rad;
+ switch (dns_zone_gettype(qctx->zone)) {
+ case dns_zone_mirror:
qctx->authoritative = false;
- }
- if (dns_zone_gettype(qctx->zone) == dns_zone_staticstub)
- {
+ break;
+ case dns_zone_staticstub:
qctx->is_staticstub_zone = true;
+ break;
+ case dns_zone_primary:
+ case dns_zone_secondary:
+ rad = dns_fixedname_initname(&fixed);
+ if (!dns_name_dynamic(&qctx->client->rad) &&
+ dns_zone_getrad(qctx->zone, rad) ==
+ ISC_R_SUCCESS)
+ {
+ dns_name_dup(
+ rad,
+ qctx->client->manager->mctx,
+ &qctx->client->rad);
+ }
+ break;
+ default:
+ break;
}
}
}