}
}
+ bool isMappedIPv4()
+ {
+ if(sin4.sin_family!=AF_INET6)
+ return false;
+
+ int n=0;
+ const unsigned char*ptr = (unsigned char*) &sin6.sin6_addr.s6_addr;
+ for(n=0; n < 10; ++n)
+ if(ptr[n])
+ return false;
+
+ for(; n < 12; ++n)
+ if(ptr[n]!=0xff)
+ return false;
+
+ return true;
+ }
+
+ ComboAddress mapToIPv4()
+ {
+ if(!isMappedIPv4())
+ throw AhuException("ComboAddress can't map non-mapped IPv6 address back to IPv4");
+ ComboAddress ret;
+ ret.sin4.sin_family=AF_INET;
+ ret.sin4.sin_port=0;
+
+ const unsigned char*ptr = (unsigned char*) &sin6.sin6_addr.s6_addr;
+ ptr+=12;
+ memcpy(&ret.sin4.sin_addr.s_addr, ptr, 4);
+ return ret;
+ }
+
string toString() const
{
char tmp[128];
d_bits=128;
}
+ bool match(const ComboAddress& ip) const
+ {
+ return match(&ip);
+ }
+
//! If this IP address in socket address matches
bool match(const ComboAddress *ip) const
{
bool match(ComboAddress *ip)
{
for(container_t::const_iterator i=d_masks.begin();i!=d_masks.end();++i)
- if(i->match(ip))
+ if(i->match(ip) || (ip->isMappedIPv4() && i->match(ip->mapToIPv4()) ))
return true;
return false;
if(newsock>0) {
g_stats.addRemote(addr);
if(g_allowFrom && !g_allowFrom->match(&addr)) {
+ if(!g_quiet)
+ L<<Logger::Error<<"["<<MT->getTid()<<"] dropping TCP query from "<<addr.toString()<<", address not matched by allow-from"<<endl;
+
g_stats.unauthorizedTCP++;
Utility::closesocket(newsock);
return;
g_fdm->setReadTTD(tc.fd, now, g_tcpTimeout);
}
}
-
+
void handleNewUDPQuestion(int fd, boost::any& var)
{
int len;
if((len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) {
g_stats.addRemote(fromaddr);
if(g_allowFrom && !g_allowFrom->match(&fromaddr)) {
+ cout<<"mapped: "<<fromaddr.isMappedIPv4()<<endl;
+ if(!g_quiet)
+ L<<Logger::Error<<"["<<MT->getTid()<<"] dropping UDP query from "<<fromaddr.toString()<<", address not matched by allow-from"<<endl;
+
g_stats.unauthorizedUDP++;
return;
}
::arg().set("server-id", "Returned when queried for 'server.id' TXT, defaults to hostname")="";
::arg().set("remotes-ringbuffer-entries", "maximum number of packets to store statistics for")="0";
::arg().set("version-string", "string reported on version.pdns or version.bind")="PowerDNS Recursor "VERSION" $Id$";
- ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse")="127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12";
+ ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse")="127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fe80::/16";
::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)")="0";
::arg().set("fork", "If set, fork the daemon for possible double performance")="no";
::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses")="20";