record trust-anchor-telementry in incoming requests.
Both _ta-XXXX.<anchor>/NULL and EDNS KEY-TAG options
are logged. [RT #46124]
+4759. [func] Add logging channel "trust-anchor-telementry" to
+ record trust-anchor-telementry in incoming requests.
+ Both _ta-XXXX.<anchor>/NULL and EDNS KEY-TAG options
+ are logged. [RT #46124]
+
4758. [doc] Remove documentation of unimplemented "topology".
[RT #46161]
"successful uses of stale cache data after lookup failure",
"QryUsedStale");
SET_NSSTATDESC(prefetch, "queries triggered prefetch", "Prefetch");
+ SET_NSSTATDESC(keytagopt, "Keytag option received", "KeyTagOpt");
INSIST(i == ns_statscounter_max);
/* Initialize resolver statistics */
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
-echo "I:check that trust-anchor-telemetry queries are received ($n)"
+echo "I:check that _ta-XXXX trust-anchor-telemetry queries are logged ($n)"
ret=0
-grep "query '_ta-[0-9a-f]*/NULL/IN' approved" ns1/named.run > /dev/null || ret=1
+grep "trust-anchor-telemetry '_ta-[0-9a-f]*/IN' from" ns1/named.run > /dev/null || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
-echo "I:check that trust-anchor-telemetry are not sent when disabled ($n)"
+echo "I:check that _ta-AAAA trust-anchor-telemetry are not sent when disabled ($n)"
ret=0
-grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/NULL" ns1/named.run > /dev/null && ret=1
+grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/IN" ns1/named.run > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:check that KEY-TAG trust-anchor-telemetry queries are logged ($n)"
+ret=0
+$DIG $DIGOPTS . dnskey +ednsopt=KEY-TAG:ffff @10.53.0.1 > dig.out.ns4.test$n || ret=1
+grep "trust-anchor-telemetry './IN' from .* 65535" ns1/named.run > /dev/null || ret=1
n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
</para>
</entry>
</row>
+ <row rowsep="0">
+ <entry colname="1">
+ <para><command>trust-anchor-telemetry</command></para>
+ </entry>
+ <entry colname="2">
+ <para>
+ Logs trust-anchor-telemetry requests received by named.
+ </para>
+ </entry>
+ </row>
<row rowsep="0">
<entry colname="1">
<para><command>unmatched</command></para>
client->mortal = ISC_FALSE;
client->sendcb = NULL;
+ if (client->keytag != NULL) {
+ isc_mem_put(client->mctx, client->keytag,
+ client->keytag_len);
+ client->keytag_len = 0;
+ }
+
/*
* Put the client on the inactive list. If we are aiming for
* the "freed" state, it will be removed from the inactive
dns_message_puttemprdataset(client->message,
&client->opt);
}
+ if (client->keytag != NULL) {
+ isc_mem_put(client->mctx, client->keytag,
+ client->keytag_len);
+ client->keytag_len = 0;
+ }
dns_message_destroy(&client->message);
return (ISC_R_SUCCESS);
}
+static isc_result_t
+process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
+
+ if (optlen == 0 || (optlen % 2) != 0) {
+ isc_buffer_forward(buf, (unsigned int)optlen);
+ return (DNS_R_OPTERR);
+ }
+
+ client->keytag = isc_mem_get(client->mctx, optlen);
+ if (client->keytag != NULL) {
+ client->keytag_len = optlen;
+ memmove(client->keytag, isc_buffer_current(buf), optlen);
+ }
+ isc_buffer_forward(buf, (unsigned int)optlen);
+ return (ISC_R_SUCCESS);
+}
+
static isc_result_t
process_opt(ns_client_t *client, dns_rdataset_t *opt) {
dns_rdata_t rdata;
ns_statscounter_padopt);
isc_buffer_forward(&optbuf, optlen);
break;
+ case DNS_OPT_KEY_TAG:
+ result = process_keytag(client, &optbuf,
+ optlen);
+ if (result != ISC_R_SUCCESS) {
+ ns_client_error(client, result);
+ return (result);
+ }
+ ns_stats_increment(client->sctx->nsstats,
+ ns_statscounter_keytagopt);
+ break;
default:
ns_stats_increment(client->sctx->nsstats,
ns_statscounter_otheropt);
ISC_LINK_INIT(client, link);
ISC_LINK_INIT(client, rlink);
ISC_QLINK_INIT(client, ilink);
+ client->keytag = NULL;
+ client->keytag_len = 0;
/*
* We call the init routines for the various kinds of client here,
ISC_QLINK(ns_client_t) ilink;
unsigned char cookie[8];
isc_uint32_t expire;
+ unsigned char *keytag;
+ isc_uint16_t keytag_len;
};
typedef ISC_QUEUE(ns_client_t) client_queue_t;
#define NS_LOGCATEGORY_QUERIES (&ns_categories[3])
#define NS_LOGCATEGORY_UPDATE_SECURITY (&ns_categories[4])
#define NS_LOGCATEGORY_QUERY_ERRORS (&ns_categories[5])
+#define NS_LOGCATEGORY_TAT (&ns_categories[6])
/*
* Backwards compatibility.
ns_statscounter_usedstale = 62,
ns_statscounter_prefetch = 63,
+ ns_statscounter_keytagopt = 64,
- ns_statscounter_max = 64
+ ns_statscounter_max = 65
};
void
{ "unmatched", 0 },
{ "update-security", 0 },
{ "query-errors", 0 },
+ { "trust-anchor-telemetry", 0 },
{ NULL, 0 }
};
zbits &= allowed;
if (zbits != 0) {
isc_netaddr_fromsockaddr(&netaddr,
- &client->peeraddr);
+ &client->peeraddr);
result = rpz_rewrite_ip(client, &netaddr, qtype,
DNS_RPZ_TYPE_CLIENT_IP,
zbits, &rdataset);
return (qctx->result);
}
+static inline void
+log_tat(ns_client_t *client) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char clientbuf[ISC_NETADDR_FORMATSIZE];
+ char classname[DNS_RDATACLASS_FORMATSIZE];
+ isc_netaddr_t netaddr;
+ char *tags = NULL;
+ size_t taglen = 0;
+
+ if (!isc_log_wouldlog(ns_lctx, ISC_LOG_INFO)) {
+ return;
+ }
+
+ if ((client->query.qtype != dns_rdatatype_null ||
+ !dns_name_istat(client->query.qname)) &&
+ (client->keytag == NULL ||
+ client->query.qtype != dns_rdatatype_dnskey))
+ {
+ return;
+ }
+
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+ dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
+ isc_netaddr_format(&client->destaddr, clientbuf, sizeof(clientbuf));
+ dns_rdataclass_format(client->view->rdclass, classname,
+ sizeof(classname));
+
+ if (client->query.qtype == dns_rdatatype_dnskey) {
+ isc_uint16_t keytags = client->keytag_len / 2;
+ size_t len = taglen = sizeof("65000") * keytags + 1;
+ char *cp = tags = isc_mem_get(client->mctx, taglen);
+ int i = 0;
+
+ INSIST(client->keytag != NULL);
+ if (tags != NULL) {
+ while (keytags-- > 0U) {
+ int n;
+ isc_uint16_t keytag;
+ keytag = (client->keytag[i * 2] << 8) |
+ client->keytag[i * 2 + 1];
+ n = snprintf(cp, len, " %u", keytag);
+ if (n > 0 && (size_t)n <= len) {
+ cp += n;
+ len -= n;
+ i++;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+
+ isc_log_write(ns_lctx, NS_LOGCATEGORY_TAT, NS_LOGMODULE_QUERY,
+ ISC_LOG_INFO, "trust-anchor-telemetry '%s/%s' from %s%s",
+ namebuf, classname, clientbuf, tags != NULL? tags : "");
+ if (tags != NULL) {
+ isc_mem_put(client->mctx, tags, taglen);
+ }
+}
+
static inline void
log_query(ns_client_t *client, unsigned int flags, unsigned int extflags) {
char namebuf[DNS_NAME_FORMATSIZE];
client->query.qtype = qtype = rdataset->type;
dns_rdatatypestats_increment(client->sctx->rcvquerystats, qtype);
+ log_tat(client);
+
if (dns_rdatatype_ismeta(qtype)) {
switch (qtype) {
case dns_rdatatype_any: