Commit a7657dc1 authored by Michał Kępień's avatar Michał Kępień

Send upstream TAT queries for locally served zones

Trying to resolve a trust anchor telemetry query for a locally served
zone does not cause upstream queries to be sent as the response is
determined just by consulting local data.  Work around this issue by
calling dns_view_findzonecut() first in order to determine the NS RRset
for a given domain name and then passing the zone cut found to

Note that this change only applies to TAT queries generated by the
resolver itself, not to ones received from downstream resolvers.
parent 127810e5
......@@ -6502,7 +6502,8 @@ struct dotat_arg {
* Prepare the QNAME for the TAT query to be sent by processing the trust
* anchors present at 'keynode' of 'keytable'. Store the result in 'dst'.
* anchors present at 'keynode' of 'keytable'. Store the result in 'dst' and
* the domain name which 'keynode' is associated with in 'origin'.
* A maximum of 12 key IDs can be reported in a single TAT query due to the
* 63-octet length limit for any single label in a domain name. If there are
......@@ -6510,11 +6511,10 @@ struct dotat_arg {
* reported in the TAT query.
static isc_result_t
get_tat_qname(dns_name_t *dst, dns_keytable_t *keytable,
dns_keynode_t *keynode)
get_tat_qname(dns_name_t *dst, const dns_name_t **origin,
dns_keytable_t *keytable, dns_keynode_t *keynode)
dns_keynode_t *firstnode = keynode;
const dns_name_t *origin;
dns_keynode_t *nextnode;
unsigned int i, n = 0;
isc_uint16_t ids[12];
......@@ -6522,10 +6522,12 @@ get_tat_qname(dns_name_t *dst, dns_keytable_t *keytable,
char label[64];
int m;
REQUIRE(origin != NULL && *origin == NULL);
do {
dst_key_t *key = dns_keynode_key(keynode);
if (key != NULL) {
origin = dst_key_name(key);
*origin = dst_key_name(key);
if (n < (sizeof(ids)/sizeof(ids[0]))) {
ids[n] = dst_key_id(key);
......@@ -6567,15 +6569,17 @@ get_tat_qname(dns_name_t *dst, dns_keytable_t *keytable,
isc_textregion_consume(&r, m);
return (dns_name_fromstring2(dst, label, origin, 0, NULL));
return (dns_name_fromstring2(dst, label, *origin, 0, NULL));
static void
dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
struct dotat_arg *dotat_arg = arg;
char namebuf[DNS_NAME_FORMATSIZE];
dns_fixedname_t fixed;
dns_name_t *tatname;
const dns_name_t *origin = NULL;
dns_fixedname_t fixed, fdomain;
dns_name_t *tatname, *domain;
dns_rdataset_t nameservers;
isc_result_t result;
dns_view_t *view;
isc_task_t *task;
......@@ -6589,7 +6593,7 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
task = dotat_arg->task;
tatname = dns_fixedname_initname(&fixed);
result = get_tat_qname(tatname, keytable, keynode);
result = get_tat_qname(tatname, &origin, keytable, keynode);
if (result != ISC_R_SUCCESS) {
......@@ -6613,12 +6617,54 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
isc_mem_attach(dotat_arg->view->mctx, &tat->mctx);
isc_task_attach(task, &tat->task);
* TAT queries should be sent to the authoritative servers for a given
* zone. If this function is called for a keytable node corresponding
* to a locally served zone, calling dns_resolver_createfetch() with
* NULL 'domain' and 'nameservers' arguments will cause 'tatname' to be
* resolved locally, without sending any TAT queries upstream.
* Work around this issue by calling dns_view_findzonecut() first. If
* the zone is served locally, the NS RRset for the given domain name
* will be retrieved from local data; if it is not, the deepest zone
* cut we have for it will be retrieved from cache. In either case,
* passing the results to dns_resolver_createfetch() will prevent it
* from returning NXDOMAIN for 'tatname' while still allowing it to
* chase down any potential delegations returned by upstream servers in
* order to eventually find the destination host to send the TAT query
* to.
* 'origin' holds the domain name at 'keynode', i.e. the domain name
* for which the trust anchors to be reported by this TAT query are
* defined.
* After the dns_view_findzonecut() call, 'domain' will hold the
* deepest zone cut we can find for 'origin' while 'nameservers' will
* hold the NS RRset at that zone cut.
domain = dns_fixedname_initname(&fdomain);
result = dns_view_findzonecut(view, origin, domain, 0, 0, ISC_TRUE,
ISC_TRUE, &nameservers, NULL);
if (result != ISC_R_SUCCESS) {
goto done;
result = dns_resolver_createfetch(view->resolver, tatname,
dns_rdatatype_null, NULL, NULL,
NULL, NULL, 0, 0, 0, NULL, tat->task,
tat_done, tat, &tat->rdataset,
&tat->sigrdataset, &tat->fetch);
dns_rdatatype_null, domain,
&nameservers, NULL, NULL, 0, 0, 0,
NULL, tat->task, tat_done, tat,
&tat->rdataset, &tat->sigrdataset,
* dns_resolver_createfetch() creates its own copies of 'domain' and
* 'nameservers'; clean up the latter (the former points into a
* dst_key_t structure and thus must not be freed).
if (result != ISC_R_SUCCESS) {
isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat));
-X named.lock -m record,size,mctx -T clienttest -c named.conf -d 99 -g -U 4 -T tat=1
......@@ -28,6 +28,7 @@ options {
listen-on-v6 { none; };
recursion yes;
allow-query-cache {; };
trust-anchor-telemetry yes;
zone "." {
......@@ -404,5 +404,13 @@ nextpart ns3/ | grep "No correct RSASHA256 signature for verify-reconfi
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "ensuring trust anchor telemetry queries are sent upstream for a mirror zone ($n)"
# ns3 is started with "-T tat=1", so TAT queries should have already been sent.
grep "_ta-[-0-9a-f]*/NULL" ns1/ > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
......@@ -1573,6 +1573,7 @@
./bin/tests/system/mirror/ns2/ SH 2018
./bin/tests/system/mirror/ns2/ ZONE 2018
./bin/tests/system/mirror/ns2/ ZONE 2018
./bin/tests/system/mirror/ns3/named.args X 2018
./bin/tests/system/mirror/ns3/ CONF-C 2018
./bin/tests/system/mirror/ SH 2018
./bin/tests/system/mirror/ SH 2018
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment