From: Remi Gacogne Date: Mon, 6 Mar 2017 17:26:27 +0000 (+0100) Subject: auth: Create additional `reuseport` sockets before dropping privileges X-Git-Tag: auth-4.0.4-rc1~3^2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a03cfa7ad5a9dd1dd02ef17c56f68b03b695ca7a;p=pdns auth: Create additional `reuseport` sockets before dropping privileges --- diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index 6572f6b26..c8f41ebdd 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -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 N; int avg_latency; TCPNameserver *TN; -vector g_distributors; +static vector g_distributors; +vector > 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 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<canReusePort() ) { + NS = g_udpReceivers[num]; + if (NS == nullptr) { NS = N; } + } else { + NS = N; } for(;;) { diff --git a/pdns/common_startup.hh b/pdns/common_startup.hh index fed4fcc2a..76112ce19 100644 --- a/pdns/common_startup.hh +++ b/pdns/common_startup.hh @@ -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 N; +extern vector > g_udpReceivers; extern int avg_latency; extern TCPNameserver *TN; extern AuthLua *LPE; diff --git a/pdns/receiver.cc b/pdns/receiver.cc index 6d597312c..8a0cc55c3 100644 --- a/pdns/receiver.cc +++ b/pdns/receiver.cc @@ -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(); // 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(true); + } + catch(const PDNSException& e) { + L<