]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/mastercommunicator.cc
rec: ensure correct service user on debian
[thirdparty/pdns.git] / pdns / mastercommunicator.cc
index d50928000a89e8b8891c32971146ccd11fe7f455..04803474994a64e63d7294265b30260d6ed0a768 100644 (file)
@@ -22,7 +22,7 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
-#include "packetcache.hh"
+#include "auth-caches.hh"
 #include "utility.hh"
 #include <errno.h>
 #include "communicator.hh"
@@ -46,25 +46,25 @@ void CommunicatorClass::queueNotifyDomain(const DomainInfo& di, UeberBackend* B)
 {
   bool hasQueuedItem=false;
   set<string> nsset, ips;
-  DNSResourceRecord rr;
+  DNSZoneRecord rr;
   FindNS fns;
 
 
   if (d_onlyNotify.size()) {
-    B->lookup(QType(QType::NS),domain);
+    B->lookup(QType(QType::NS), di.zone);
     while(B->get(rr))
-      nsset.insert(rr.content);
+      nsset.insert(getRR<NSRecordContent>(rr.dr)->getNS().toString());
 
     for(set<string>::const_iterator j=nsset.begin();j!=nsset.end();++j) {
-      vector<string> nsips=fns.lookup(DNSName(*j), B);
+      vector<string> nsips=fns.lookup(DNSName(*j), B, di.zone);
       if(nsips.empty())
-        L<<Logger::Warning<<"Unable to queue notification of domain '"<<domain<<"': nameservers do not resolve!"<<endl;
+        g_log<<Logger::Warning<<"Unable to queue notification of domain '"<<di.zone<<"': nameservers do not resolve!"<<endl;
       else
         for(vector<string>::const_iterator k=nsips.begin();k!=nsips.end();++k) {
           const ComboAddress caIp(*k, 53);
           if(!d_preventSelfNotification || !AddressIsUs(caIp)) {
             if(!d_onlyNotify.match(&caIp))
-              L<<Logger::Info<<"Skipped notification of domain '"<<domain<<"' to "<<*j<<" because it does not match only-notify."<<endl;
+              g_log<<Logger::Info<<"Skipped notification of domain '"<<di.zone<<"' to "<<*j<<" because it does not match only-notify."<<endl;
             else
               ips.insert(caIp.toStringWithPort());
           }
@@ -72,8 +72,8 @@ void CommunicatorClass::queueNotifyDomain(const DomainInfo& di, UeberBackend* B)
     }
 
     for(set<string>::const_iterator j=ips.begin();j!=ips.end();++j) {
-      L<<Logger::Warning<<"Queued notification of domain '"<<domain<<"' to "<<*j<<endl;
-      d_nq.add(domain,*j);
+      g_log<<Logger::Warning<<"Queued notification of domain '"<<di.zone<<"' to "<<*j<<endl;
+      d_nq.add(di.zone,*j);
       hasQueuedItem=true;
     }
   }
@@ -84,7 +84,7 @@ void CommunicatorClass::queueNotifyDomain(const DomainInfo& di, UeberBackend* B)
   for(set<string>::const_iterator j=alsoNotify.begin();j!=alsoNotify.end();++j) {
     try {
       const ComboAddress caIp(*j, 53);
-      L<<Logger::Warning<<"Queued also-notification of domain '"<<di.zone<<"' to "<<caIp.toStringWithPort()<<endl;
+      g_log<<Logger::Warning<<"Queued also-notification of domain '"<<di.zone<<"' to "<<caIp.toStringWithPort()<<endl;
       if (!ips.count(caIp.toStringWithPort())) {
         ips.insert(caIp.toStringWithPort());
         d_nq.add(di.zone, caIp.toStringWithPort());
@@ -92,12 +92,12 @@ void CommunicatorClass::queueNotifyDomain(const DomainInfo& di, UeberBackend* B)
       hasQueuedItem=true;
     }
     catch(PDNSException &e) {
-      L<<Logger::Warning<<"Unparseable IP in ALSO-NOTIFY metadata of domain '"<<di.zone<<"'. Warning: "<<e.reason<<endl;
+      g_log<<Logger::Warning<<"Unparseable IP in ALSO-NOTIFY metadata of domain '"<<di.zone<<"'. Warning: "<<e.reason<<endl;
     }
   }
 
   if (!hasQueuedItem)
-    L<<Logger::Warning<<"Request to queue notification for domain '"<<di.zone<<"' was processed, but no valid nameservers or ALSO-NOTIFYs found. Not notifying!"<<endl;
+    g_log<<Logger::Warning<<"Request to queue notification for domain '"<<di.zone<<"' was processed, but no valid nameservers or ALSO-NOTIFYs found. Not notifying!"<<endl;
 }
 
 
@@ -106,7 +106,7 @@ bool CommunicatorClass::notifyDomain(const DNSName &domain)
   DomainInfo di;
   UeberBackend B;
   if(!B.getDomainInfo(domain, di)) {
-    L<<Logger::Error<<"No such domain '"<<domain<<"' in our database"<<endl;
+    g_log<<Logger::Error<<"No such domain '"<<domain<<"' in our database"<<endl;
     return false;
   }
   queueNotifyDomain(di, &B);
@@ -135,12 +135,12 @@ void CommunicatorClass::masterUpdateCheck(PacketHandler *P)
   
   if(cmdomains.empty()) {
     if(d_masterschanged)
-      L<<Logger::Warning<<"No master domains need notifications"<<endl;
+      g_log<<Logger::Warning<<"No master domains need notifications"<<endl;
     d_masterschanged=false;
   }
   else {
     d_masterschanged=true;
-    L<<Logger::Error<<cmdomains.size()<<" domain"<<(cmdomains.size()>1 ? "s" : "")<<" for which we are master need"<<
+    g_log<<Logger::Error<<cmdomains.size()<<" domain"<<(cmdomains.size()>1 ? "s" : "")<<" for which we are master need"<<
       (cmdomains.size()>1 ? "" : "s")<<
       " notifications"<<endl;
   }
@@ -149,8 +149,7 @@ void CommunicatorClass::masterUpdateCheck(PacketHandler *P)
   // do this via the FindNS class, d_fns
   
   for(auto& di : cmdomains) {
-    extern PacketCache PC;
-    PC.purgeExact(di.zone);
+    purgeAuthCachesExact(di.zone);
     queueNotifyDomain(di, B);
     di.backend->setNotified(di.id, di.serial);
   }
@@ -163,9 +162,10 @@ time_t CommunicatorClass::doNotifications()
   char buffer[1500];
   int sock;
   ssize_t size;
+  set<int> fds = {d_nsock4, d_nsock6};
 
   // receive incoming notifications on the nonblocking socket and take them off the list
-  while(waitFor2Data(d_nsock4, d_nsock6, 0, 0, &sock) > 0) {
+  while(waitForMultiData(fds, 0, 0, &sock) > 0) {
     fromlen=sizeof(from);
     size=recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr *)&from,&fromlen);
     if(size < 0)
@@ -175,17 +175,17 @@ time_t CommunicatorClass::doNotifications()
     p.setRemote(&from);
 
     if(p.parse(buffer,(size_t)size)<0) {
-      L<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
+      g_log<<Logger::Warning<<"Unable to parse SOA notification answer from "<<p.getRemote()<<endl;
       continue;
     }
 
     if(p.d.rcode)
-      L<<Logger::Warning<<"Received unsuccessful notification report for '"<<p.qdomain<<"' from "<<from.toStringWithPort()<<", error: "<<RCode::to_s(p.d.rcode)<<endl;      
+      g_log<<Logger::Warning<<"Received unsuccessful notification report for '"<<p.qdomain<<"' from "<<from.toStringWithPort()<<", error: "<<RCode::to_s(p.d.rcode)<<endl;      
 
     if(d_nq.removeIf(from.toStringWithPort(), p.d.id, p.qdomain))
-      L<<Logger::Warning<<"Removed from notification list: '"<<p.qdomain<<"' to "<<from.toStringWithPort()<<" "<< (p.d.rcode ? RCode::to_s(p.d.rcode) : "(was acknowledged)")<<endl;      
+      g_log<<Logger::Warning<<"Removed from notification list: '"<<p.qdomain<<"' to "<<from.toStringWithPort()<<" "<< (p.d.rcode ? RCode::to_s(p.d.rcode) : "(was acknowledged)")<<endl;      
     else {
-      L<<Logger::Warning<<"Received spurious notify answer for '"<<p.qdomain<<"' from "<< from.toStringWithPort()<<endl;
+      g_log<<Logger::Warning<<"Received spurious notify answer for '"<<p.qdomain<<"' from "<< from.toStringWithPort()<<endl;
       //d_nq.dump();
     }
   }
@@ -201,20 +201,23 @@ time_t CommunicatorClass::doNotifications()
       try {
         ComboAddress remote(ip, 53); // default to 53
         if((d_nsock6 < 0 && remote.sin4.sin_family == AF_INET6) ||
-           (d_nsock4 < 0 && remote.sin4.sin_family == AF_INET))
+           (d_nsock4 < 0 && remote.sin4.sin_family == AF_INET)) {
+             g_log<<Logger::Warning<<"Unable to notify "<<remote.toStringWithPort()<<" for domain '"<<domain<<"', address family is disabled. Is query-local-address"<<(remote.sin4.sin_family == AF_INET ? "" : "6")<<" unset?"<<endl;
+             d_nq.removeIf(remote.toStringWithPort(), id, domain); // Remove, we'll never be able to notify
              continue; // don't try to notify what we can't!
+        }
         if(d_preventSelfNotification && AddressIsUs(remote))
           continue;
 
-        sendNotification(remote.sin4.sin_family == AF_INET ? d_nsock4 : d_nsock6, domain, remote, id); 
+        sendNotification(remote.sin4.sin_family == AF_INET ? d_nsock4 : d_nsock6, domain, remote, id);
         drillHole(domain, ip);
       }
       catch(ResolverException &re) {
-        L<<Logger::Error<<"Error trying to resolve '"<<ip<<"' for notifying '"<<domain<<"' to server: "<<re.reason<<endl;
+        g_log<<Logger::Error<<"Error trying to resolve '"<<ip<<"' for notifying '"<<domain<<"' to server: "<<re.reason<<endl;
       }
     }
     else
-      L<<Logger::Error<<"Notification for "<<domain<<" to "<<ip<<" failed after retries"<<endl;
+      g_log<<Logger::Error<<"Notification for "<<domain<<" to "<<ip<<" failed after retries"<<endl;
   }
 
   return d_nq.earliest();
@@ -229,7 +232,7 @@ void CommunicatorClass::sendNotification(int sock, const DNSName& domain, const
   string tsigsecret64;
   string tsigsecret;
 
-  if (B.getDomainMetadata(domain, "TSIG-ALLOW-AXFR", meta) && meta.size() > 0) {
+  if (::arg().mustDo("send-signed-notify") && B.getDomainMetadata(domain, "TSIG-ALLOW-AXFR", meta) && meta.size() > 0) {
     tsigkeyname = DNSName(meta[0]);
   }
 
@@ -239,7 +242,10 @@ void CommunicatorClass::sendNotification(int sock, const DNSName& domain, const
   pw.getHeader()->aa = true; 
 
   if (tsigkeyname.empty() == false) {
-    B.getTSIGKey(tsigkeyname, &tsigalgorithm, &tsigsecret64);
+    if (!B.getTSIGKey(tsigkeyname, &tsigalgorithm, &tsigsecret64)) {
+      g_log<<Logger::Error<<"TSIG key '"<<tsigkeyname<<"' for domain '"<<domain<<"' not found"<<endl;
+      return;
+    }
     TSIGRecordContent trc;
     if (tsigalgorithm.toStringNoDot() == "hmac-md5")
       trc.d_algoName = DNSName(tsigalgorithm.toStringNoDot() + ".sig-alg.reg.int.");
@@ -249,7 +255,10 @@ void CommunicatorClass::sendNotification(int sock, const DNSName& domain, const
     trc.d_fudge = 300;
     trc.d_origID=ntohs(id);
     trc.d_eRcode=0;
-    B64Decode(tsigsecret64, tsigsecret);
+    if (B64Decode(tsigsecret64, tsigsecret) == -1) {
+      g_log<<Logger::Error<<"Unable to Base-64 decode TSIG key '"<<tsigkeyname<<"' for domain '"<<domain<<"'"<<endl;
+      return;
+    }
     addTSIG(pw, trc, tsigkeyname, tsigsecret, "", false);
   }
 
@@ -279,11 +288,16 @@ bool CommunicatorClass::justNotified(const DNSName &domain, const string &ip)
 
 void CommunicatorClass::makeNotifySockets()
 {
-  d_nsock4 = makeQuerySocket(ComboAddress(::arg()["query-local-address"]), true, ::arg().mustDo("non-local-bind"));
-  if(!::arg()["query-local-address6"].empty())
+  if(!::arg()["query-local-address"].empty()) {
+    d_nsock4 = makeQuerySocket(ComboAddress(::arg()["query-local-address"]), true, ::arg().mustDo("non-local-bind"));
+  } else {
+    d_nsock4 = -1;
+  }
+  if(!::arg()["query-local-address6"].empty()) {
     d_nsock6 = makeQuerySocket(ComboAddress(::arg()["query-local-address6"]), true, ::arg().mustDo("non-local-bind"));
-  else
+  } else {
     d_nsock6 = -1;
+  }
 }
 
 void CommunicatorClass::notify(const DNSName &domain, const string &ip)