::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";
#include "dnsbackend.hh"
#include "ueberbackend.hh"
#include "packethandler.hh"
+#include "nameserver.hh"
#include "resolver.hh"
#include "logger.hh"
#include "dns.hh"
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);
}
void CommunicatorClass::notify(const string &domain, const string &ip)
{
d_nq.add(domain, ip);
-
d_any_sem.post();
}
#define GEN_IP_PKTINFO IP_RECVDSTADDR
#endif
+vector<ComboAddress> g_localaddresses;
void UDPNameserver::bindIPv4()
{
int s;
for(vector<string>::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);
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
{
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<<Logger::Error<<"binding UDP socket to '"+localname+"' port "+lexical_cast<string>(ntohs(locala.sin_port))+": "<<strerror(errno)<<endl;
+ locala.sin4.sin_port=htons(::arg().asNum("local-port"));
+ g_localaddresses.push_back(locala);
+ if(::bind(s, (sockaddr*)&locala, locala.getSocklen()) < 0) {
+ L<<Logger::Error<<"binding UDP socket to '"+localname+"' port "+lexical_cast<string>(ntohs(locala.sin4.sin_port))+": "<<strerror(errno)<<endl;
throw AhuException("Unable to bind to UDP socket");
}
d_sockets.push_back(s);
- L<<Logger::Error<<"UDP server bound to "<<inet_ntoa(locala.sin_addr)<<":"<<::arg().asNum("local-port")<<endl;
+ L<<Logger::Error<<"UDP server bound to "<<inet_ntoa(locala.sin4.sin_addr)<<":"<<::arg().asNum("local-port")<<endl;
struct pollfd pfd;
pfd.fd = s;
pfd.events = POLLIN;
return false;
}
+
+bool AddressIsUs(const ComboAddress& remote)
+{
+ BOOST_FOREACH(const ComboAddress& us, g_localaddresses) {
+ if(remote == us)
+ return true;
+ if(IsAnyAddress(us)) {
+ int s = socket(AF_INET, SOCK_DGRAM, 0);
+ if(s < 0)
+ continue;
+
+ if(connect(s, (struct sockaddr*)&remote, remote.getSocklen()) < 0) {
+ close(s);
+ continue;
+ }
+
+ ComboAddress actualLocal;
+ actualLocal.sin4.sin_family = remote.sin4.sin_family;
+ socklen_t socklen = actualLocal.getSocklen();
+
+ if(getsockname(s, (struct sockaddr*) &actualLocal, &socklen) < 0) {
+ close(s);
+ continue;
+ }
+ close(s);
+ actualLocal.sin4.sin_port = us.sin4.sin_port;
+ if(actualLocal == remote)
+ return true;
+ }
+ }
+ return false;
+}
+
+
void UDPNameserver::bindIPv6()
{
#if !WIN32 && HAVE_IPV6
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
}
-
+ g_localaddresses.push_back(locala);
if(::bind(s, (sockaddr*)&locala, sizeof(locala))<0) {
L<<Logger::Error<<"binding to UDP ipv6 socket: "<<strerror(errno)<<endl;
throw AhuException("Unable to bind to UDP ipv6 socket");