]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
teach SOA freshness retriever about DNSSEC & do=1, and have it examine returned RRSIGs
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 10 Feb 2011 19:52:46 +0000 (19:52 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 10 Feb 2011 19:52:46 +0000 (19:52 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2006 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/resolver.cc
pdns/resolver.hh

index 58d0583c3a09f329309037afdf6863850589eb21..5a81e7261c3b2b39645a3242b9316f4a332eb8be 100644 (file)
@@ -39,6 +39,7 @@
 #include "dnswriter.hh"
 #include "dnsparser.hh"
 #include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
 #include "dns_random.hh"
 
 #include "namespaces.hh"
@@ -129,12 +130,17 @@ int Resolver::notify(int sock, const string &domain, const string &ip, uint16_t
   return true;
 }
 
-uint16_t Resolver::sendResolve(const string &ip, const char *domain, int type)
+uint16_t Resolver::sendResolve(const string &ip, const char *domain, int type, bool dnssecOK)
 {
   vector<uint8_t> packet;
   DNSPacketWriter pw(packet, domain, type);
   pw.getHeader()->id = d_randomid = dns_random(0xffff);
 
+  if(dnssecOK) {
+    pw.addOpt(2800, 0, EDNSOpts::DNSSECOK);
+    pw.commit();
+  }
+
   d_domain=domain;
   d_type=type;
   d_inaxfr=false;
@@ -156,7 +162,7 @@ uint16_t Resolver::sendResolve(const string &ip, const char *domain, int type)
   return d_randomid;
 }
 
-bool Resolver::tryGetSOASerial(string* domain, uint32_t *theirSerial, uint16_t* id)
+bool Resolver::tryGetSOASerial(string* domain, uint32_t *theirSerial, uint32_t *theirInception, uint32_t *theirExpire, uint16_t* id)
 {
   Utility::setNonBlocking( d_sock );
   
@@ -181,14 +187,25 @@ bool Resolver::tryGetSOASerial(string* domain, uint32_t *theirSerial, uint16_t*
   if(mdp.d_answers.empty())
     throw ResolverException("Query to '" + fromaddr.toString() + "' for SOA of '" + *domain + "' produced no results");
   
-  if(mdp.d_qtype != QType::SOA || mdp.d_answers.begin()->first.d_type != QType::SOA) 
+  if(mdp.d_qtype != QType::SOA)
     throw ResolverException("Query to '" + fromaddr.toString() + "' for SOA of '" + *domain + "' returned wrong record type");
 
-  shared_ptr<SOARecordContent> rrc=boost::dynamic_pointer_cast<SOARecordContent>(mdp.d_answers.begin()->first.d_content);
-
-  *theirSerial=rrc->d_st.serial;
-  
-  
+  *theirInception = *theirExpire = 0;
+  bool gotSOA=false;
+  BOOST_FOREACH(const MOADNSParser::answers_t::value_type& drc, mdp.d_answers) {
+    if(drc.first.d_type == QType::SOA) {
+      shared_ptr<SOARecordContent> src=boost::dynamic_pointer_cast<SOARecordContent>(drc.first.d_content);
+      *theirSerial=src->d_st.serial;
+      gotSOA = true;
+    }
+    if(drc.first.d_type == QType::RRSIG) {
+      shared_ptr<RRSIGRecordContent> rrc=boost::dynamic_pointer_cast<RRSIGRecordContent>(drc.first.d_content);
+      *theirInception= std::max(*theirInception, rrc->d_siginception);
+      *theirExpire = std::max(*theirExpire, rrc->d_sigexpire);
+    }
+  }
+  if(!gotSOA)
+    throw ResolverException("Query to '" + fromaddr.toString() + "' for SOA of '" + *domain + "' did not return a SOA");
   return true;
 }
 
index 63893d7df81a0f2eeb744774770d7b76db6cbeb1..d828bc71cb3b43f9ae0ba02e6319e98511858892 100644 (file)
@@ -57,8 +57,8 @@ public:
   void makeTCPSocket(const string &ip, uint16_t port=53);
   int notify(int sock, const string &domain, const string &ip, uint16_t id);
   int resolve(const string &ip, const char *domain, int type);
-  uint16_t sendResolve(const string &ip, const char *domain, int type);
-  bool tryGetSOASerial(string* theirDomain, uint32_t* theirSerial, uint16_t* id);
+  uint16_t sendResolve(const string &ip, const char *domain, int type, bool dnssecOk=false);
+  bool tryGetSOASerial(string* theirDomain, uint32_t* theirSerial, uint32_t* theirInception, uint32_t* theirExpire, uint16_t* id);
 
   int receiveResolve(struct sockaddr* fromaddr, Utility::socklen_t addrlen);