From 3a56adcc8b9e18aaf56cee75df0eaa15d48a6db4 Mon Sep 17 00:00:00 2001 From: Mark Zealey Date: Mon, 9 Dec 2013 14:01:02 +0200 Subject: [PATCH] more changes --- pdns/common_startup.cc | 7 +++++-- pdns/docs/pdns.xml | 12 ++++++++++++ pdns/nameserver.cc | 25 ++++++++++++++----------- pdns/nameserver.hh | 3 ++- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index af0bd6b52..2294ce605 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -54,6 +54,7 @@ void declareArguments() ::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().set("local-ipv6","Local IP address to which we bind")=""; + ::arg().setSwitch("reuseport","Enable higher performance on compliant kernels by using SO_REUSEPORT allowing each receiver thread to open its own socket")=""; ::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"; @@ -247,8 +248,10 @@ void *qthread(void *number) // 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(); + if( number > 0 && NS->canReusePort() ) { + L< If this many packets are waiting for database attention, answer any new questions strictly from the packet cache. + reuseport=[yes|no] + + On Linux 3.9 and some BSD kernels the SO_REUSEPORT option allows each + receiver-thread to open a new socket on the same port which allows + for much higher performance on multi-core boxes. Setting this option + will enable use of SO_REUSEPORT when available and seamlessly fall + back to a single socket when it is not available. A side-effect is + that you can start multiple servers on the same IP/port combination + which may or may not be a good idea. You could use this to enable + transparent restarts, but it may also mask configuration issues and + for this reason it is disabled by default. + server-id diff --git a/pdns/nameserver.cc b/pdns/nameserver.cc index 5b99520a1..75ab1d511 100644 --- a/pdns/nameserver.cc +++ b/pdns/nameserver.cc @@ -89,7 +89,6 @@ extern StatBag S; #endif vector g_localaddresses; // not static, our unit tests need to poke this -pthread_mutex_t localaddresses_lock=PTHREAD_MUTEX_INITIALIZER; void UDPNameserver::bindIPv4() { @@ -124,17 +123,17 @@ void UDPNameserver::bindIPv4() 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; + if( d_can_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"); - pthread_mutex_lock(&localaddresses_lock); - g_localaddresses.push_back(locala); - pthread_mutex_unlock(&localaddresses_lock); + if( !d_additional_socket ) + g_localaddresses.push_back(locala); if(::bind(s, (sockaddr*)&locala, locala.getSocklen()) < 0) { L<