From 475fc44ee8d1fc21bb9fe0beffa5fd5b1799277f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 3 Apr 2019 14:10:22 +0200 Subject: [PATCH 1/3] A way to fix https://github.com/PowerDNS/pdns/issues/7646. It might not be the right place, though, but it prevents fatal exception on unparseable A (or AAAA) addresss for nameserver addresses needed to send notifies. --- pdns/communicator.hh | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pdns/communicator.hh b/pdns/communicator.hh index 5413e4dacf23..2cb0f70feb3c 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -259,10 +259,25 @@ public: if(b) { b->lookup(QType(QType::ANY),name); - DNSZoneRecord rr; - while(b->get(rr)) - if(rr.dr.d_type == QType::A || rr.dr.d_type==QType::AAAA) - addresses.push_back(rr.dr.d_content->getZoneRepresentation()); // SOL if you have a CNAME for an NS + bool ok; + do { + DNSZoneRecord rr; + try { + ok = b->get(rr); + } + catch (PDNSException &ae) { + g_log << Logger::Error << "Skipping record: " << ae.reason << endl; + continue; + } + catch (std::exception &e) { + g_log << Logger::Error << "Skipping record: " << e.what() << endl; + continue; + } + if (ok) { + if (rr.dr.d_type == QType::A || rr.dr.d_type == QType::AAAA) + addresses.push_back(rr.dr.d_content->getZoneRepresentation()); // SOL if you have a CNAME for an NS + } + } while (ok); } return addresses; } From cb22b82e6e97374e0eadcc03c56dd8e7f1328bf3 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 3 Apr 2019 16:00:12 +0200 Subject: [PATCH 2/3] Rearrange; to avoid uninitialized var and bail out after exception, b might be inconsistent in that case. --- pdns/communicator.hh | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/pdns/communicator.hh b/pdns/communicator.hh index 2cb0f70feb3c..831b2cecf534 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -258,26 +258,25 @@ public: this->resolve_name(&addresses, name); if(b) { - b->lookup(QType(QType::ANY),name); - bool ok; - do { + b->lookup(QType(QType::ANY),name); + while (true) { + try { DNSZoneRecord rr; - try { - ok = b->get(rr); - } - catch (PDNSException &ae) { - g_log << Logger::Error << "Skipping record: " << ae.reason << endl; - continue; - } - catch (std::exception &e) { - g_log << Logger::Error << "Skipping record: " << e.what() << endl; - continue; - } - if (ok) { - if (rr.dr.d_type == QType::A || rr.dr.d_type == QType::AAAA) - addresses.push_back(rr.dr.d_content->getZoneRepresentation()); // SOL if you have a CNAME for an NS - } - } while (ok); + if (!b->get(rr)) + break; + if (rr.dr.d_type == QType::A || rr.dr.d_type == QType::AAAA) + addresses.push_back(rr.dr.d_content->getZoneRepresentation()); // SOL if you have a CNAME for an NS + } + // After an exception, b can be inconsistent so break + catch (PDNSException &ae) { + g_log << Logger::Error << "Skipping record(s): " << ae.reason << endl; + break; + } + catch (std::exception &e) { + g_log << Logger::Error << "Skipping record(s): " << e.what() << endl; + break; + } + } } return addresses; } From c6e6b0559cfcff8537ee95c4f3d7c02477fd81a3 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 3 Apr 2019 16:24:09 +0200 Subject: [PATCH 3/3] Better logging, so the operator knows where to look. --- pdns/communicator.hh | 6 +++--- pdns/mastercommunicator.cc | 2 +- pdns/tcpreceiver.cc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pdns/communicator.hh b/pdns/communicator.hh index 831b2cecf534..c63534dc232b 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -251,7 +251,7 @@ private: class FindNS { public: - vector lookup(const DNSName &name, UeberBackend *b) + vector lookup(const DNSName &name, UeberBackend *b, const DNSName& zone) { vector addresses; @@ -269,11 +269,11 @@ public: } // After an exception, b can be inconsistent so break catch (PDNSException &ae) { - g_log << Logger::Error << "Skipping record(s): " << ae.reason << endl; + g_log << Logger::Error << "Could not lookup address for nameserver " << name << " in zone " << zone << ", cannot notify: " << ae.reason << endl; break; } catch (std::exception &e) { - g_log << Logger::Error << "Skipping record(s): " << e.what() << endl; + g_log << Logger::Error << "Could not lookup address for nameserver " << name << " in zone " << zone << ", cannot notify: " << e.what() << endl; break; } } diff --git a/pdns/mastercommunicator.cc b/pdns/mastercommunicator.cc index b5841132cfad..04803474994a 100644 --- a/pdns/mastercommunicator.cc +++ b/pdns/mastercommunicator.cc @@ -56,7 +56,7 @@ void CommunicatorClass::queueNotifyDomain(const DomainInfo& di, UeberBackend* B) nsset.insert(getRR(rr.dr)->getNS().toString()); for(set::const_iterator j=nsset.begin();j!=nsset.end();++j) { - vector nsips=fns.lookup(DNSName(*j), B); + vector nsips=fns.lookup(DNSName(*j), B, di.zone); if(nsips.empty()) g_log< q) while(B->get(rr)) nsset.insert(DNSName(rr.content)); for(const auto & j: nsset) { - vector nsips=fns.lookup(j, s_P->getBackend()); + vector nsips=fns.lookup(j, s_P->getBackend(),q->qdomain); for(vector::const_iterator k=nsips.begin();k!=nsips.end();++k) { // cerr<<"got "<<*k<<" from AUTO-NS"<getRemote().toString())