From 51c6f4b6820beec6f53e48c57ad6bb0ec0a3059d Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 2 Oct 2018 14:13:14 -0700 Subject: [PATCH] extend DNSTAP to record UPDATE requests and responses as a separate type --- bin/named/server.c | 5 ++++- doc/arm/Bv9ARM-book.xml | 9 +++++---- lib/dns/dnstap.c | 18 ++++++++++++++++++ lib/dns/dnstap.proto | 10 ++++++++++ lib/dns/include/dns/dnstap.h | 8 ++++++-- lib/isccfg/namedconf.c | 5 +++-- lib/ns/client.c | 21 +++++++++++++++++---- 7 files changed, 63 insertions(+), 13 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 8acdae9a26..9052672e2b 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3412,11 +3412,14 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) { dt |= DNS_DTTYPE_RQ|DNS_DTTYPE_RR; } else if (strcasecmp(str, "forwarder") == 0) { dt |= DNS_DTTYPE_FQ|DNS_DTTYPE_FR; + } else if (strcasecmp(str, "update") == 0) { + dt |= DNS_DTTYPE_UQ|DNS_DTTYPE_UR; } else if (strcasecmp(str, "all") == 0) { dt |= DNS_DTTYPE_CQ|DNS_DTTYPE_CR| DNS_DTTYPE_AQ|DNS_DTTYPE_AR| DNS_DTTYPE_RQ|DNS_DTTYPE_RR| - DNS_DTTYPE_FQ|DNS_DTTYPE_FR; + DNS_DTTYPE_FQ|DNS_DTTYPE_FR| + DNS_DTTYPE_UQ|DNS_DTTYPE_UR; } obj2 = cfg_tuple_get(obj, "mode"); diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index f34ac57b6b..c012ce88c7 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -4366,10 +4366,11 @@ badresp:1,adberr:0,findfail:0,valfail:0] The dnstap option is a bracketed list of message types to be logged. These may be set differently for each view. Supported types are client, - auth, resolver, and - forwarder. Specifying type - all will cause all dnstap - messages to be logged, regardless of type. + auth, resolver, + forwarder, and update. + Specifying type all will cause all + dnstap messages to be logged, regardless of + type. Each type may take an additional argument to indicate whether diff --git a/lib/dns/dnstap.c b/lib/dns/dnstap.c index 077445d005..cd83d45633 100644 --- a/lib/dns/dnstap.c +++ b/lib/dns/dnstap.c @@ -694,6 +694,10 @@ dnstap_type(dns_dtmsgtype_t msgtype) { return (DNSTAP__MESSAGE__TYPE__TOOL_QUERY); case DNS_DTTYPE_TR: return (DNSTAP__MESSAGE__TYPE__TOOL_RESPONSE); + case DNS_DTTYPE_UQ: + return (DNSTAP__MESSAGE__TYPE__UPDATE_QUERY); + case DNS_DTTYPE_UR: + return (DNSTAP__MESSAGE__TYPE__UPDATE_RESPONSE); default: INSIST(0); } @@ -860,6 +864,7 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, case DNS_DTTYPE_FR: case DNS_DTTYPE_SR: case DNS_DTTYPE_TR: + case DNS_DTTYPE_UR: if (rtime != NULL) t = rtime; @@ -881,6 +886,7 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, case DNS_DTTYPE_RQ: case DNS_DTTYPE_SQ: case DNS_DTTYPE_TQ: + case DNS_DTTYPE_UQ: if (qtime != NULL) t = qtime; @@ -1160,6 +1166,12 @@ dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) { case DNSTAP__MESSAGE__TYPE__TOOL_RESPONSE: d->type = DNS_DTTYPE_TR; break; + case DNSTAP__MESSAGE__TYPE__UPDATE_QUERY: + d->type = DNS_DTTYPE_UQ; + break; + case DNSTAP__MESSAGE__TYPE__UPDATE_RESPONSE: + d->type = DNS_DTTYPE_UR; + break; default: CHECK(DNS_R_BADDNSTAP); } @@ -1316,6 +1328,12 @@ dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest) { case DNS_DTTYPE_TR: CHECK(putstr(dest, "TR ")); break; + case DNS_DTTYPE_UQ: + CHECK(putstr(dest, "UQ ")); + break; + case DNS_DTTYPE_UR: + CHECK(putstr(dest, "UR ")); + break; default: return (DNS_R_BADDNSTAP); } diff --git a/lib/dns/dnstap.proto b/lib/dns/dnstap.proto index 1ed1bb00e2..5280c9b650 100644 --- a/lib/dns/dnstap.proto +++ b/lib/dns/dnstap.proto @@ -165,6 +165,16 @@ message Message { // TOOL_RESPONSE is a DNS response message received by a DNS software // tool from a DNS server, from the perspective of the tool. TOOL_RESPONSE = 12; + + // UPDATE_QUERY is a DNS update query message received from a resolver + // by an authoritative name server, from the perspective of the + // authoritative name server. + UPDATE_QUERY = 13; + + // UPDATE_RESPONSE is a DNS update response message sent from an + // authoritative name server to a resolver, from the perspective of the + // authoritative name server. + UPDATE_RESPONSE = 14; } // One of the Type values described above. diff --git a/lib/dns/include/dns/dnstap.h b/lib/dns/include/dns/dnstap.h index bc3b79e9eb..e27c95e8a0 100644 --- a/lib/dns/include/dns/dnstap.h +++ b/lib/dns/include/dns/dnstap.h @@ -73,13 +73,17 @@ struct fstrm_iothr_options; #define DNS_DTTYPE_FR 0x0200 #define DNS_DTTYPE_TQ 0x0400 #define DNS_DTTYPE_TR 0x0800 +#define DNS_DTTYPE_UQ 0x1000 +#define DNS_DTTYPE_UR 0x2000 #define DNS_DTTYPE_QUERY \ (DNS_DTTYPE_SQ|DNS_DTTYPE_CQ|DNS_DTTYPE_AQ|\ - DNS_DTTYPE_RQ|DNS_DTTYPE_FQ|DNS_DTTYPE_TQ) + DNS_DTTYPE_RQ|DNS_DTTYPE_FQ|DNS_DTTYPE_TQ|\ + DNS_DTTYPE_UQ) #define DNS_DTTYPE_RESPONSE \ (DNS_DTTYPE_SR|DNS_DTTYPE_CR|DNS_DTTYPE_AR|\ - DNS_DTTYPE_RR|DNS_DTTYPE_FR|DNS_DTTYPE_TR) + DNS_DTTYPE_RR|DNS_DTTYPE_FR|DNS_DTTYPE_TR|\ + DNS_DTTYPE_UR) #define DNS_DTTYPE_ALL \ (DNS_DTTYPE_QUERY|DNS_DTTYPE_RESPONSE) diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index c6b1072d88..d6881de77f 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1276,10 +1276,11 @@ static cfg_type_t cfg_type_resppadding = { * ... * } * - * ... where message type is one of: client, resolver, auth, forwarder, all + * ... where message type is one of: client, resolver, auth, forwarder, + * update, all */ static const char *dnstap_types[] = { - "all", "auth", "client", "forwarder", "resolver", NULL + "all", "auth", "client", "forwarder", "resolver", "update", NULL }; static const char *dnstap_modes[] = { "query", "response", NULL }; diff --git a/lib/ns/client.c b/lib/ns/client.c index bcf022e1ee..b5c3175dc2 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -1225,10 +1225,13 @@ client_send(ns_client_t *client) { isc_buffer_usedregion(&b, &zr); } - if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) + if (client->message->opcode == dns_opcode_update) { + dtmsgtype = DNS_DTTYPE_UR; + } else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) { dtmsgtype = DNS_DTTYPE_CR; - else + } else { dtmsgtype = DNS_DTTYPE_AR; + } #endif /* HAVE_DNSTAP */ if (cleanup_cctx) { @@ -1269,9 +1272,11 @@ client_send(ns_client_t *client) { break; } } else { - respsize = isc_buffer_usedlength(&buffer); - result = client_sendpkg(client, &buffer); #ifdef HAVE_DNSTAP + /* + * Log dnstap data first, because client_sendpkg() may + * leave client->view set to NULL. + */ if (client->view != NULL) { dns_dt_send(client->view, dtmsgtype, &client->peeraddr, @@ -1281,6 +1286,9 @@ client_send(ns_client_t *client) { } #endif /* HAVE_DNSTAP */ + respsize = isc_buffer_usedlength(&buffer); + result = client_sendpkg(client, &buffer); + switch (isc_sockaddr_pf(&client->peeraddr)) { case AF_INET: isc_stats_increment(client->sctx->udpoutstats4, @@ -2847,6 +2855,11 @@ ns__client_request(isc_task_t *task, isc_event_t *event) { break; case dns_opcode_update: CTRACE("update"); +#ifdef HAVE_DNSTAP + dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr, + &client->destsockaddr, TCP_CLIENT(client), NULL, + &client->requesttime, NULL, buffer); +#endif /* HAVE_DNSTAP */ ns_client_settimeout(client, 60); ns_update_start(client, sigresult); break;