]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
This patch allows user to specify that socket binding can fail. On IPv4 there
authorMark Zealey <mark@markandruth.co.uk>
Mon, 2 Dec 2013 08:02:28 +0000 (10:02 +0200)
committerMark Zealey <mark@markandruth.co.uk>
Mon, 2 Dec 2013 08:02:28 +0000 (10:02 +0200)
is a ip_nonlocal_bind sysctl that can be set, however for IPv6 there is not
this call and it is unlikely to be implemented kernel-side.

Fixes PowerDNS/pdns#344

pdns/common_startup.cc
pdns/nameserver.cc
pdns/tcpreceiver.cc

index eb75054918ef18c16aaf984742d2f391b9909750..ad9e26b33f871f719c078b0480016f08621a5aa0 100644 (file)
@@ -53,7 +53,9 @@ void declareArguments()
   ::arg().set("urlredirector","Where we send hosts to that need to be url redirected")="127.0.0.1";
   ::arg().set("smtpredirector","Our smtpredir MX host")="a.misconfigured.powerdns.smtp.server";
   ::arg().set("local-address","Local IP addresses to which we bind")="0.0.0.0";
+  ::arg().setSwitch("local-address-nonexist-fail","Fail to start if one or more of the local-address's do not exist on this server")="yes";
   ::arg().set("local-ipv6","Local IP address to which we bind")="";
+  ::arg().setSwitch("local-ipv6-nonexist-fail","Fail to start if one or more of the local-ipv6 addresses do not exist on this server")="yes";
   ::arg().set("query-local-address","Source IP address for sending queries")="0.0.0.0";
   ::arg().set("query-local-address6","Source IPv6 address for sending queries")="::";
   ::arg().set("overload-queue-length","Maximum queuelength moving to packetcache only")="0";
index c5b0bb036591996d48753b03e2c5f8a20057e490..790557695279784e52fd3c4e5198dc0cbde9ee3b 100644 (file)
@@ -126,8 +126,13 @@ void UDPNameserver::bindIPv4()
 
     g_localaddresses.push_back(locala);
     if(::bind(s, (sockaddr*)&locala, locala.getSocklen()) < 0) {
-      L<<Logger::Error<<"binding UDP socket to '"+locala.toStringWithPort()+": "<<strerror(errno)<<endl;
-      throw PDNSException("Unable to bind to UDP socket");
+      if( errno == EADDRNOTAVAIL && ! ::arg().mustDo("local-address-nonexist-fail") ) {
+        L<<Logger::Error<<"IPv4 Address " << localname << " does not exist on this server - skipping UDP bind" << endl;
+        continue;
+      } else {
+        L<<Logger::Error<<"binding UDP socket to '"+locala.toStringWithPort()+": "<<strerror(errno)<<endl;
+        throw PDNSException("Unable to bind to UDP socket");
+      }
     }
     d_sockets.push_back(s);
     L<<Logger::Error<<"UDP server bound to "<<locala.toStringWithPort()<<endl;
@@ -215,8 +220,13 @@ void UDPNameserver::bindIPv6()
     }
     g_localaddresses.push_back(locala);
     if(::bind(s, (sockaddr*)&locala, sizeof(locala))<0) {
-      L<<Logger::Error<<"binding to UDP ipv6 socket: "<<strerror(errno)<<endl;
-      throw PDNSException("Unable to bind to UDP ipv6 socket");
+      if( errno == EADDRNOTAVAIL && ! ::arg().mustDo("local-ipv6-nonexist-fail") ) {
+        L<<Logger::Error<<"IPv6 Address " << localname << " does not exist on this server - skipping UDP bind" << endl;
+        continue;
+      } else {
+        L<<Logger::Error<<"binding to UDP ipv6 socket "<< localname <<": "<<strerror(errno)<<endl;
+        throw AhuException("Unable to bind to UDP ipv6 socket");
+      }
     }
     d_sockets.push_back(s);
     struct pollfd pfd;
index f61d0e1efd4293fbd076bb6b16fe1f1f270a4062..35b986afe766ac4bab2a5c34355b8027fb9243a9 100644 (file)
@@ -879,8 +879,13 @@ TCPNameserver::TCPNameserver()
     }
     
     if(::bind(s, (sockaddr*)&local, local.getSocklen())<0) {
-      L<<Logger::Error<<"binding to TCP socket: "<<strerror(errno)<<endl;
-      throw PDNSException("Unable to bind to TCP socket");
+      if( errno == EADDRNOTAVAIL && ! ::arg().mustDo("local-address-nonexist-fail") ) {
+        L<<Logger::Error<<"IPv4 Address " << *laddr << " does not exist on this server - skipping TCP bind" << endl;
+        continue;
+      } else {
+        L<<Logger::Error<<"binding to TCP socket " << *laddr << ": "<<strerror(errno)<<endl;
+        throw AhuException("Unable to bind to TCP socket");
+      }
     }
     
     listen(s,128);
@@ -914,8 +919,13 @@ TCPNameserver::TCPNameserver()
       L<<Logger::Error<<"Failed to set IPv6 socket to IPv6 only, continuing anyhow: "<<strerror(errno)<<endl;
     }
     if(bind(s, (const sockaddr*)&local, local.getSocklen())<0) {
-      L<<Logger::Error<<"binding to TCP socket: "<<strerror(errno)<<endl;
-      throw PDNSException("Unable to bind to TCPv6 socket");
+      if( errno == EADDRNOTAVAIL && ! ::arg().mustDo("local-ipv6-nonexist-fail") ) {
+        L<<Logger::Error<<"IPv6 Address " << *laddr << " does not exist on this server - skipping TCP bind" << endl;
+        continue;
+      } else {
+        L<<Logger::Error<<"binding to TCPv6 socket" << *laddr << ": "<<strerror(errno)<<endl;
+        throw AhuException("Unable to bind to TCPv6 socket");
+      }
     }
     
     listen(s,128);