2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

4424. [experimental] Named now sends _ta-XXXX.<trust-anchor>/NULL queries

to provide feedback to the trust-anchor administrators
                        about how key rollovers are progressing as per
                        draft-ietf-dnsop-edns-key-tag-02.  This can be
                        disabled using 'trust-anchor-telemetry no;'.
                        [RT #40583]
This commit is contained in:
Mark Andrews
2016-07-22 20:02:17 +10:00
parent 9616761417
commit f20179857a
19 changed files with 422 additions and 85 deletions

View File

@@ -4103,6 +4103,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
else
INSIST(0);
obj = NULL;
result = ns_config_get(maps, "trust-anchor-telemetry", &obj);
INSIST(result == ISC_R_SUCCESS);
view->trust_anchor_telemetry = cfg_obj_asboolean(obj);
/*
* Set sources where additional data and CNAME/DNAME
* targets for authoritative answers may be found.
@@ -5834,6 +5839,186 @@ heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) {
}
}
typedef struct {
isc_mem_t *mctx;
isc_task_t *task;
dns_rdataset_t rdataset;
dns_rdataset_t sigrdataset;
dns_fetch_t *fetch;
} ns_tat_t;
static int
cid(const void *a, const void *b) {
const isc_uint16_t ida = *(const isc_uint16_t *)a;
const isc_uint16_t idb = *(const isc_uint16_t *)b;
if (ida < idb)
return (-1);
else if (ida > idb)
return (1);
else
return (0);
}
static void
tat_done(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent;
ns_tat_t *tat;
UNUSED(task);
INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
INSIST(event->ev_arg != NULL);
tat = event->ev_arg;
devent = (dns_fetchevent_t *) event;
/* Free resources which are not of interest */
if (devent->node != NULL)
dns_db_detachnode(devent->db, &devent->node);
if (devent->db != NULL)
dns_db_detach(&devent->db);
isc_event_free(&event);
dns_resolver_destroyfetch(&tat->fetch);
if (dns_rdataset_isassociated(&tat->rdataset))
dns_rdataset_disassociate(&tat->rdataset);
if (dns_rdataset_isassociated(&tat->sigrdataset))
dns_rdataset_disassociate(&tat->sigrdataset);
isc_task_detach(&tat->task);
isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat));
}
struct dotat_arg {
dns_view_t *view;
isc_task_t *task;
};
static void
dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
isc_result_t result;
dns_keynode_t *firstnode = keynode;
dns_keynode_t *nextnode;
unsigned int i, n = 0;
char label[64], namebuf[DNS_NAME_FORMATSIZE];
dns_fixedname_t fixed;
dns_name_t *tatname;
isc_uint16_t ids[12]; /* Only 12 id's will fit in a label. */
int m;
ns_tat_t *tat;
dns_name_t *name = NULL;
struct dotat_arg *dotat_arg = arg;
dns_view_t *view;
isc_task_t *task;
isc_textregion_t r;
REQUIRE(keytable != NULL);
REQUIRE(keynode != NULL);
REQUIRE(arg != NULL);
view = dotat_arg->view;
task = dotat_arg->task;
do {
dst_key_t *key = dns_keynode_key(keynode);
if (key != NULL) {
name = dst_key_name(key);
if (n < (sizeof(ids)/sizeof(ids[0]))) {
ids[n] = dst_key_id(key);
n++;
}
}
nextnode = NULL;
(void)dns_keytable_nextkeynode(keytable, keynode, &nextnode);
if (keynode != firstnode)
dns_keytable_detachkeynode(keytable, &keynode);
keynode = nextnode;
} while (keynode != NULL);
if (n == 0)
return;
if (n > 1)
qsort(ids, n, sizeof(ids[0]), cid);
/*
* Encoded as "_ta-xxxx\(-xxxx\)*" where xxxx is the hex version of
* of the keyid.
*/
label[0] = 0;
r.base = label;
r.length = sizeof(label);;
m = snprintf(r.base, r.length, "_ta");
if (m < 0 || (unsigned)m > r.length)
return;
isc_textregion_consume(&r, m);
for (i = 0; i < n; i++) {
m = snprintf(r.base, r.length, "-%04x", ids[i]);
if (m < 0 || (unsigned)m > r.length)
return;
isc_textregion_consume(&r, m);
}
dns_fixedname_init(&fixed);
tatname = dns_fixedname_name(&fixed);
result = dns_name_fromstring2(tatname, label, name, 0, NULL);
if (result != ISC_R_SUCCESS)
return;
dns_name_format(tatname, namebuf, sizeof(namebuf));
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
ISC_LOG_INFO,
"%s: sending trust-anchor-telemetry query '%s/NULL'",
view->name, namebuf);
tat = isc_mem_get(dotat_arg->view->mctx, sizeof(*tat));
if (tat == NULL)
return;
tat->mctx = NULL;
tat->task = NULL;
tat->fetch = NULL;
dns_rdataset_init(&tat->rdataset);
dns_rdataset_init(&tat->sigrdataset);
isc_mem_attach(dotat_arg->view->mctx, &tat->mctx);
isc_task_attach(task, &tat->task);
result = dns_resolver_createfetch(view->resolver, tatname,
dns_rdatatype_null, NULL, NULL,
NULL, 0, tat->task, tat_done, tat,
&tat->rdataset, &tat->sigrdataset,
&tat->fetch);
if (result != ISC_R_SUCCESS) {
isc_task_detach(&tat->task);
isc_mem_putanddetach(&tat->mctx, tat, sizeof(*tat));
}
}
static void
tat_timer_tick(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
ns_server_t *server = (ns_server_t *) event->ev_arg;
struct dotat_arg arg;
dns_view_t *view;
dns_keytable_t *secroots = NULL;
isc_event_free(&event);
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
if (!view->trust_anchor_telemetry)
continue;
result = dns_view_getsecroots(view, &secroots);
if (result != ISC_R_SUCCESS)
continue;
arg.view = view;
arg.task = task;
(void)dns_keytable_forall(secroots, dotat, &arg);
dns_keytable_detach(&secroots);
}
}
static void
pps_timer_tick(isc_task_t *task, isc_event_t *event) {
static unsigned int oldrequests = 0;
@@ -7257,6 +7442,10 @@ load_configuration(const char *filename, ns_server_t *server,
CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker, NULL,
&interval, ISC_FALSE));
isc_interval_set(&interval, ns_g_tat_interval, 0);
CHECK(isc_timer_reset(server->tat_timer, isc_timertype_ticker, NULL,
&interval, ISC_FALSE));
/*
* Write the PID file.
*/
@@ -7970,6 +8159,11 @@ run_server(isc_task_t *task, isc_event_t *event) {
server, &server->heartbeat_timer),
"creating heartbeat timer");
CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive,
NULL, NULL, server->task, tat_timer_tick,
server, &server->tat_timer),
"creating trust anchor telemetry timer");
CHECKFATAL(isc_timer_create(ns_g_timermgr, isc_timertype_inactive,
NULL, NULL, server->task, pps_timer_tick,
server, &server->pps_timer),
@@ -8059,6 +8253,7 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
isc_timer_detach(&server->interface_timer);
isc_timer_detach(&server->heartbeat_timer);
isc_timer_detach(&server->pps_timer);
isc_timer_detach(&server->tat_timer);
ns_interfacemgr_shutdown(server->interfacemgr);
ns_interfacemgr_detach(&server->interfacemgr);
@@ -8173,6 +8368,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->interface_timer = NULL;
server->heartbeat_timer = NULL;
server->pps_timer = NULL;
server->tat_timer = NULL;
server->interface_interval = 0;
server->heartbeat_interval = 0;