From 2e921ec6961500a5b59b4eb8d3d408e7825cd174 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Mon, 21 Mar 2016 17:40:56 +0100 Subject: [PATCH] this fixes #3261 and likely #3532 and #3446. In the new model, SyncRes has one flag: do DNSSEC or not. If the user did not want DNSSEC, pdns_recursor.cc will strip it out for you. But the processing is mostly done anyhow (except for optimization). This also fixes everyone's favorite warning about State being unset, and it restores 'dnssec=process' as default --- pdns/pdns_recursor.cc | 43 +++++++++++++++++++++++++++++++-------- pdns/syncres.cc | 21 ++++++++++--------- pdns/validate-recursor.cc | 41 +++++++++++++++++++++++++++---------- 3 files changed, 76 insertions(+), 29 deletions(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index e92cd6dccf..5b61e3161c 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -630,14 +630,18 @@ void startDoResolve(void *p) uint32_t minTTL=std::numeric_limits::max(); SyncRes sr(dc->d_now); + bool DNSSECOK=false; if(t_pdl) { sr.setLuaEngine(*t_pdl); sr.d_requestor=dc->d_remote; } + + if(g_dnssecmode != DNSSECMode::Off) + sr.d_doDNSSEC=true; - if(pw.getHeader()->cd || edo.d_Z & EDNSOpts::DNSSECOK) { + if(pw.getHeader()->cd || (edo.d_Z & EDNSOpts::DNSSECOK)) { + DNSSECOK=true; g_stats.dnssecQueries++; - sr.d_doDNSSEC=true; } bool tracedQuery=false; // we could consider letting Lua know about this too @@ -808,20 +812,41 @@ void startDoResolve(void *p) if(haveEDNS) { if(g_dnssecmode != DNSSECMode::Off && ((edo.d_Z & EDNSOpts::DNSSECOK) || g_dnssecmode == DNSSECMode::ValidateAll || g_dnssecmode==DNSSECMode::ValidateForLog)) { + if(sr.doLog()) { + L<d_mdp.d_qname<<" for "<d_remote.toStringWithPort()<d_mdp.d_qname<<" for "<d_remote.toStringWithPort()<<" validates correctly"<ad=1; } else if(state == Insecure) { + if(sr.doLog()) { + L<d_mdp.d_qname<<" for "<d_remote.toStringWithPort()<<" validates as Insecure"<ad=0; } - else if(state == Bogus && !pw.getHeader()->cd) { - if(g_dnssecmode == DNSSECMode::ValidateAll || (edo.d_Z & EDNSOpts::DNSSECOK)) { + else if(state == Bogus ) { + if(sr.doLog()) { + L<d_mdp.d_qname<<" for "<d_remote.toStringWithPort()<<" validates as Bogus"<cd && (g_dnssecmode == DNSSECMode::ValidateAll || (edo.d_Z & EDNSOpts::DNSSECOK))) { + if(sr.doLog()) { + L<d_mdp.d_qname<<" because recursor or query demands it for Bogus results"<rcode=RCode::ServFail; goto sendit; - } - else { - L<d_mdp.d_qname<<" for "<d_remote.toStringWithPort()<d_mdp.d_qname<<" Bogus validation since neither config nor query demands this"<d_type == QType::RRSIG || i->d_type==QType::NSEC || i->d_type==QType::NSEC3)) + continue; pw.startRecord(i->d_name, i->d_type, i->d_ttl, i->d_class, i->d_place); if(i->d_type != QType::OPT) // their TTL ain't real minTTL = min(minTTL, i->d_ttl); @@ -2633,7 +2660,7 @@ int main(int argc, char **argv) ::arg().set("local-address","IP addresses to listen on, separated by spaces or commas. Also accepts ports.")="127.0.0.1"; ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options")="no"; ::arg().set("trace","if we should output heaps of logging. set to 'fail' to only log failing domains")="off"; - ::arg().set("dnssec", "DNSSEC mode: off (default)/process/log-fail/validate")="off"; + ::arg().set("dnssec", "DNSSEC mode: off (default)/process/log-fail/validate")="process"; ::arg().set("daemon","Operate as a daemon")="no"; ::arg().setSwitch("write-pid","Write a PID file")="yes"; ::arg().set("loglevel","Amount of logging. Higher is more. Do not set below 3")="4"; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 11f3b1fff5..6d947b7185 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -387,7 +387,7 @@ int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vectord_qname; sqt=QType::SOA; - if(d_doDNSSEC) { - for(const auto& p : ni->d_dnssecProof) { - for(const auto& rec: p.second.records) - ret.push_back(rec); - for(const auto& rec: p.second.signatures) - ret.push_back(rec); - } - } + if(d_doDNSSEC) { + for(const auto& p : ni->d_dnssecProof) { + for(const auto& rec: p.second.records) + ret.push_back(rec); + for(const auto& rec: p.second.signatures) + ret.push_back(rec); + } + } moveCacheItemToBack(t_sstorage->negcache, ni); break; } @@ -1257,7 +1257,7 @@ int SyncRes::doResolveAt(map > &nameservers, D ret.push_back(rec); newtarget=std::dynamic_pointer_cast(rec.d_content)->getTarget(); } - else if(d_doDNSSEC && (rec.d_type==QType::RRSIG || rec.d_type==QType::NSEC || rec.d_type==QType::NSEC3) && rec.d_place==DNSResourceRecord::ANSWER){ + else if((rec.d_type==QType::RRSIG || rec.d_type==QType::NSEC || rec.d_type==QType::NSEC3) && rec.d_place==DNSResourceRecord::ANSWER){ if(rec.d_type != QType::RRSIG || rec.d_name == qname) ret.push_back(rec); // enjoy your DNSSEC } @@ -1343,6 +1343,7 @@ int SyncRes::doResolveAt(map > &nameservers, D } if(nsset.empty() && !lwr.d_rcode && (negindic || lwr.d_aabit || sendRDQuery)) { LOG(prefix<& recs) SRRecordOracle sro; - vState state; + vState state=Insecure; if(numsigs) { for(const auto& csp : cspmap) { for(const auto& sig : csp.second.signatures) { state = getKeysFor(sro, sig->d_signer, keys); // XXX check validity here // cerr<<"! state = "<d_name, keys); // um WHAT DOES THIS MEAN - try first qname?? + // cerr<<"! state = "<first.first<<"/"<first.second)<first.first<<"/"<first.second)<second.records.begin(); j!=i->second.records.end(); j++) { - // cerr<<"\t% > "<<(*j)->getZoneRepresentation()< "<<(*j)->getZoneRepresentation()<