bool logDNSQueries = ::arg().mustDo("log-dns-queries");
bool skipfirst=true;
unsigned int maintcount = 0;
+ UDPNameserver *NS = N;
+
+ // If we have SO_REUSEPORT then create a new port for all receiver threads
+ // other than the first one.
+ if( number > 0 && NS->canReusePort() )
+ NS = new UDPNameserver();
+
for(;;) {
if (skipfirst)
skipfirst=false;
}
}
- if(!(P=N->receive(&question))) { // receive a packet inline
+
+ if(!(P=NS->receive(&question))) { // receive a packet inline
continue; // packet was broken, try again
}
cached.d.id=P->d.id;
cached.commitD(); // commit d to the packet inlined
- N->send(&cached); // answer it then inlined
+ NS->send(&cached); // answer it then inlined
diff=P->d_dt.udiff();
avg_latency=(int)(0.999*avg_latency+0.001*diff); // 'EWMA'
{
vector<string>locals;
stringtok(locals,::arg()["local-address"]," ,");
+ int one = 1;
if(locals.empty())
throw PDNSException("No local address specified");
memset(&locala,0,sizeof(locala));
locala.sin4.sin_family=AF_INET;
- if(localname=="0.0.0.0") {
- int val=1;
- setsockopt(s, IPPROTO_IP, GEN_IP_PKTINFO, &val, sizeof(val));
- }
+ if(localname=="0.0.0.0")
+ setsockopt(s, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one));
+
+#ifdef SO_REUSEPORT
+ if( setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) )
+ d_can_reuseport = false;
+#endif
+
locala=ComboAddress(localname, ::arg().asNum("local-port"));
if(locala.sin4.sin_family != AF_INET)
throw PDNSException("Attempting to bind IPv4 socket to IPv6 address");
#if HAVE_IPV6
vector<string> locals;
stringtok(locals,::arg()["local-ipv6"]," ,");
+ int one=1;
if(locals.empty())
return;
ComboAddress locala(localname, ::arg().asNum("local-port"));
if(IsAnyAddress(locala)) {
- int val=1;
- setsockopt(s, IPPROTO_IP, GEN_IP_PKTINFO, &val, sizeof(val)); // linux supports this, so why not - might fail on other systems
- setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &val, sizeof(val));
- setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val)); // if this fails, we report an error in tcpreceiver too
+ setsockopt(s, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)); // linux supports this, so why not - might fail on other systems
+ setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one));
+ setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); // if this fails, we report an error in tcpreceiver too
}
+
+#ifdef SO_REUSEPORT
+ if( setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) )
+ d_can_reuseport = false;
+#endif
+
g_localaddresses.push_back(locala);
if(::bind(s, (sockaddr*)&locala, sizeof(locala))<0) {
L<<Logger::Error<<"binding to UDP ipv6 socket: "<<strerror(errno)<<endl;
UDPNameserver::UDPNameserver()
{
+#ifdef SO_REUSEPORT
+ d_can_reuseport = true;
+#endif
+
if(!::arg()["local-address"].empty())
bindIPv4();
if(!::arg()["local-ipv6"].empty())