]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: make outgoing-query-address{,6} behaviour equivalent
authorPieter Lexis <pieter.lexis@powerdns.com>
Thu, 2 Nov 2017 19:46:21 +0000 (20:46 +0100)
committerPieter Lexis <pieter.lexis@powerdns.com>
Tue, 23 Jan 2018 15:15:24 +0000 (16:15 +0100)
If either is unset, don't send out notifications or AXFR requests using
that address family.

pdns/mastercommunicator.cc
pdns/resolver.cc
pdns/rfc2136handler.cc
pdns/slavecommunicator.cc

index 456957a80d789aff457de76fe71bccccef6b1f9d..2b6e25047ad6d6e854220d68c65f7c4999462217 100644 (file)
@@ -200,12 +200,15 @@ 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)) {
+             L<<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) {
@@ -284,11 +287,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)
index 81eabdfea634537da3459596293707812f230221..78b7fbde92b26d6e1b378ca3c42750906f5d4e6f 100644 (file)
@@ -99,13 +99,16 @@ Resolver::Resolver()
   locals["default4"] = -1;
   locals["default6"] = -1;
   try {
-    locals["default4"] = makeQuerySocket(ComboAddress(::arg()["query-local-address"]), true, ::arg().mustDo("non-local-bind"));
+    if(!::arg()["query-local-address"].empty())
+      locals["default4"] = makeQuerySocket(ComboAddress(::arg()["query-local-address"]), true, ::arg().mustDo("non-local-bind"));
     if(!::arg()["query-local-address6"].empty())
       locals["default6"] = makeQuerySocket(ComboAddress(::arg()["query-local-address6"]), true, ::arg().mustDo("non-local-bind"));
   }
   catch(...) {
     if(locals["default4"]>=0)
       close(locals["default4"]);
+    if(locals["default6"]>=0)
+      close(locals["default6"]);
     throw;
   }
 }
@@ -153,6 +156,11 @@ uint16_t Resolver::sendResolve(const ComboAddress& remote, const ComboAddress& l
   if (local.sin4.sin_family == 0) {
     // up to us.
     sock = remote.sin4.sin_family == AF_INET ? locals["default4"] : locals["default6"];
+    if (sock == -1) {
+      string ipv = remote.sin4.sin_family == AF_INET ? "4" : "6";
+      string qla = remote.sin4.sin_family == AF_INET ? "" : "6";
+      throw ResolverException("No IPv" + ipv + " socket available, is query-local-address" + qla + " unset?");
+    }
   } else {
     std::string lstr = local.toString();
     std::map<std::string, int>::iterator lptr;
@@ -357,15 +365,14 @@ AXFRRetriever::AXFRRetriever(const ComboAddress& remote,
   : d_tsigVerifier(tt, remote, d_trc), d_receivedBytes(0), d_maxReceivedBytes(maxReceivedBytes)
 {
   ComboAddress local;
-  if (laddr != NULL) {
-    local = (ComboAddress) (*laddr);
+  if (laddr != nullptr) {
+    local = ComboAddress(*laddr);
   } else {
-    if(remote.sin4.sin_family == AF_INET)
+    if(remote.sin4.sin_family == AF_INET && !::arg()["query-local-address"].empty()) {
       local=ComboAddress(::arg()["query-local-address"]);
-    else if(!::arg()["query-local-address6"].empty())
+    } else if(remote.sin4.sin_family == AF_INET6 && !::arg()["query-local-address6"].empty()) {
       local=ComboAddress(::arg()["query-local-address6"]);
-    else
-      local=ComboAddress("::");
+    }
   }
   d_sock = -1;
   try {
index d6a7d64637c51fa389195b8764b7b587e797042b..072cb0779a26065b9ba10a93d3262917ea460ccd 100644 (file)
@@ -597,12 +597,13 @@ int PacketHandler::forwardPacket(const string &msgPrefix, DNSPacket *p, DomainIn
     }
 
     ComboAddress local;
-    if(remote.sin4.sin_family == AF_INET)
+    if (remote.sin4.sin_family == AF_INET && !::arg()["query-local-address"].empty()) {
       local = ComboAddress(::arg()["query-local-address"]);
-    else if(!::arg()["query-local-address6"].empty())
+    } else if(remote.sin4.sin_family == AF_INET6 && !::arg()["query-local-address6"].empty()) {
       local = ComboAddress(::arg()["query-local-address6"]);
-    else
-      local = ComboAddress("::");
+    } else {
+      continue;
+    }
     int sock = makeQuerySocket(local, false); // create TCP socket. RFC2136 section 6.2 seems to be ok with this.
     if(sock < 0) {
       L<<Logger::Error<<msgPrefix<<"Error creating socket: "<<stringerror()<<endl;
index 748522b41a734c2d7ecaa8d215fc2f980c043d19..59ee0a25df308f33d2bcc7778d61132f0048283a 100644 (file)
@@ -363,13 +363,16 @@ void CommunicatorClass::suck(const DNSName &domain, const string &remote)
         L<<Logger::Error<<"Failed to load AXFR source '"<<localaddr[0]<<"' for incoming AXFR of '"<<domain<<"': "<<e.what()<<endl;
         return;
       }
-    } else { 
-      if(raddr.sin4.sin_family == AF_INET)
-        laddr=ComboAddress(::arg()["query-local-address"]);
-      else if(!::arg()["query-local-address6"].empty())
-        laddr=ComboAddress(::arg()["query-local-address6"]);
-      else
-        laddr.sin4.sin_family = 0;
+    } else {
+      if(raddr.sin4.sin_family == AF_INET && !::arg()["query-local-address"].empty()) {
+        laddr = ComboAddress(::arg()["query-local-address"]);
+      } else if(raddr.sin4.sin_family == AF_INET6 && !::arg()["query-local-address6"].empty()) {
+        laddr = ComboAddress(::arg()["query-local-address6"]);
+      } else {
+        bool isv6 = raddr.sin4.sin_family == AF_INET6;
+        L<<Logger::Error<<"Unable to AXFR, destination address is IPv" << (isv6 ? "6" : "4") << ", but query-local-address"<< (isv6 ? "6" : "") << " is unset!"<<endl;
+        return;
+      }
     }
 
     bool hadDnssecZone = false;