]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Emit and read correct DoT and DoH dnstap entries
authorAydın Mercan <aydin@isc.org>
Thu, 1 Feb 2024 07:20:12 +0000 (10:20 +0300)
committerAydın Mercan <aydin@isc.org>
Fri, 26 Apr 2024 13:12:29 +0000 (16:12 +0300)
Other protocols still pretend to be TCP/UDP.
This only causes a difference when using dnstap-read on a file with DoQ
or DNSCrypt entries

bin/tools/dnstap-read.c
lib/dns/dnstap.c
lib/dns/include/dns/dnstap.h
lib/dns/resolver.c
lib/ns/client.c
tests/dns/dnstap_test.c

index 1df44dad6f94479f37f3bb7a70ef02c54ebeb33f..cbc82c33c50d64a668de36151bf18f0c422fe3b9 100644 (file)
@@ -269,7 +269,8 @@ print_yaml(dns_dtdata_t *dt) {
                }
        }
 
-       printf("  socket_protocol: %s\n", dt->tcp ? "TCP" : "UDP");
+       printf("  socket_protocol: %s\n",
+              dt->transport == DNS_TRANSPORT_UDP ? "UDP" : "TCP");
 
        if (m->has_query_address) {
                ProtobufCBinaryData *ip = &m->query_address;
index 887c017996bca029295e190f50ba02c410cc9a48..bc0be5fe6a4ef8e9cb7dd749ff44de7ded9e50d4 100644 (file)
@@ -643,7 +643,7 @@ cpbuf(isc_buffer_t *buf, ProtobufCBinaryData *p, protobuf_c_boolean *has) {
 }
 
 static void
-setaddr(dns_dtmsg_t *dm, isc_sockaddr_t *sa, bool tcp,
+setaddr(dns_dtmsg_t *dm, isc_sockaddr_t *sa, dns_transport_type_t transport,
        ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr, uint32_t *port,
        protobuf_c_boolean *has_port) {
        int family = isc_sockaddr_pf(sa);
@@ -664,10 +664,22 @@ setaddr(dns_dtmsg_t *dm, isc_sockaddr_t *sa, bool tcp,
                *port = ntohs(sa->type.sin.sin_port);
        }
 
-       if (tcp) {
+       switch (transport) {
+       case DNS_TRANSPORT_TCP:
                dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
-       } else {
+               break;
+       case DNS_TRANSPORT_UDP:
                dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
+               break;
+       case DNS_TRANSPORT_TLS:
+               dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOT;
+               break;
+       case DNS_TRANSPORT_HTTP:
+               dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOH;
+               break;
+       case DNS_TRANSPORT_NONE:
+       case DNS_TRANSPORT_COUNT:
+               UNREACHABLE();
        }
 
        dm->m.has_socket_protocol = 1;
@@ -732,8 +744,9 @@ unlock_and_return:
 
 void
 dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, isc_sockaddr_t *qaddr,
-           isc_sockaddr_t *raddr, bool tcp, isc_region_t *zone,
-           isc_time_t *qtime, isc_time_t *rtime, isc_buffer_t *buf) {
+           isc_sockaddr_t *raddr, dns_transport_type_t transport,
+           isc_region_t *zone, isc_time_t *qtime, isc_time_t *rtime,
+           isc_buffer_t *buf) {
        isc_time_t now, *t;
        dns_dtmsg_t dm;
 
@@ -833,12 +846,12 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, isc_sockaddr_t *qaddr,
        }
 
        if (qaddr != NULL) {
-               setaddr(&dm, qaddr, tcp, &dm.m.query_address,
+               setaddr(&dm, qaddr, transport, &dm.m.query_address,
                        &dm.m.has_query_address, &dm.m.query_port,
                        &dm.m.has_query_port);
        }
        if (raddr != NULL) {
-               setaddr(&dm, raddr, tcp, &dm.m.response_address,
+               setaddr(&dm, raddr, transport, &dm.m.response_address,
                        &dm.m.has_response_address, &dm.m.response_port,
                        &dm.m.has_response_port);
        }
@@ -1162,11 +1175,27 @@ dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) {
                        protobuf_c_enum_descriptor_get_value(
                                &dnstap__socket_protocol__descriptor,
                                m->socket_protocol);
-               if (type != NULL && type->value == DNSTAP__SOCKET_PROTOCOL__TCP)
-               {
-                       d->tcp = true;
+
+               if (type != NULL) {
+                       switch (type->value) {
+                       case DNSTAP__SOCKET_PROTOCOL__DNSCryptUDP:
+                       case DNSTAP__SOCKET_PROTOCOL__DOQ:
+                       case DNSTAP__SOCKET_PROTOCOL__UDP:
+                               d->transport = DNS_TRANSPORT_UDP;
+                               break;
+                       case DNSTAP__SOCKET_PROTOCOL__DNSCryptTCP:
+                       case DNSTAP__SOCKET_PROTOCOL__TCP:
+                               d->transport = DNS_TRANSPORT_TCP;
+                               break;
+                       case DNSTAP__SOCKET_PROTOCOL__DOT:
+                               d->transport = DNS_TRANSPORT_TLS;
+                               break;
+                       case DNSTAP__SOCKET_PROTOCOL__DOH:
+                               d->transport = DNS_TRANSPORT_HTTP;
+                               break;
+                       }
                } else {
-                       d->tcp = false;
+                       d->transport = DNS_TRANSPORT_UDP;
                }
        }
 
@@ -1292,10 +1321,24 @@ dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest) {
        CHECK(putstr(dest, " "));
 
        /* Protocol */
-       if (d->tcp) {
-               CHECK(putstr(dest, "TCP "));
-       } else {
+       switch (d->transport) {
+       case DNS_TRANSPORT_NONE:
+               CHECK(putstr(dest, "NUL "));
+               break;
+       case DNS_TRANSPORT_UDP:
                CHECK(putstr(dest, "UDP "));
+               break;
+       case DNS_TRANSPORT_TCP:
+               CHECK(putstr(dest, "TCP "));
+               break;
+       case DNS_TRANSPORT_TLS:
+               CHECK(putstr(dest, "DOT "));
+               break;
+       case DNS_TRANSPORT_HTTP:
+               CHECK(putstr(dest, "DOH "));
+               break;
+       case DNS_TRANSPORT_COUNT:
+               UNREACHABLE();
        }
 
        /* Message size */
index 0d937c4e00c19a0d5b1ccf87812fe7ce54920d6c..aa80cbba788da24e6272691edd8ca84f493f20a8 100644 (file)
@@ -39,6 +39,7 @@ struct fstrm_iothr_options;
 #include <dns/name.h>
 #include <dns/rdataclass.h>
 #include <dns/rdatatype.h>
+#include <dns/transport.h>
 #include <dns/types.h>
 
 /*%
@@ -93,9 +94,9 @@ struct dns_dtdata {
 
        void *frame;
 
-       bool            query;
-       bool            tcp;
-       dns_dtmsgtype_t type;
+       bool                 query;
+       dns_dtmsgtype_t      type;
+       dns_transport_type_t transport;
 
        isc_time_t qtime;
        isc_time_t rtime;
@@ -262,8 +263,9 @@ dns_dt_getstats(dns_dtenv_t *env, isc_stats_t **statsp);
 
 void
 dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, isc_sockaddr_t *qaddr,
-           isc_sockaddr_t *dstaddr, bool tcp, isc_region_t *zone,
-           isc_time_t *qtime, isc_time_t *rtime, isc_buffer_t *buf);
+           isc_sockaddr_t *dstaddr, dns_transport_type_t transport,
+           isc_region_t *zone, isc_time_t *qtime, isc_time_t *rtime,
+           isc_buffer_t *buf);
 /*%<
  * Sends a dnstap message to the log, if 'msgtype' is one of the message
  * types represented in 'view->dttypes'.
index 6fe8ba448bd396ede008957ce92fa81d0e92e96c..fd5cc04be1c525d25b158945145ee394e666d1f3 100644 (file)
@@ -2319,6 +2319,7 @@ resquery_send(resquery_t *query) {
 #ifdef HAVE_DNSTAP
        isc_sockaddr_t localaddr, *la = NULL;
        unsigned char zone[DNS_NAME_MAXWIRE];
+       dns_transport_type_t transport_type;
        dns_dtmsgtype_t dtmsgtype;
        isc_region_t zr;
        isc_buffer_t zb;
@@ -2717,8 +2718,17 @@ resquery_send(resquery_t *query) {
                la = &localaddr;
        }
 
+       if (query->addrinfo->transport != NULL) {
+               transport_type =
+                       dns_transport_get_type(query->addrinfo->transport);
+       } else if ((query->options & DNS_FETCHOPT_TCP) != 0) {
+               transport_type = DNS_TRANSPORT_TCP;
+       } else {
+               transport_type = DNS_TRANSPORT_UDP;
+       }
+
        dns_dt_send(fctx->res->view, dtmsgtype, la, &query->addrinfo->sockaddr,
-                   tcp, &zr, &query->start, NULL, &buffer);
+                   transport_type, &zr, &query->start, NULL, &buffer);
 #endif /* HAVE_DNSTAP */
 
        return (ISC_R_SUCCESS);
@@ -9556,6 +9566,7 @@ rctx_logpacket(respctx_t *rctx) {
        isc_result_t result;
        isc_sockaddr_t localaddr, *la = NULL;
        unsigned char zone[DNS_NAME_MAXWIRE];
+       dns_transport_type_t transport_type;
        dns_dtmsgtype_t dtmsgtype;
        dns_compress_t cctx;
        isc_region_t zr;
@@ -9594,9 +9605,17 @@ rctx_logpacket(respctx_t *rctx) {
                la = &localaddr;
        }
 
+       if (rctx->query->addrinfo->transport != NULL) {
+               transport_type = dns_transport_get_type(
+                       rctx->query->addrinfo->transport);
+       } else if ((rctx->query->options & DNS_FETCHOPT_TCP) != 0) {
+               transport_type = DNS_TRANSPORT_TCP;
+       } else {
+               transport_type = DNS_TRANSPORT_UDP;
+       }
+
        dns_dt_send(fctx->res->view, dtmsgtype, la,
-                   &rctx->query->addrinfo->sockaddr,
-                   ((rctx->query->options & DNS_FETCHOPT_TCP) != 0), &zr,
+                   &rctx->query->addrinfo->sockaddr, transport_type, &zr,
                    &rctx->query->start, NULL, &rctx->buffer);
 #endif /* HAVE_DNSTAP */
 }
index 34ab13caa333768c0989b6aa667e2d66fea05a11..b129db00c371fa6c5effb5fa08178444186c47d5 100644 (file)
@@ -123,6 +123,40 @@ static void
 compute_cookie(ns_client_t *client, uint32_t when, const unsigned char *secret,
               isc_buffer_t *buf);
 
+static dns_transport_type_t
+ns_client_transport_type(const ns_client_t *client) {
+       REQUIRE(client->handle != NULL);
+
+       switch (isc_nm_socket_type(client->handle)) {
+       case isc_nm_udpsocket:
+       case isc_nm_udplistener:
+       case isc_nm_proxyudpsocket:
+       case isc_nm_proxyudplistener:
+               return DNS_TRANSPORT_UDP;
+       case isc_nm_tlssocket:
+       case isc_nm_tlslistener:
+               return DNS_TRANSPORT_TLS;
+       case isc_nm_httpsocket:
+       case isc_nm_httplistener:
+               return DNS_TRANSPORT_HTTP;
+       case isc_nm_streamdnslistener:
+       case isc_nm_streamdnssocket:
+       case isc_nm_proxystreamlistener:
+       case isc_nm_proxystreamsocket:
+               /* If it isn't DoT, it is DNS-over-TCP */
+               if (isc_nm_has_encryption(client->handle)) {
+                       return DNS_TRANSPORT_TLS;
+               }
+               FALLTHROUGH;
+       case isc_nm_tcpsocket:
+       case isc_nm_tcplistener:
+               return DNS_TRANSPORT_TCP;
+       case isc_nm_maxsocket:
+       case isc_nm_nonesocket:
+               UNREACHABLE();
+       }
+}
+
 void
 ns_client_recursing(ns_client_t *client) {
        REQUIRE(NS_CLIENT_VALID(client));
@@ -396,6 +430,10 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
        isc_buffer_t buffer;
        isc_region_t r;
        isc_region_t *mr = NULL;
+#ifdef HAVE_DNSTAP
+       dns_transport_type_t transport_type;
+       dns_dtmsgtype_t dtmsgtype;
+#endif
 
        REQUIRE(NS_CLIENT_VALID(client));
 
@@ -427,8 +465,8 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
 
 #ifdef HAVE_DNSTAP
        if (client->view != NULL) {
-               bool tcp = TCP_CLIENT(client);
-               dns_dtmsgtype_t dtmsgtype;
+               transport_type = ns_client_transport_type(client);
+
                if (client->message->opcode == dns_opcode_update) {
                        dtmsgtype = DNS_DTTYPE_UR;
                } else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
@@ -437,7 +475,7 @@ ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
                        dtmsgtype = DNS_DTTYPE_AR;
                }
                dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
-                           &client->destsockaddr, tcp, NULL,
+                           &client->destsockaddr, transport_type, NULL,
                            &client->requesttime, NULL, &buffer);
        }
 #endif
@@ -470,6 +508,7 @@ ns_client_send(ns_client_t *client) {
        dns_aclenv_t *env = NULL;
 #ifdef HAVE_DNSTAP
        unsigned char zone[DNS_NAME_MAXWIRE];
+       dns_transport_type_t transport_type;
        dns_dtmsgtype_t dtmsgtype;
        isc_region_t zr;
 #endif /* HAVE_DNSTAP */
@@ -637,6 +676,8 @@ renderend:
        } else {
                dtmsgtype = DNS_DTTYPE_AR;
        }
+
+       transport_type = ns_client_transport_type(client);
 #endif /* HAVE_DNSTAP */
 
        if (cleanup_cctx) {
@@ -650,7 +691,7 @@ renderend:
 #ifdef HAVE_DNSTAP
                if (client->view != NULL) {
                        dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
-                                   &client->destsockaddr, true, &zr,
+                                   &client->destsockaddr, transport_type, &zr,
                                    &client->requesttime, NULL, &buffer);
                }
 #endif /* HAVE_DNSTAP */
@@ -679,7 +720,7 @@ renderend:
                 */
                if (client->view != NULL) {
                        dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
-                                   &client->destsockaddr, false, &zr,
+                                   &client->destsockaddr, transport_type, &zr,
                                    &client->requesttime, NULL, &buffer);
                }
 #endif /* HAVE_DNSTAP */
@@ -1652,6 +1693,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
        size_t reqsize;
        dns_aclenv_t *env = NULL;
 #ifdef HAVE_DNSTAP
+       dns_transport_type_t transport_type;
        dns_dtmsgtype_t dtmsgtype;
 #endif /* ifdef HAVE_DNSTAP */
        static const char *ra_reasons[] = {
@@ -2210,6 +2252,10 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
                }
        }
 
+#ifdef HAVE_DNSTAP
+       transport_type = ns_client_transport_type(client);
+#endif /* HAVE_DNSTAP */
+
        /*
         * Dispatch the request.
         */
@@ -2224,7 +2270,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
                }
 
                dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
-                           &client->destsockaddr, TCP_CLIENT(client), NULL,
+                           &client->destsockaddr, transport_type, NULL,
                            &client->requesttime, NULL, buffer);
 #endif /* HAVE_DNSTAP */
 
@@ -2234,7 +2280,7 @@ ns_client_request(isc_nmhandle_t *handle, isc_result_t eresult,
                CTRACE("update");
 #ifdef HAVE_DNSTAP
                dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr,
-                           &client->destsockaddr, TCP_CLIENT(client), NULL,
+                           &client->destsockaddr, transport_type, NULL,
                            &client->requesttime, NULL, buffer);
 #endif /* HAVE_DNSTAP */
                ns_client_settimeout(client, 60);
index 8c82461b28edd2b930a97f6809c2a012fb6dba0f..6d37979c3d6f5fa9cf82da384c07dbccd1fc9a69 100644 (file)
@@ -230,14 +230,20 @@ ISC_RUN_TEST_IMPL(dns_dt_send) {
                        break;
                }
 
-               dns_dt_send(view, dt, q, r, false, &zr, &p, &f, m);
-               dns_dt_send(view, dt, q, r, false, &zr, NULL, &f, m);
-               dns_dt_send(view, dt, q, r, false, &zr, &p, NULL, m);
-               dns_dt_send(view, dt, q, r, false, &zr, NULL, NULL, m);
-               dns_dt_send(view, dt, q, r, true, &zr, &p, &f, m);
-               dns_dt_send(view, dt, q, r, true, &zr, NULL, &f, m);
-               dns_dt_send(view, dt, q, r, true, &zr, &p, NULL, m);
-               dns_dt_send(view, dt, q, r, true, &zr, NULL, NULL, m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_UDP, &zr, &p, &f, m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_UDP, &zr, NULL, &f,
+                           m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_UDP, &zr, &p, NULL,
+                           m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_UDP, &zr, NULL, NULL,
+                           m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_TCP, &zr, &p, &f, m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_TCP, &zr, NULL, &f,
+                           m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_TCP, &zr, &p, NULL,
+                           m);
+               dns_dt_send(view, dt, q, r, DNS_TRANSPORT_TCP, &zr, NULL, NULL,
+                           m);
        }
 
        dns_dt_detach(&view->dtenv);