diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index 52685c0b23..887f21a1ed 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -339,6 +339,21 @@ init_desc(void) { "RPZRewrites"); SET_NSSTATDESC(udp, "UDP queries received", "QryUDP"); SET_NSSTATDESC(tcp, "TCP queries received", "QryTCP"); + SET_NSSTATDESC(dot, "DoT queries received", "QryDoT"); + SET_NSSTATDESC(doh, "DoH queries received", "QryDoH"); + SET_NSSTATDESC(dohplain, "DoH-Plain queries received", "QryDoHPlain"); + SET_NSSTATDESC(proxyudp, "PROXYv2 UDP queries received", "QryProxyUDP"); + SET_NSSTATDESC(proxytcp, "PROXYv2 TCP queries received", "QryProxyTCP"); + SET_NSSTATDESC(proxydot, "PROXYv2 DoT queries received", "QryProxyDoT"); + SET_NSSTATDESC(proxydoh, "PROXYv2 DoH queries received", "QryProxyDoH"); + SET_NSSTATDESC(proxydohplain, "PROXYv2/DoH-Plain queries received", + "QryProxyDoHPlain"); + SET_NSSTATDESC(encryptedproxydot, + "Encrypted PROXYv2 DoT queries received", + "QryEncryptedProxyDoT"); + SET_NSSTATDESC(encryptedproxydoh, + "Encrypted PROXYv2 DoH queries received", + "QryEncryptedProxyDoH"); SET_NSSTATDESC(nsidopt, "NSID option received", "NSIDOpt"); SET_NSSTATDESC(expireopt, "Expire option received", "ExpireOpt"); SET_NSSTATDESC(keepaliveopt, "EDNS TCP keepalive option received", diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 50b2b784e8..21babdebad 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -657,6 +657,12 @@ isc_nm_is_proxy_handle(isc_nmhandle_t *handle); * connection. */ +isc_nm_proxy_type_t +isc_nmhandle_proxy_type(isc_nmhandle_t *handle); +/*%< + * Returns the PROXYv2 type associated with 'handle'. + */ + isc_result_t isc_nm_listentls(isc_nm_t *mgr, uint32_t workers, isc_sockaddr_t *iface, isc_nm_accept_cb_t accept_cb, void *accept_cbarg, int backlog, diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 70519621c7..c8e67fafda 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -2397,6 +2397,26 @@ isc_nm_socket_type(const isc_nmhandle_t *handle) { return handle->sock->type; } +isc_nm_proxy_type_t +isc_nmhandle_proxy_type(isc_nmhandle_t *handle) { + isc_nmhandle_t *proxyhandle; + + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + proxyhandle = get_proxy_handle(handle); + + if (proxyhandle == NULL) { + return ISC_NM_PROXY_NONE; + } + + if (isc_nm_has_encryption(proxyhandle)) { + return ISC_NM_PROXY_ENCRYPTED; + } + + return ISC_NM_PROXY_PLAIN; +} + bool isc_nm_has_encryption(const isc_nmhandle_t *handle) { REQUIRE(VALID_NMHANDLE(handle)); diff --git a/lib/ns/include/ns/stats.h b/lib/ns/include/ns/stats.h index 766ba37a56..5dabdb216f 100644 --- a/lib/ns/include/ns/stats.h +++ b/lib/ns/include/ns/stats.h @@ -114,7 +114,19 @@ enum { ns_statscounter_recurshighwater = 68, - ns_statscounter_max = 69, + ns_statscounter_dot = 69, + ns_statscounter_doh = 70, + ns_statscounter_dohplain = 71, + + ns_statscounter_proxyudp = 72, + ns_statscounter_proxytcp = 73, + ns_statscounter_proxydot = 74, + ns_statscounter_proxydoh = 75, + ns_statscounter_proxydohplain = 76, + ns_statscounter_encryptedproxydot = 77, + ns_statscounter_encryptedproxydoh = 78, + + ns_statscounter_max = 79, }; void diff --git a/lib/ns/query.c b/lib/ns/query.c index bf11644c75..ee7b83a4f7 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -5622,11 +5622,84 @@ ns__query_start(query_ctx_t *qctx) { } qctx->client->query.authdbset = true; - /* Track TCP vs UDP stats per zone */ - if (TCP(qctx->client)) { - inc_stats(qctx->client, ns_statscounter_tcp); - } else { + isc_nmhandle_t *handle = qctx->client->handle; + + /* Track protocol stats per zone */ + switch (isc_nm_socket_type(handle)) { + case isc_nm_httpsocket: + switch (isc_nmhandle_proxy_type(handle)) { + case ISC_NM_PROXY_ENCRYPTED: + /* Encrypted PROXYv2 cannot carry plain DoH */ + INSIST(isc_nm_has_encryption(handle)); + inc_stats(qctx->client, + ns_statscounter_encryptedproxydoh); + break; + case ISC_NM_PROXY_PLAIN: + if (isc_nm_has_encryption(handle)) { + inc_stats(qctx->client, + ns_statscounter_proxydoh); + } else { + inc_stats( + qctx->client, + ns_statscounter_proxydohplain); + } + break; + case ISC_NM_PROXY_NONE: + if (isc_nm_has_encryption(handle)) { + inc_stats(qctx->client, + ns_statscounter_doh); + } else { + inc_stats(qctx->client, + ns_statscounter_dohplain); + } + break; + } + break; + case isc_nm_streamdnssocket: + switch (isc_nmhandle_proxy_type(handle)) { + case ISC_NM_PROXY_ENCRYPTED: + inc_stats(qctx->client, + ns_statscounter_encryptedproxydot); + break; + case ISC_NM_PROXY_PLAIN: + if (isc_nm_has_encryption(handle)) { + inc_stats(qctx->client, + ns_statscounter_proxydot); + + } else { + /* + * If the StreamDNS socket doesn't have + * encryption, it has to be plain TCP + * DNS. + */ + inc_stats(qctx->client, + ns_statscounter_proxytcp); + } + break; + case ISC_NM_PROXY_NONE: + if (isc_nm_has_encryption(handle)) { + inc_stats(qctx->client, + ns_statscounter_dot); + } else { + /* + * If the StreamDNS socket doesn't have + * encryption, it has to be plain TCP + * DNS. + */ + inc_stats(qctx->client, + ns_statscounter_tcp); + } + break; + } + break; + case isc_nm_proxyudpsocket: + inc_stats(qctx->client, ns_statscounter_proxyudp); + break; + case isc_nm_udpsocket: inc_stats(qctx->client, ns_statscounter_udp); + break; + default: + UNREACHABLE(); } }