if msg.socketProtocol == dnsmessage_pb2.PBDNSMessage.UDP:
protostr = 'UDP'
- else:
+ elif msg.socketProtocol == dnsmessage_pb2.PBDNSMessage.TCP:
protostr = 'TCP'
+ elif msg.socketProtocol == dnsmessage_pb2.PBDNSMessage.DOT:
+ protostr = 'DoT'
+ elif msg.socketProtocol == dnsmessage_pb2.PBDNSMessage.DOH:
+ protostr = 'DoH'
+ elif msg.socketProtocol == dnsmessage_pb2.PBDNSMessage.DNSCryptUDP:
+ protostr = 'DNSCrypt UDP'
+ elif msg.socketProtocol == dnsmessage_pb2.PBDNSMessage.DNSCryptTCP:
+ protostr = 'DNSCrypt TCP'
if msg.HasField('fromPort'):
fromportstr = ':' + str(msg.fromPort) + ' '
static DnstapMessage::ProtocolType ProtocolToDNSTap(dnsdist::Protocol protocol)
{
- if (protocol == dnsdist::Protocol::DoUDP || protocol == dnsdist::Protocol::DNSCryptUDP) {
+ if (protocol == dnsdist::Protocol::DoUDP) {
return DnstapMessage::ProtocolType::DoUDP;
}
- else if (protocol == dnsdist::Protocol::DoTCP || protocol == dnsdist::Protocol::DNSCryptTCP) {
+ else if (protocol == dnsdist::Protocol::DoTCP) {
return DnstapMessage::ProtocolType::DoTCP;
}
else if (protocol == dnsdist::Protocol::DoT) {
else if (protocol == dnsdist::Protocol::DoH) {
return DnstapMessage::ProtocolType::DoH;
}
+ else if (protocol == dnsdist::Protocol::DNSCryptUDP) {
+ return DnstapMessage::ProtocolType::DNSCryptUDP;
+ }
+ else if (protocol == dnsdist::Protocol::DNSCryptTCP) {
+ return DnstapMessage::ProtocolType::DNSCryptTCP;
+ }
throw std::runtime_error("Unhandled protocol for dnstap: " + protocol.toPrettyString());
}
m.setTime(ts.tv_sec, ts.tv_nsec / 1000);
}
- m.setRequest(d_dq.uniqueId ? *d_dq.uniqueId : getUniqueID(), d_requestor ? *d_requestor : *d_dq.remote, d_responder ? *d_responder : *d_dq.local, d_question ? d_question->d_name : *d_dq.qname, d_question ? d_question->d_type : d_dq.qtype, d_question ? d_question->d_class : d_dq.qclass, d_dq.getHeader()->id, (d_dq.getProtocol() == dnsdist::Protocol::DoH) ? true : d_dq.overTCP(), d_bytes ? *d_bytes : d_dq.getData().size());
+ const auto distProto = d_dq.getProtocol();
+ pdns::ProtoZero::Message::TransportProtocol protocol = pdns::ProtoZero::Message::TransportProtocol::UDP;
+
+ if (distProto == dnsdist::Protocol::DoTCP) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::TCP;
+ }
+ else if (distProto == dnsdist::Protocol::DoT) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::DoT;
+ }
+ else if (distProto == dnsdist::Protocol::DoH) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::DoH;
+ }
+ else if (distProto == dnsdist::Protocol::DNSCryptUDP) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::DNSCryptUDP;
+ }
+ else if (distProto == dnsdist::Protocol::DNSCryptTCP) {
+ protocol = pdns::ProtoZero::Message::TransportProtocol::DNSCryptTCP;
+ }
+
+ m.setRequest(d_dq.uniqueId ? *d_dq.uniqueId : getUniqueID(), d_requestor ? *d_requestor : *d_dq.remote, d_responder ? *d_responder : *d_dq.local, d_question ? d_question->d_name : *d_dq.qname, d_question ? d_question->d_type : d_dq.qtype, d_question ? d_question->d_class : d_dq.qclass, d_dq.getHeader()->id, protocol, d_bytes ? *d_bytes : d_dq.getData().size());
if (d_serverIdentity) {
m.setServerIdentity(*d_serverIdentity);
pbBuffer.clear();
pdns::ProtoZero::Message pbMessage(pbBuffer);
pbMessage.setType(dh->qr ? pdns::ProtoZero::Message::MessageType::DNSResponseType : pdns::ProtoZero::Message::MessageType::DNSQueryType);
- pbMessage.setRequest(uniqueId, requestor, responder, qname, qtype, qclass, dh->id, false, pr.d_len);
+ pbMessage.setRequest(uniqueId, requestor, responder, qname, qtype, qclass, dh->id, pdns::ProtoZero::Message::TransportProtocol::UDP, pr.d_len);
pbMessage.setTime(pr.d_pheader.ts.tv_sec, pr.d_pheader.ts.tv_usec);
if (dh->qr) {
{
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 };
+ enum class ProtocolType : uint32_t { DoUDP = 1, DoTCP = 2, DoT = 3, DoH = 4, DNSCryptUDP = 5, DNSCryptTCP = 6 };
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<const DNSName&> auth=boost::none);
#endif // HAVE_FSTRM
-static void logOutgoingQuery(const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& outgoingLoggers, boost::optional<const boost::uuids::uuid&> initialRequestId, const boost::uuids::uuid& uuid, const ComboAddress& ip, const DNSName& domain, int type, uint16_t qid, bool doTCP, size_t bytes, boost::optional<Netmask>& srcmask)
+static void logOutgoingQuery(const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& outgoingLoggers, boost::optional<const boost::uuids::uuid&> initialRequestId, const boost::uuids::uuid& uuid, const ComboAddress& ip, const DNSName& domain, int type, uint16_t qid, bool doTCP, bool tls, size_t bytes, boost::optional<Netmask>& srcmask)
{
if (!outgoingLoggers) {
return;
m.setType(pdns::ProtoZero::Message::MessageType::DNSOutgoingQueryType);
m.setMessageIdentity(uuid);
m.setSocketFamily(ip.sin4.sin_family);
- m.setSocketProtocol(doTCP);
+ if (!doTCP) {
+ m.setSocketProtocol(pdns::ProtoZero::Message::TransportProtocol::UDP);
+ }
+ else if (!tls) {
+ m.setSocketProtocol(pdns::ProtoZero::Message::TransportProtocol::TCP);
+ }
+ else {
+ m.setSocketProtocol(pdns::ProtoZero::Message::TransportProtocol::DoT);
+ }
+
m.setTo(ip);
m.setInBytes(bytes);
m.setTime();
}
}
-static void logIncomingResponse(const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& outgoingLoggers, boost::optional<const boost::uuids::uuid&> initialRequestId, const boost::uuids::uuid& uuid, const ComboAddress& ip, const DNSName& domain, int type, uint16_t qid, bool doTCP, boost::optional<Netmask>& srcmask, size_t bytes, int rcode, const std::vector<DNSRecord>& records, const struct timeval& queryTime, const std::set<uint16_t>& exportTypes)
+static void logIncomingResponse(const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& outgoingLoggers, boost::optional<const boost::uuids::uuid&> initialRequestId, const boost::uuids::uuid& uuid, const ComboAddress& ip, const DNSName& domain, int type, uint16_t qid, bool doTCP, bool tls, boost::optional<Netmask>& srcmask, size_t bytes, int rcode, const std::vector<DNSRecord>& records, const struct timeval& queryTime, const std::set<uint16_t>& exportTypes)
{
if (!outgoingLoggers) {
return;
m.setType(pdns::ProtoZero::Message::MessageType::DNSIncomingResponseType);
m.setMessageIdentity(uuid);
m.setSocketFamily(ip.sin4.sin_family);
- m.setSocketProtocol(doTCP);
+ if (!doTCP) {
+ m.setSocketProtocol(pdns::ProtoZero::Message::TransportProtocol::UDP);
+ }
+ else if (!tls) {
+ m.setSocketProtocol(pdns::ProtoZero::Message::TransportProtocol::TCP);
+ }
+ else {
+ m.setSocketProtocol(pdns::ProtoZero::Message::TransportProtocol::DoT);
+ }
m.setTo(ip);
m.setInBytes(bytes);
m.setTime();
boost::uuids::uuid uuid;
const struct timeval queryTime = *now;
+ bool dnsOverTLS = SyncRes::s_dot_to_port_853 && ip.getPort() == 853;
if (outgoingLoggers) {
uuid = getUniqueID();
- logOutgoingQuery(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, vpacket.size(), srcmask);
+ logOutgoingQuery(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, vpacket.size(), srcmask);
}
srcmask = boost::none; // this is also our return value, even if EDNS0Level == 0
// We only store the localip if needed for fstrm logging
ComboAddress localip;
- bool dnsOverTLS = false;
#ifdef HAVE_FSTRM
bool fstrmQEnabled = false;
bool fstrmREnabled = false;
if (ret != LWResult::Result::Success) { // includes 'timeout'
if (outgoingLoggers) {
- logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, srcmask, 0, -1, {}, queryTime, exportTypes);
+ logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, 0, -1, {}, queryTime, exportTypes);
}
return ret;
}
if(mdp.d_header.rcode == RCode::FormErr && mdp.d_qname.empty() && mdp.d_qtype == 0 && mdp.d_qclass == 0) {
if(outgoingLoggers) {
- logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes);
+ logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes);
}
lwr->d_validpacket = true;
return LWResult::Result::Success; // this is "success", the error is set in lwr->d_rcode
}
if(outgoingLoggers) {
- logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes);
+ logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes);
}
lwr->d_validpacket = true;
g_stats.serverParseError++;
if(outgoingLoggers) {
- logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes);
+ logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes);
}
return LWResult::Result::Success; // success - oddly enough
pdns::ProtoZero::RecMessage m{128, std::string::size_type(policyTags.empty() ? 0 : 64)}; // It's a guess
m.setType(pdns::ProtoZero::Message::MessageType::DNSQueryType);
- m.setRequest(uniqueId, requestor, local, qname, qtype, qclass, id, tcp, len);
+ m.setRequest(uniqueId, requestor, local, qname, qtype, qclass, id, tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP, len);
m.setServerIdentity(SyncRes::s_serverID);
m.setEDNSSubnet(ednssubnet, ednssubnet.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
m.setRequestorId(requestorId);
pbMessage.setMessageIdentity(uniqueId);
pbMessage.setFrom(requestor);
pbMessage.setTo(destination);
- pbMessage.setSocketProtocol(tcp);
+ pbMessage.setSocketProtocol(tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP);
pbMessage.setId(dh->id);
pbMessage.setTime();
}
pbMessage.setMessageIdentity(dc->d_uuid);
pbMessage.setSocketFamily(dc->d_source.sin4.sin_family);
- pbMessage.setSocketProtocol(dc->d_tcp);
+ pbMessage.setSocketProtocol(dc->d_tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP);
Netmask requestorNM(dc->d_source, dc->d_source.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
ComboAddress requestor = requestorNM.getMaskedNetwork();
pbMessage.setFrom(requestor);
// leaving the block will cause the sub writer to compute how much was written based on the new size and update the size accordingly
}
-void pdns::ProtoZero::Message::setRequest(const boost::uuids::uuid& uniqueId, const ComboAddress& requestor, const ComboAddress& local, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t id, bool tcp, size_t len)
+void pdns::ProtoZero::Message::setRequest(const boost::uuids::uuid& uniqueId, const ComboAddress& requestor, const ComboAddress& local, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t id, pdns::ProtoZero::Message::TransportProtocol proto, size_t len)
{
setMessageIdentity(uniqueId);
setSocketFamily(requestor.sin4.sin_family);
- setSocketProtocol(tcp);
+ setSocketProtocol(proto);
setFrom(requestor);
setTo(local);
setInBytes(len);
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 };
Message(std::string& buffer): d_buffer(buffer), d_message{d_buffer}
{
Message& operator=(const Message&) = delete;
Message& operator=(Message&&) = delete;
- void setRequest(const boost::uuids::uuid& uniqueId, const ComboAddress& requestor, const ComboAddress& local, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t id, bool tcp, size_t len);
+ void setRequest(const boost::uuids::uuid& uniqueId, const ComboAddress& requestor, const ComboAddress& local, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t id, TransportProtocol proto, size_t len);
void setResponse(const DNSName& qname, uint16_t qtype, uint16_t qclass);
void setType(MessageType mtype)
add_enum(d_message, Field::socketFamily, family == AF_INET ? 1 : 2);
}
- void setSocketProtocol(bool tcp)
+ void setSocketProtocol(TransportProtocol proto)
{
- add_enum(d_message, Field::socketProtocol, tcp ? 2 : 1);
+ add_enum(d_message, Field::socketProtocol, static_cast<int32_t>(proto));
}
void setFrom(const ComboAddress& ca)