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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user