From 48afcf832ca7db6fadbb0041ba28af8304d9024c Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Thu, 10 Feb 2011 19:52:46 +0000 Subject: [PATCH] teach SOA freshness retriever about DNSSEC & do=1, and have it examine returned RRSIGs git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2006 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/resolver.cc | 33 +++++++++++++++++++++++++-------- pdns/resolver.hh | 4 ++-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/pdns/resolver.cc b/pdns/resolver.cc index 58d0583c3a..5a81e7261c 100644 --- a/pdns/resolver.cc +++ b/pdns/resolver.cc @@ -39,6 +39,7 @@ #include "dnswriter.hh" #include "dnsparser.hh" #include +#include #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 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 rrc=boost::dynamic_pointer_cast(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 src=boost::dynamic_pointer_cast(drc.first.d_content); + *theirSerial=src->d_st.serial; + gotSOA = true; + } + if(drc.first.d_type == QType::RRSIG) { + shared_ptr rrc=boost::dynamic_pointer_cast(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; } diff --git a/pdns/resolver.hh b/pdns/resolver.hh index 63893d7df8..d828bc71cb 100644 --- a/pdns/resolver.hh +++ b/pdns/resolver.hh @@ -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); -- 2.47.3