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()
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(;;) {
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;
}
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;
}