]> granicus.if.org Git - pdns/commitdiff
auth: Create additional `reuseport` sockets before dropping privileges
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 6 Mar 2017 17:26:27 +0000 (18:26 +0100)
committermind04 <mind04@monshouwer.org>
Thu, 4 May 2017 20:38:34 +0000 (22:38 +0200)
pdns/common_startup.cc
pdns/common_startup.hh
pdns/receiver.cc

index 6572f6b2655f232cd88e958dea17bc34dd9b6f06..c8f41ebddb7d114fdce0a5b440b753b795d4b2dc 100644 (file)
@@ -43,10 +43,11 @@ PacketCache PC; //!< This is the main PacketCache, shared across all threads
 DNSProxy *DP;
 DynListener *dl;
 CommunicatorClass Communicator;
-UDPNameserver *N;
+shared_ptr<UDPNameserver> N;
 int avg_latency;
 TCPNameserver *TN;
-vector<DNSDistributor*> g_distributors;
+static vector<DNSDistributor*> g_distributors;
+vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
 AuthLua *LPE;
 
 ArgvMap &arg()
@@ -358,18 +359,17 @@ void *qthread(void *number)
   int diff;
   bool logDNSQueries = ::arg().mustDo("log-dns-queries");
   bool doRecursion = ::arg().mustDo("recursor");
-  UDPNameserver *NS = N;
+  shared_ptr<UDPNameserver> NS;
 
   // If we have SO_REUSEPORT then create a new port for all receiver threads
   // other than the first one.
-  if( number != NULL && NS->canReusePort() ) {
-    L<<Logger::Notice<<"Starting new listen thread on the same IPs/ports using SO_REUSEPORT"<<endl;
-    try {
-      NS = new UDPNameserver( true );
-    } catch(PDNSException &e) {
-      L<<Logger::Error<<"Unable to reuse port, falling back to original bind"<<endl;
+  if( number != NULL && N->canReusePort() ) {
+    NS = g_udpReceivers[num];
+    if (NS == nullptr) {
       NS = N;
     }
+  } else {
+    NS = N;
   }
 
   for(;;) {
index fed4fcc2ad49121efd82655e9c22d0259018d5cc..76112ce19d8d3808baee5df5495beaa1ea4d8c64 100644 (file)
@@ -40,7 +40,8 @@ extern PacketCache PC; //!< This is the main PacketCache, shared across all thre
 extern DNSProxy *DP;
 extern DynListener *dl;
 extern CommunicatorClass Communicator;
-extern UDPNameserver *N;
+extern std::shared_ptr<UDPNameserver> N;
+extern vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
 extern int avg_latency;
 extern TCPNameserver *TN;
 extern AuthLua *LPE;
index 6d597312ca116e87514f6307adb517aa9c97ed66..8a0cc55c3a24371f5702f7fb70fb700d1993d4e9 100644 (file)
@@ -605,8 +605,24 @@ int main(int argc, char **argv)
     }
 
     UeberBackend::go();
-    N=new UDPNameserver; // this fails when we are not root, throws exception
-    
+    N=std::make_shared<UDPNameserver>(); // this fails when we are not root, throws exception
+    g_udpReceivers.push_back(N);
+
+    size_t rthreads = ::arg().asNum("receiver-threads", 1);
+    if (rthreads > 1 && N->canReusePort()) {
+      g_udpReceivers.resize(rthreads);
+
+      for (size_t idx = 1; idx < rthreads; idx++) {
+        try {
+          g_udpReceivers[idx] = std::make_shared<UDPNameserver>(true);
+        }
+        catch(const PDNSException& e) {
+          L<<Logger::Error<<"Unable to reuse port, falling back to original bind"<<endl;
+          break;
+        }
+      }
+    }
+
     if(!::arg().mustDo("disable-tcp"))
       TN=new TCPNameserver; 
   }