From: bert hubert Date: Sun, 5 May 2013 19:22:03 +0000 (+0200) Subject: after a decade+.. finally try to stop notifying ourselves. In convoluted X-Git-Tag: auth-3.3-rc1~40^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8db49a64b49c747a89f22e1942f77483b6e473b3;p=thirdparty%2Fpdns.git after a decade+.. finally try to stop notifying ourselves. In convoluted cases involving REUSE_PORT and binding to 0.0.0.0 and ::, it might be possible that we guess wrong, in which case we now provide & document the setting prevent-self-notification which you could then set to off. --- diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index 4f0959cbdb..fc86aca499 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -96,7 +96,7 @@ void declareArguments() ::arg().setSwitch("guardian","Run within a guardian process")="no"; ::arg().setSwitch("strict-rfc-axfrs","Perform strictly rfc compliant axfrs (very slow)")="no"; ::arg().setSwitch("send-root-referral","Send out old-fashioned root-referral instead of ServFail in case of no authority")="no"; - + ::arg().setSwitch("prevent-self-notification","Don't send notifications to what we think is ourself")="yes"; ::arg().setSwitch("webserver","Start a webserver for monitoring")="no"; ::arg().setSwitch("webserver-print-arguments","If the webserver should print arguments")="no"; ::arg().setSwitch("edns-subnet-processing","If we should act on EDNS Subnet options")="no"; diff --git a/pdns/communicator.cc b/pdns/communicator.cc index 889f1b7135..4f2038e79b 100644 --- a/pdns/communicator.cc +++ b/pdns/communicator.cc @@ -58,6 +58,7 @@ void CommunicatorClass::go() for(int n=0; n < ::arg().asNum("retrieval-threads"); ++n) pthread_create(&tid, 0, &retrieveLaunchhelper, this); // Starts CommunicatorClass::retrievalLoopThread() + d_preventSelfNotification =::arg().mustDo("prevent-self-notification"); } void CommunicatorClass::mainloop(void) diff --git a/pdns/communicator.hh b/pdns/communicator.hh index d2e15a6d6b..267a2a94ad 100644 --- a/pdns/communicator.hh +++ b/pdns/communicator.hh @@ -198,6 +198,7 @@ private: bool d_masterschanged, d_slaveschanged; set d_tocheck; vector d_potentialsupermasters; + bool d_preventSelfNotification; }; #endif diff --git a/pdns/docs/pdns.xml b/pdns/docs/pdns.xml index a0b485a1b7..71fb35fa86 100644 --- a/pdns/docs/pdns.xml +++ b/pdns/docs/pdns.xml @@ -14628,6 +14628,12 @@ Tell PowerDNS to log all incoming DNS queries. This will lead to a lot of loggin ABI version to use for the pipe backend. See . + prevent-self-notification | prevent-self-notification = yes | prevent-self-notification = no + + Available as of 3.3. PowerDNS Authoritative Server attempts to not send out notifications to itself in master mode. + In very complicated situations we could guess wrong and not notify a server that should be notified. In that case, + set prevent-self-notification to "no". + query-cache-ttl=... diff --git a/pdns/mastercommunicator.cc b/pdns/mastercommunicator.cc index 8a72e31a21..c8cf3dbf28 100644 --- a/pdns/mastercommunicator.cc +++ b/pdns/mastercommunicator.cc @@ -25,6 +25,7 @@ #include "dnsbackend.hh" #include "ueberbackend.hh" #include "packethandler.hh" +#include "nameserver.hh" #include "resolver.hh" #include "logger.hh" #include "dns.hh" @@ -168,6 +169,9 @@ time_t CommunicatorClass::doNotifications() if((d_nsock6 < 0 && remote.sin4.sin_family == AF_INET6) || (d_nsock4 < 0 && remote.sin4.sin_family == AF_INET)) continue; // don't try to notify what we can't! + if(d_preventSelfNotification && AddressIsUs(remote)) + continue; + sendNotification(remote.sin4.sin_family == AF_INET ? d_nsock4 : d_nsock6, domain, remote, id); drillHole(domain, ip); } @@ -225,7 +229,6 @@ void CommunicatorClass::makeNotifySockets() void CommunicatorClass::notify(const string &domain, const string &ip) { d_nq.add(domain, ip); - d_any_sem.post(); } diff --git a/pdns/nameserver.cc b/pdns/nameserver.cc index 1eb3ae1fb7..5584a62ac3 100644 --- a/pdns/nameserver.cc +++ b/pdns/nameserver.cc @@ -83,6 +83,7 @@ extern StatBag S; #define GEN_IP_PKTINFO IP_RECVDSTADDR #endif +vector g_localaddresses; void UDPNameserver::bindIPv4() { @@ -95,7 +96,7 @@ void UDPNameserver::bindIPv4() int s; for(vector::const_iterator i=locals.begin();i!=locals.end();++i) { string localname(*i); - struct sockaddr_in locala; + ComboAddress locala; s=socket(AF_INET,SOCK_DGRAM,0); @@ -108,12 +109,12 @@ void UDPNameserver::bindIPv4() throw AhuException("Unable to set UDP socket to non-blocking: "+stringerror()); memset(&locala,0,sizeof(locala)); - locala.sin_family=AF_INET; + 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)); - locala.sin_addr.s_addr = INADDR_ANY; + locala.sin4.sin_addr.s_addr = INADDR_ANY; } else { @@ -122,17 +123,17 @@ void UDPNameserver::bindIPv4() if(!h) throw AhuException("Unable to resolve local address"); - locala.sin_addr.s_addr=*(int*)h->h_addr; + locala.sin4.sin_addr.s_addr=*(int*)h->h_addr; } - locala.sin_port=htons(::arg().asNum("local-port")); - - if(::bind(s, (sockaddr*)&locala,sizeof(locala))<0) { - L<(ntohs(locala.sin_port))+": "<(ntohs(locala.sin4.sin_port))+": "< d_rfds; }; - - +bool AddressIsUs(const ComboAddress& remote); #endif