From: Neil Cook Date: Fri, 19 Oct 2018 11:23:02 +0000 (+0000) Subject: Add UDR Tracking and refactor NOD support X-Git-Tag: dnsdist-1.3.3~16^2~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=41c542ec6a2fc57b14ccce4b6faa895fb2159fc0;p=pdns Add UDR Tracking and refactor NOD support - New Unique DNS Response tracking (tracks triplet of (qname, qtype, RR)) - Move NOD checks so that the results appear in protobuf - Add NOD and UDR to protobuf messages - Clear NOD and UDR flags for protobuf messsages from packet cache --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index f537f62d2..f5f7b71ea 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -125,6 +125,7 @@ thread_local std::unique_ptr t_uuidGenerator; #endif #ifdef NOD_ENABLED thread_local std::shared_ptr t_nodDBp; +thread_local std::shared_ptr t_udrDBp; #endif /* NOD_ENABLED */ __thread struct timeval g_now; // timestamp, updated (too) frequently @@ -208,6 +209,8 @@ static bool g_nodEnabled; static DNSName g_nodLookupDomain; static bool g_nodLog; static SuffixMatchNode g_nodDomainWL; +static bool g_udrEnabled; +static bool g_udrLog; #endif /* NOD_ENABLED */ #ifdef HAVE_BOOST_CONTAINER_FLAT_SET_HPP static boost::container::flat_set s_avoidUdpSourcePorts; @@ -916,10 +919,11 @@ static bool checkOutgoingProtobufExport(LocalStateHolder& luacon #endif /* HAVE_PROTOBUF */ #ifdef NOD_ENABLED -static void nodCheckNewDomain(const DNSName& dname) +static bool nodCheckNewDomain(const DNSName& dname) { static const QType qt(QType::A); static const uint16_t qc(QClass::IN); + bool ret = false; // First check the (sub)domain isn't whitelisted for NOD purposes if (!g_nodDomainWL.check(dname)) { // Now check the NODDB (note this is probablistic so can have FNs/FPs) @@ -935,8 +939,10 @@ static void nodCheckNewDomain(const DNSName& dname) qname += g_nodLookupDomain; directResolve(qname, qt, qc, dummy); } + ret = true; } } + return ret; } static void nodAddDomain(const DNSName& dname) @@ -949,6 +955,25 @@ static void nodAddDomain(const DNSName& dname) } } } + +static bool udrCheckUniqueDNSRecord(const DNSName& dname, uint16_t qtype, const DNSRecord& record) +{ + bool ret = false; + if (record.d_place == DNSResourceRecord::ANSWER || + record.d_place == DNSResourceRecord::ADDITIONAL) { + // Create a string that represent a triplet of (qname, qtype and RR[type, name, content]) + std::stringstream ss; + ss << dname.toDNSStringLC() << ":" << qtype << ":" << qtype << ":" << record.d_type << ":" << record.d_name.toDNSStringLC() << ":" << record.d_content->getZoneRepresentation(); + if (t_udrDBp && t_udrDBp->isUniqueResponse(ss.str())) { + if (g_udrLog) { + // This should also probably log to a dedicated file. + g_log<(); + try { + t_udrDBp->setCacheDir(::arg()["unique-response-history-dir"]); + } + catch (const PDNSException& e) { + g_log<init()) { + g_log<