From: Charles-Henri Bruyand Date: Mon, 15 Jan 2024 16:56:44 +0000 (+0100) Subject: dnsdist: properly set protocol for dnstap and protobuf logging when using DoQ or... X-Git-Tag: dnsdist-1.9.0-rc1~31^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a261cdeb23be35558a5c32fe46e3705b3f0c8fca;p=thirdparty%2Fpdns.git dnsdist: properly set protocol for dnstap and protobuf logging when using DoQ or DoH3 --- diff --git a/pdns/dnsdist-lua-actions.cc b/pdns/dnsdist-lua-actions.cc index e6da31b6c8..fcf4f6a93a 100644 --- a/pdns/dnsdist-lua-actions.cc +++ b/pdns/dnsdist-lua-actions.cc @@ -1491,7 +1491,7 @@ static DnstapMessage::ProtocolType ProtocolToDNSTap(dnsdist::Protocol protocol) else if (protocol == dnsdist::Protocol::DoT) { return DnstapMessage::ProtocolType::DoT; } - else if (protocol == dnsdist::Protocol::DoH) { + else if (protocol == dnsdist::Protocol::DoH || protocol == dnsdist::Protocol::DoH3) { return DnstapMessage::ProtocolType::DoH; } else if (protocol == dnsdist::Protocol::DNSCryptUDP) { @@ -1500,6 +1500,9 @@ static DnstapMessage::ProtocolType ProtocolToDNSTap(dnsdist::Protocol protocol) else if (protocol == dnsdist::Protocol::DNSCryptTCP) { return DnstapMessage::ProtocolType::DNSCryptTCP; } + else if (protocol == dnsdist::Protocol::DoQ) { + return DnstapMessage::ProtocolType::DoQ; + } throw std::runtime_error("Unhandled protocol for dnstap: " + protocol.toPrettyString()); } diff --git a/pdns/dnsdist-protobuf.cc b/pdns/dnsdist-protobuf.cc index 453cba87f5..8b84f20474 100644 --- a/pdns/dnsdist-protobuf.cc +++ b/pdns/dnsdist-protobuf.cc @@ -149,6 +149,11 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const } else if (distProto == dnsdist::Protocol::DoH) { protocol = pdns::ProtoZero::Message::TransportProtocol::DoH; + m.setHTTPVersion(pdns::ProtoZero::Message::HTTPVersion::HTTP2); + } + else if (distProto == dnsdist::Protocol::DoH3) { + protocol = pdns::ProtoZero::Message::TransportProtocol::DoH; + m.setHTTPVersion(pdns::ProtoZero::Message::HTTPVersion::HTTP3); } else if (distProto == dnsdist::Protocol::DNSCryptUDP) { protocol = pdns::ProtoZero::Message::TransportProtocol::DNSCryptUDP; @@ -156,6 +161,9 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const else if (distProto == dnsdist::Protocol::DNSCryptTCP) { protocol = pdns::ProtoZero::Message::TransportProtocol::DNSCryptTCP; } + else if (distProto == dnsdist::Protocol::DoQ) { + protocol = pdns::ProtoZero::Message::TransportProtocol::DoQ; + } m.setRequest(d_dq.ids.d_protoBufData && d_dq.ids.d_protoBufData->uniqueId ? *d_dq.ids.d_protoBufData->uniqueId : getUniqueID(), d_requestor ? *d_requestor : d_dq.ids.origRemote, d_responder ? *d_responder : d_dq.ids.origDest, d_question ? d_question->d_name : d_dq.ids.qname, d_question ? d_question->d_type : d_dq.ids.qtype, d_question ? d_question->d_class : d_dq.ids.qclass, d_dq.getHeader()->id, protocol, d_bytes ? *d_bytes : d_dq.getData().size()); diff --git a/pdns/dnsdist-protobuf.hh b/pdns/dnsdist-protobuf.hh index 1e30f26582..6072ccb3d9 100644 --- a/pdns/dnsdist-protobuf.hh +++ b/pdns/dnsdist-protobuf.hh @@ -40,6 +40,7 @@ public: void setResponderPort(uint16_t port); void setResponseCode(uint8_t rcode); void setType(pdns::ProtoZero::Message::MessageType type); + void setHTTPVersion(pdns::ProtoZero::Message::HTTPVersion version); void setBytes(size_t bytes); void setTime(time_t sec, uint32_t usec); void setQueryTime(time_t sec, uint32_t usec); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 871d901596..5fe938ff1b 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -566,6 +566,12 @@ struct ClientState else if (hasTLS()) { return dnsdist::Protocol::DoT; } + else if (doqFrontend != nullptr) { + return dnsdist::Protocol::DoQ; + } + else if (doh3Frontend != nullptr) { + return dnsdist::Protocol::DoH3; + } else if (udpFD != -1) { return dnsdist::Protocol::DoUDP; } diff --git a/pdns/dnsmessage.proto b/pdns/dnsmessage.proto index 99355dfa35..dc819c1b00 100644 --- a/pdns/dnsmessage.proto +++ b/pdns/dnsmessage.proto @@ -43,6 +43,12 @@ message PBDNSMessage { DOH = 4; // DNS over HTTPS (RFC 8484) DNSCryptUDP = 5; // DNSCrypt over UDP (https://dnscrypt.info/protocol) DNSCryptTCP = 6; // DNSCrypt over TCP (https://dnscrypt.info/protocol) + DoQ = 7; // DNS over QUIC (RFC 9250) + } + enum HTTPVersion { + HTTP1 = 1; // HTTP/1.1 + HTTP2 = 2; // HTTP/2 + HTTP3 = 3; // HTTP/3 } enum PolicyType { UNKNOWN = 1; // No RPZ policy applied, or unknown type @@ -177,6 +183,7 @@ message PBDNSMessage { optional string custom = 8; // The name of the event for custom events } repeated Event trace = 23; + optional HTTPVersion httpVersion = 24; // HTTP version used for DNS over HTTP } message PBDNSMessageList { diff --git a/pdns/dnstap.hh b/pdns/dnstap.hh index 8a62b1a769..9c7f55c675 100644 --- a/pdns/dnstap.hh +++ b/pdns/dnstap.hh @@ -36,7 +36,7 @@ class DnstapMessage { public: enum class MessageType : uint32_t { auth_query = 1, auth_response = 2, resolver_query = 3, resolver_response = 4, client_query = 5, client_response = 6, forwarder_query = 7, forwarded_response = 8, stub_query = 9, stub_response = 10, tool_query = 11, tool_response = 12 }; - enum class ProtocolType : uint32_t { DoUDP = 1, DoTCP = 2, DoT = 3, DoH = 4, DNSCryptUDP = 5, DNSCryptTCP = 6 }; + enum class ProtocolType : uint32_t { DoUDP = 1, DoTCP = 2, DoT = 3, DoH = 4, DNSCryptUDP = 5, DNSCryptTCP = 6, DoQ = 7 }; DnstapMessage(std::string& buffer, MessageType type, const std::string& identity, const ComboAddress* requestor, const ComboAddress* responder, ProtocolType protocol, const char* packet, const size_t len, const struct timespec* queryTime, const struct timespec* responseTime, boost::optional auth=boost::none); diff --git a/pdns/protozero.hh b/pdns/protozero.hh index 439d862f4b..8dd49db0df 100644 --- a/pdns/protozero.hh +++ b/pdns/protozero.hh @@ -37,14 +37,15 @@ namespace pdns { public: enum class MetaValueField : protozero::pbf_tag_type { stringVal = 1, intVal = 2 }; + enum class HTTPVersion : protozero::pbf_tag_type { HTTP1 = 1, HTTP2 = 2, HTTP3 = 3 }; enum class MetaField : protozero::pbf_tag_type { key = 1, value = 2 }; enum class Event : protozero::pbf_tag_type { ts = 1, event = 2, start = 3, boolVal = 4, intVal = 5, stringVal = 6, bytesVal = 7, custom = 8 }; enum class MessageType : int32_t { DNSQueryType = 1, DNSResponseType = 2, DNSOutgoingQueryType = 3, DNSIncomingResponseType = 4 }; - enum class Field : protozero::pbf_tag_type { type = 1, messageId = 2, serverIdentity = 3, socketFamily = 4, socketProtocol = 5, from = 6, to = 7, inBytes = 8, timeSec = 9, timeUsec = 10, id = 11, question = 12, response = 13, originalRequestorSubnet = 14, requestorId = 15, initialRequestId = 16, deviceId = 17, newlyObservedDomain = 18, deviceName = 19, fromPort = 20, toPort = 21, meta = 22, trace = 23 }; + enum class Field : protozero::pbf_tag_type { type = 1, messageId = 2, serverIdentity = 3, socketFamily = 4, socketProtocol = 5, from = 6, to = 7, inBytes = 8, timeSec = 9, timeUsec = 10, id = 11, question = 12, response = 13, originalRequestorSubnet = 14, requestorId = 15, initialRequestId = 16, deviceId = 17, newlyObservedDomain = 18, deviceName = 19, fromPort = 20, toPort = 21, meta = 22, trace = 23, httpVersion = 24 }; enum class QuestionField : protozero::pbf_tag_type { qName = 1, qType = 2, qClass = 3 }; enum class ResponseField : protozero::pbf_tag_type { rcode = 1, rrs = 2, appliedPolicy = 3, tags = 4, queryTimeSec = 5, queryTimeUsec = 6, appliedPolicyType = 7, appliedPolicyTrigger = 8, appliedPolicyHit = 9, appliedPolicyKind = 10, validationState = 11 }; enum class RRField : protozero::pbf_tag_type { name = 1, type = 2, class_ = 3, ttl = 4, rdata = 5, udr = 6 }; - enum class TransportProtocol : protozero::pbf_tag_type { UDP = 1, TCP = 2, DoT = 3, DoH = 4, DNSCryptUDP = 5, DNSCryptTCP = 6 }; + enum class TransportProtocol : protozero::pbf_tag_type { UDP = 1, TCP = 2, DoT = 3, DoH = 4, DNSCryptUDP = 5, DNSCryptTCP = 6, DoQ = 7 }; Message(std::string& buffer): d_buffer(buffer), d_message{d_buffer} { @@ -63,6 +64,11 @@ namespace pdns { add_enum(d_message, Field::type, static_cast(mtype)); } + void setHTTPVersion(HTTPVersion version) + { + add_enum(d_message, Field::httpVersion, static_cast(version)); + } + void setMessageIdentity(const boost::uuids::uuid& uniqueId) { add_bytes(d_message, Field::messageId, reinterpret_cast(uniqueId.begin()), uniqueId.size());