]> granicus.if.org Git - pdns/commitdiff
rec: Use the incoming ECS for cache lookup if `use-incoming-edns-subnet` is set
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 14 Jun 2017 11:31:18 +0000 (13:31 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 3 Jul 2017 10:07:40 +0000 (12:07 +0200)
Otherwise we insert into the cache based on the incoming ECS but
later do the lookup based on the query's source IP.

(cherry picked from commit 5736e55e0d2d8cd9a064b8377e87d08a540cb1b1)

pdns/pdns_recursor.cc
pdns/syncres.cc
pdns/syncres.hh

index 4890056eac621146d1c16bce011d23d555d6ab62..ef523a010ab191bc42165892e76392a41376ebe4 100644 (file)
@@ -776,6 +776,7 @@ void startDoResolve(void *p)
       sr.d_incomingECSFound = dc->d_ecsFound;
       if (dc->d_ecsFound) {
         sr.d_incomingECS = dc->d_ednssubnet;
+        sr.d_incomingECSNetwork = sr.d_incomingECS ? sr.d_incomingECS->source.getMaskedNetwork() : ComboAddress();
       }
     }
 
index 63c4732164f13caaacc80c6db5091820c1a32977..653c17682ba2282c11fd38b68bd581447910a4e9 100644 (file)
@@ -541,7 +541,7 @@ vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth,
     if(done) {
       if(j==1 && s_doIPv6) { // we got an A record, see if we have some AAAA lying around
        vector<DNSRecord> cset;
-       if(t_RC->get(d_now.tv_sec, qname, QType(QType::AAAA), &cset, d_requestor) > 0) {
+       if(t_RC->get(d_now.tv_sec, qname, QType(QType::AAAA), &cset, d_incomingECSFound ? d_incomingECSNetwork : d_requestor) > 0) {
          for(auto k=cset.cbegin();k!=cset.cend();++k) {
            if(k->d_ttl > (unsigned int)d_now.tv_sec ) {
              if (auto drc = std::dynamic_pointer_cast<AAAARecordContent>(k->d_content)) {
@@ -592,7 +592,7 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType& qtype, vecto
     LOG(prefix<<qname<<": Checking if we have NS in cache for '"<<subdomain<<"'"<<endl);
     vector<DNSRecord> ns;
     *flawedNSSet = false;
-    if(t_RC->get(d_now.tv_sec, subdomain, QType(QType::NS), &ns, d_requestor) > 0) {
+    if(t_RC->get(d_now.tv_sec, subdomain, QType(QType::NS), &ns, d_incomingECSFound ? d_incomingECSNetwork : d_requestor) > 0) {
       for(auto k=ns.cbegin();k!=ns.cend(); ++k) {
         if(k->d_ttl > (unsigned int)d_now.tv_sec ) {
           vector<DNSRecord> aset;
@@ -600,7 +600,7 @@ void SyncRes::getBestNSFromCache(const DNSName &qname, const QType& qtype, vecto
           const DNSRecord& dr=*k;
          auto nrr = getRR<NSRecordContent>(dr);
           if(nrr && (!nrr->getNS().isPartOf(subdomain) || t_RC->get(d_now.tv_sec, nrr->getNS(), s_doIPv6 ? QType(QType::ADDR) : QType(QType::A),
-                                                                    doLog() ? &aset : 0, d_requestor) > 5)) {
+                                                                    doLog() ? &aset : 0, d_incomingECSFound ? d_incomingECSNetwork : d_requestor) > 5)) {
             bestns.push_back(dr);
             LOG(prefix<<qname<<": NS (with ip, or non-glue) in cache for '"<<subdomain<<"' -> '"<<nrr->getNS()<<"'"<<endl);
             LOG(prefix<<qname<<": within bailiwick: "<< nrr->getNS().isPartOf(subdomain));
@@ -713,7 +713,7 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector
   LOG(prefix<<qname<<": Looking for CNAME cache hit of '"<<qname<<"|CNAME"<<"'"<<endl);
   vector<DNSRecord> cset;
   vector<std::shared_ptr<RRSIGRecordContent>> signatures;
-  if(t_RC->get(d_now.tv_sec, qname,QType(QType::CNAME), &cset, d_requestor, &signatures, &d_wasVariable) > 0) {
+  if(t_RC->get(d_now.tv_sec, qname,QType(QType::CNAME), &cset, d_incomingECSFound ? d_incomingECSNetwork : d_requestor, &signatures, &d_wasVariable) > 0) {
 
     for(auto j=cset.cbegin() ; j != cset.cend() ; ++j) {
       if(j->d_ttl>(unsigned int) d_now.tv_sec) {
@@ -842,7 +842,7 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSR
   bool found=false, expired=false;
   vector<std::shared_ptr<RRSIGRecordContent>> signatures;
   uint32_t ttl=0;
-  if(t_RC->get(d_now.tv_sec, sqname, sqt, &cset, d_requestor, d_doDNSSEC ? &signatures : 0, &d_wasVariable) > 0) {
+  if(t_RC->get(d_now.tv_sec, sqname, sqt, &cset, d_incomingECSFound ? d_incomingECSNetwork : d_requestor, d_doDNSSEC ? &signatures : 0, &d_wasVariable) > 0) {
     LOG(prefix<<sqname<<": Found cache hit for "<<sqt.getName()<<": ");
     for(auto j=cset.cbegin() ; j != cset.cend() ; ++j) {
       LOG(j->d_content->getZoneRepresentation());
index fdb0867f1ca6edfca86abe07c6c2370aa8cfa250..26b2a9cccd2dcaa446205e119b4989b28f92961a 100644 (file)
@@ -353,7 +353,6 @@ public:
   }
 
   int asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional<Netmask>& srcmask, LWResult* res);
-
   static void doEDNSDumpAndClose(int fd);
 
   static std::atomic<uint64_t> s_queries;
@@ -374,6 +373,7 @@ public:
   std::unordered_map<std::string,bool> d_discardedPolicies;
   DNSFilterEngine::Policy d_appliedPolicy;
   boost::optional<const EDNSSubnetOpts&> d_incomingECS;
+  ComboAddress d_incomingECSNetwork;
 #ifdef HAVE_PROTOBUF
   boost::optional<const boost::uuids::uuid&> d_initialRequestId;
 #endif