From: Peter van Dijk Date: Mon, 15 Jun 2015 13:47:10 +0000 (+0200) Subject: recursor runs! X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~58^2~21^2~5^2~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ddb92472535d02360c6fbd69298d86cf30608ef;p=thirdparty%2Fpdns.git recursor runs! --- diff --git a/pdns/misc.cc b/pdns/misc.cc index 6e673a9ab4..5c7862d428 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -59,7 +59,7 @@ int writen2(int fd, const void *buf, size_t count) { const char *ptr = (char*)buf; const char *eptr = ptr + count; - + int res; while(ptr != eptr) { res = ::write(fd, ptr, eptr - ptr); @@ -71,10 +71,10 @@ int writen2(int fd, const void *buf, size_t count) } else if (res == 0) throw std::runtime_error("could not write all bytes, got eof in writen2"); - + ptr += res; } - + return count; } @@ -84,15 +84,15 @@ int readn2(int fd, void* buffer, unsigned int len) int res; for(;;) { res = read(fd, (char*)buffer + pos, len - pos); - if(res == 0) + if(res == 0) throw runtime_error("EOF while writing message"); if(res < 0) { if (errno == EAGAIN) throw std::runtime_error("used writen2 on non-blocking socket, got EAGAIN"); else unixDie("failed in writen2"); - } - + } + pos+=res; if(pos == len) break; @@ -150,14 +150,14 @@ bool stripDomainSuffix(string *qname, const string &domain) } /** Chops off the start of a domain, so goes from 'www.ds9a.nl' to 'ds9a.nl' to 'nl' to ''. Return zero on the empty string */ -bool chopOff(string &domain) +bool chopOff(string &domain) { if(domain.empty()) return false; string::size_type fdot=domain.find('.'); - if(fdot==string::npos) + if(fdot==string::npos) domain=""; else { string::size_type remain = domain.length() - (fdot + 1); @@ -178,7 +178,7 @@ bool chopOffDotted(string &domain) if(fdot == string::npos) return false; - if(fdot==domain.size()-1) + if(fdot==domain.size()-1) domain="."; else { string::size_type remain = domain.length() - (fdot + 1); @@ -203,14 +203,14 @@ bool ciEqual(const string& a, const string& b) } /** does domain end on suffix? Is smart about "wwwds9a.nl" "ds9a.nl" not matching */ -bool endsOn(const string &domain, const string &suffix) +bool endsOn(const string &domain, const string &suffix) { if( suffix.empty() || ciEqual(domain, suffix) ) return true; if(domain.size()<=suffix.size()) return false; - + string::size_type dpos=domain.size()-suffix.size()-1, spos=0; if(domain[dpos++]!='.') @@ -223,15 +223,22 @@ bool endsOn(const string &domain, const string &suffix) return true; } +// REMOVE ME +bool dottedEndsOn(const DNSName &domain, const DNSName &suffix) +{ + return domain.isPartOf(suffix); +} + + /** does domain end on suffix? Is smart about "wwwds9a.nl" "ds9a.nl" not matching */ -bool dottedEndsOn(const string &domain, const string &suffix) +bool dottedEndsOn(const string &domain, const string &suffix) { if( suffix=="." || ciEqual(domain, suffix) ) return true; if(domain.size()<=suffix.size()) return false; - + string::size_type dpos=domain.size()-suffix.size()-1, spos=0; if(domain[dpos++]!='.') @@ -299,7 +306,7 @@ int waitForRWData(int fd, bool waitForRead, int seconds, int useconds) struct pollfd pfd; memset(&pfd, 0, sizeof(pfd)); pfd.fd = fd; - + if(waitForRead) pfd.events=POLLIN; else @@ -321,7 +328,7 @@ int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd) memset(&pfds[0], 0, 2*sizeof(struct pollfd)); pfds[0].fd = fd1; pfds[1].fd = fd2; - + pfds[0].events= pfds[1].events = POLLIN; int nsocks = 1 + (fd2 >= 0); // fd2 can optionally be -1 @@ -332,7 +339,7 @@ int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd) ret = poll(pfds, nsocks, -1); if(!ret || ret < 0) return ret; - + if((pfds[0].revents & POLLIN) && !(pfds[1].revents & POLLIN)) *fd = pfds[0].fd; else if((pfds[1].revents & POLLIN) && !(pfds[0].revents & POLLIN)) @@ -342,7 +349,7 @@ int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd) } else *fd = -1; // should never happen - + return 1; } @@ -386,7 +393,7 @@ const string unquotify(const string &item) string::size_type bpos=0, epos=item.size(); - if(item[0]=='"') + if(item[0]=='"') bpos=1; if(item[epos-1]=='"') @@ -478,7 +485,7 @@ bool IpToU32(const string &str, uint32_t *ip) *ip=0; return true; } - + struct in_addr inp; if(inet_aton(str.c_str(), &inp)) { *ip=inp.s_addr; @@ -490,7 +497,7 @@ bool IpToU32(const string &str, uint32_t *ip) string U32ToIP(uint32_t val) { char tmp[17]; - snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u", + snprintf(tmp, sizeof(tmp)-1, "%u.%u.%u.%u", (val >> 24)&0xff, (val >> 16)&0xff, (val >> 8)&0xff, @@ -516,24 +523,24 @@ string makeHexDump(const string& str) void shuffle(vector& rrs) { vector::iterator first, second; - for(first=rrs.begin();first!=rrs.end();++first) + for(first=rrs.begin();first!=rrs.end();++first) if(first->d_place==DNSResourceRecord::ANSWER && first->qtype.getCode() != QType::CNAME) // CNAME must come first break; for(second=first;second!=rrs.end();++second) if(second->d_place!=DNSResourceRecord::ANSWER) break; - + if(second-first>1) random_shuffle(first,second); - + // now shuffle the additional records - for(first=second;first!=rrs.end();++first) + for(first=second;first!=rrs.end();++first) if(first->d_place==DNSResourceRecord::ADDITIONAL && first->qtype.getCode() != QType::CNAME) // CNAME must come first break; for(second=first;second!=rrs.end();++second) if(second->d_place!=DNSResourceRecord::ADDITIONAL) break; - + if(second-first>1) random_shuffle(first,second); @@ -658,7 +665,7 @@ string labelReverse(const std::string& qname) string makeRelative(const std::string& fqdn, const std::string& zone) { if(zone.empty()) - return fqdn; + return fqdn; if(toLower(fqdn) != toLower(zone)) return fqdn.substr(0, fqdn.size() - zone.length() - 1); // strip domain name return ""; @@ -668,7 +675,7 @@ string dotConcat(const std::string& a, const std::string &b) { if(a.empty() || b.empty()) return a+b; - else + else return a+"."+b; } @@ -683,7 +690,7 @@ int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret) if(pos == string::npos || pos + 2 > addr.size() || addr[pos+1]!=':') return -1; ourAddr.assign(addr.c_str() + 1, pos-1); - port = atoi(addr.c_str()+pos+2); + port = atoi(addr.c_str()+pos+2); } ret->sin6_scope_id=0; ret->sin6_family=AF_INET6; @@ -692,15 +699,15 @@ int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret) struct addrinfo* res; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); - + hints.ai_family = AF_INET6; hints.ai_flags = AI_NUMERICHOST; - + int error; if((error=getaddrinfo(ourAddr.c_str(), 0, &hints, &res))) { // this is correct return -1; } - + memcpy(ret, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); } @@ -717,7 +724,7 @@ int makeIPv4sockaddr(const std::string& str, struct sockaddr_in* ret) return -1; } struct in_addr inp; - + string::size_type pos = str.find(':'); if(pos == string::npos) { // no port specified, not touching the port if(inet_aton(str.c_str(), &inp)) { @@ -727,13 +734,13 @@ int makeIPv4sockaddr(const std::string& str, struct sockaddr_in* ret) return -1; } if(!*(str.c_str() + pos + 1)) // trailing : - return -1; - + return -1; + char *eptr = (char*)str.c_str() + str.size(); int port = strtol(str.c_str() + pos + 1, &eptr, 10); if(*eptr) return -1; - + ret->sin_port = htons(port); if(inet_aton(str.substr(0, pos).c_str(), &inp)) { ret->sin_addr.s_addr=inp.s_addr; @@ -761,12 +768,12 @@ bool stringfgets(FILE* fp, std::string& line) { char buffer[1024]; line.clear(); - + do { if(!fgets(buffer, sizeof(buffer), fp)) return !line.empty(); - - line.append(buffer); + + line.append(buffer); } while(!strchr(buffer, '\n')); return true; } @@ -933,14 +940,14 @@ uint32_t pdns_strtoui(const char *nptr, char **endptr, int base) if (val > UINT_MAX) { errno = ERANGE; return UINT_MAX; - } + } return val; #endif } bool setNonBlocking(int sock) { - int flags=fcntl(sock,F_GETFL,0); + int flags=fcntl(sock,F_GETFL,0); if(flags<0 || fcntl(sock, F_SETFL,flags|O_NONBLOCK) <0) return false; return true; @@ -948,7 +955,7 @@ bool setNonBlocking(int sock) bool setBlocking(int sock) { - int flags=fcntl(sock,F_GETFL,0); + int flags=fcntl(sock,F_GETFL,0); if(flags<0 || fcntl(sock, F_SETFL,flags&(~O_NONBLOCK)) <0) return false; return true; @@ -960,14 +967,14 @@ int closesocket( int socket ) int ret=::close(socket); if(ret < 0 && errno == ECONNRESET) // see ticket 192, odd BSD behaviour return 0; - if(ret < 0) + if(ret < 0) throw PDNSException("Error closing socket: "+stringerror()); return ret; } bool setCloseOnExec(int sock) { - int flags=fcntl(sock,F_GETFD,0); + int flags=fcntl(sock,F_GETFD,0); if(flags<0 || fcntl(sock, F_SETFD,flags|FD_CLOEXEC) <0) return false; return true; diff --git a/pdns/misc.hh b/pdns/misc.hh index 90bf5b7983..e1aaeab140 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -89,23 +89,23 @@ stringtok (Container &container, string const &in, { const string::size_type len = in.length(); string::size_type i = 0; - + while (i RHEL5. + + // the below is necessary because __sync_fetch_and_add is not universally available on i386.. I 3> RHEL5. #if defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) static native_t atomic_exchange_and_add( native_t * pw, native_t dv ) { @@ -428,7 +428,7 @@ private: return r; } - #else + #else static native_t atomic_exchange_and_add( native_t * pw, native_t dv ) { return __sync_fetch_and_add(pw, dv); @@ -437,7 +437,7 @@ private: }; // FIXME this should probably go? -struct CIStringCompare: public std::binary_function +struct CIStringCompare: public std::binary_function { bool operator()(const string& a, const string& b) const { @@ -461,7 +461,7 @@ struct CIStringComparePOSIX } }; -struct CIStringPairCompare: public std::binary_function, pair, bool> +struct CIStringPairCompare: public std::binary_function, pair, bool> { bool operator()(const pair& a, const pair& b) const { @@ -494,6 +494,14 @@ inline bool isCanonical(const string& qname) return qname[qname.size()-1]=='.'; } +inline bool isCanonical(const DNSName& qname) +{ + if(qname.empty()) + return false; + return true; +} + + inline DNSName toCanonic(const DNSName& zone, const string& qname) { if(qname.size()==1 && qname[0]=='@') @@ -529,7 +537,7 @@ class Regex public: /** constructor that accepts the expression to regex */ Regex(const string &expr); - + ~Regex() { regfree(&d_preg); diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 6dc510e451..fabc2f88c1 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -3,7 +3,7 @@ Copyright (C) 2003 - 2015 PowerDNS.COM BV This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 + it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation Additionally, the license of this program contains a special @@ -30,7 +30,7 @@ #include "ws-recursor.hh" #include #include "recpacketcache.hh" -#include "utility.hh" +#include "utility.hh" #include "dns_random.hh" #include #include @@ -135,7 +135,7 @@ unsigned int g_numThreads, g_numWorkerThreads; #define LOCAL_NETS "127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10" // Bad Nets taken from both: -// http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +// http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml // and // http://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml // where such a network may not be considered a valid destination @@ -144,7 +144,7 @@ unsigned int g_numThreads, g_numWorkerThreads; //! used to send information to a newborn mthread struct DNSComboWriter { - DNSComboWriter(const char* data, uint16_t len, const struct timeval& now) : d_mdp(data, len), d_now(now), + DNSComboWriter(const char* data, uint16_t len, const struct timeval& now) : d_mdp(data, len), d_now(now), d_tcp(false), d_socket(-1) {} MOADNSParser d_mdp; @@ -187,12 +187,12 @@ ArgvMap &arg() void handleTCPClientWritable(int fd, FDMultiplexer::funcparam_t& var); // -1 is error, 0 is timeout, 1 is success -int asendtcp(const string& data, Socket* sock) +int asendtcp(const string& data, Socket* sock) { PacketID pident; pident.sock=sock; pident.outMSG=data; - + t_fdm->addWriteFD(sock->getHandle(), handleTCPClientWritable, pident); string packet; @@ -230,7 +230,7 @@ int arecvtcp(string& data, int len, Socket* sock, bool incompleteOkay) return ret; } -vector g_localQueryAddresses4, g_localQueryAddresses6; +vector g_localQueryAddresses4, g_localQueryAddresses6; const ComboAddress g_local4("0.0.0.0"), g_local6("::"); //! pick a random query local address @@ -238,9 +238,9 @@ ComboAddress getQueryLocalAddress(int family, uint16_t port) { ComboAddress ret; if(family==AF_INET) { - if(g_localQueryAddresses4.empty()) + if(g_localQueryAddresses4.empty()) ret = g_local4; - else + else ret = g_localQueryAddresses4[dns_random(g_localQueryAddresses4.size())]; ret.sin4.sin_port = htons(port); } @@ -249,7 +249,7 @@ ComboAddress getQueryLocalAddress(int family, uint16_t port) ret = g_local6; else ret = g_localQueryAddresses6[dns_random(g_localQueryAddresses6.size())]; - + ret.sin6.sin6_port = htons(port); } return ret; @@ -261,10 +261,10 @@ void setSocketBuffer(int fd, int optname, uint32_t size) { uint32_t psize=0; socklen_t len=sizeof(psize); - + if(!getsockopt(fd, SOL_SOCKET, optname, (char*)&psize, &len) && psize > size) { L<= 0) + if (::bind(ret, (struct sockaddr *)&sin, sin.getSocklen()) >= 0) break; } if(!tries) throw PDNSException("Resolver binding to local query client socket: "+stringerror()); - + setNonBlocking(ret); return ret; } @@ -384,8 +384,8 @@ static __thread UDPClientSocks* t_udpclientsocks; /* these two functions are used by LWRes */ // -2 is OS error, -1 is error that depends on the remote, > 0 is success -int asendto(const char *data, int len, int flags, - const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, int* fd) +int asendto(const char *data, int len, int flags, + const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, int* fd) { PacketID pident; @@ -415,7 +415,7 @@ int asendto(const char *data, int len, int flags, pident.fd=*fd; pident.id=id; - + t_fdm->addReadFD(*fd, handleUDPServerResponse, pident); ret = send(*fd, data, len, 0); @@ -429,11 +429,11 @@ int asendto(const char *data, int len, int flags, } // -1 is error, 0 is timeout, 1 is success -int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int *d_len, +int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int *d_len, uint16_t id, const DNSName& domain, uint16_t qtype, int fd, struct timeval* now) { static optional nearMissLimit; - if(!nearMissLimit) + if(!nearMissLimit) nearMissLimit=::arg().asNum("spoof-nearmiss-max"); PacketID pident; @@ -448,7 +448,7 @@ int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int if(ret > 0) { if(packet.empty()) // means "error" - return -1; + return -1; *d_len=(int)packet.size(); memcpy(data,packet.c_str(),min(len,*d_len)); @@ -480,21 +480,21 @@ typedef map tcpClient tcpClientCounts_t __thread* t_tcpClientCounts; TCPConnection::TCPConnection(int fd, const ComboAddress& addr) : d_remote(addr), d_fd(fd) -{ - ++s_currentConnections; +{ + ++s_currentConnections; (*t_tcpClientCounts)[d_remote]++; } TCPConnection::~TCPConnection() { - if(closesocket(d_fd) < 0) + if(closesocket(d_fd) < 0) unixDie("closing socket for TCPConnection"); - if(t_tcpClientCounts->count(d_remote) && !(*t_tcpClientCounts)[d_remote]--) + if(t_tcpClientCounts->count(d_remote) && !(*t_tcpClientCounts)[d_remote]--) t_tcpClientCounts->erase(d_remote); --s_currentConnections; } -AtomicCounter TCPConnection::s_currentConnections; +AtomicCounter TCPConnection::s_currentConnections; void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var); // the idea is, only do things that depend on the *response* here. Incoming accounting is on incoming. @@ -543,12 +543,12 @@ void startDoResolve(void *p) if(getEDNSOpts(dc->d_mdp, &edo) && !dc->d_tcp) { maxanswersize = min(edo.d_packetsize, g_udpTruncationThreshold); } - ComboAddress local; + ComboAddress local; listenSocketsAddresses_t::const_iterator lociter; vector ret; vector packet; - DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); + DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); pw.getHeader()->aa=0; pw.getHeader()->ra=1; @@ -580,7 +580,7 @@ void startDoResolve(void *p) sr.setLogMode(SyncRes::Store); tracedQuery=true; } - + if(!g_quiet || tracedQuery) L<getTid()<<"/"<numProcesses()<<"] " << (dc->d_tcp ? "TCP " : "") << "question for '"<d_mdp.d_qname<<"|" <d_mdp.d_qtype)<<"' from "<getRemote()<d_socket, (sockaddr*)&local, &len); // if this fails, we're ok with it } - // if there is a RecursorLua active, and it 'took' the query in preResolve, we don't launch beginResolve + // if there is a RecursorLua active, and it 'took' the query in preResolve, we don't launch beginResolve if(!t_pdl->get() || !(*t_pdl)->preresolve(dc->d_remote, local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer)) { try { res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret); @@ -614,7 +614,7 @@ void startDoResolve(void *p) if(t_pdl->get()) { if(res == RCode::NoError) { vector::const_iterator i; - for(i=ret.begin(); i!=ret.end(); ++i) + for(i=ret.begin(); i!=ret.end(); ++i) if(i->qtype.getCode() == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER) break; if(i == ret.end()) @@ -622,17 +622,17 @@ void startDoResolve(void *p) } else if(res == RCode::NXDomain) (*t_pdl)->nxdomain(dc->d_remote,local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer); - + (*t_pdl)->postresolve(dc->d_remote,local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer); } } - + if(res == PolicyDecision::DROP) { g_stats.policyDrops++; delete dc; dc=0; return; - } + } if(tracedQuery || res == PolicyDecision::PASS || res == RCode::ServFail || pw.getHeader()->rcode == RCode::ServFail) { string trace(sr.getTrace()); @@ -645,7 +645,7 @@ void startDoResolve(void *p) } } } - + if(res == PolicyDecision::PASS) { pw.getHeader()->rcode=RCode::ServFail; // no commit here, because no record @@ -654,18 +654,18 @@ void startDoResolve(void *p) else { pw.getHeader()->rcode=res; - + if(ret.size()) { orderAndShuffle(ret); for(vector::const_iterator i=ret.begin(); i!=ret.end(); ++i) { - pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place); + pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place); minTTL = min(minTTL, i->ttl); if(i->qtype.getCode() == QType::A) { // blast out A record w/o doing whole dnswriter thing uint32_t ip=0; IpToU32(i->content, &ip); pw.xfr32BitInt(htonl(ip)); } else { - shared_ptr drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content)); + shared_ptr drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content)); drc->toPacket(pw); } if(pw.size() > maxanswersize) { @@ -697,10 +697,10 @@ void startDoResolve(void *p) sendmsg(dc->d_socket, &msgh, 0); if(!SyncRes::s_nopacketcache && !variableAnswer ) { t_packetCache->insertResponsePacket(string((const char*)&*packet.begin(), packet.size()), - g_now.tv_sec, - min(minTTL, + g_now.tv_sec, + min(minTTL, (pw.getHeader()->rcode == RCode::ServFail) ? SyncRes::s_packetcacheservfailttl : SyncRes::s_packetcachettl - ) + ) ); } } @@ -717,17 +717,17 @@ void startDoResolve(void *p) int ret=Utility::writev(dc->d_socket, iov, 2); bool hadError=true; - if(ret == 0) + if(ret == 0) L<getRemote()<getRemote()<<": "<< strerror(errno) <getRemote()<<" for "<d_mdp.d_qname<<" (size="<< (2 + packet.size()) <<", sent "<d_socket = -1; @@ -739,7 +739,7 @@ void startDoResolve(void *p) t_fdm->setReadTTD(dc->d_socket, g_now, g_tcpTimeout); } } - + if(!g_quiet) { L<getTid()<<"/"<numProcesses()<<"] answer to "<<(dc->d_mdp.d_header.rd?"":"non-rd ")<<"question '"<d_mdp.d_qname<<"|"<d_mdp.d_qtype); L<<"': "<ancount)<<" answers, "<arcount)<<" additional, took "<getMaxStackUsage(), g_stats.maxMThreadStackUsage); } @@ -794,7 +794,7 @@ void makeControlChannelSocket(int processNum=-1) sockname += "."+lexical_cast(processNum); sockname+=".controlsocket"; s_rcc.listen(sockname); - + int sockowner = -1; int sockgroup = -1; @@ -802,7 +802,7 @@ void makeControlChannelSocket(int processNum=-1) sockgroup=::arg().asGid("socket-group"); if (!::arg().isEmpty("socket-owner")) sockowner=::arg().asUid("socket-owner"); - + if (sockgroup > -1 || sockowner > -1) { if(chown(sockname.c_str(), sockowner, sockgroup) < 0) { unixDie("Failed to chown control socket"); @@ -824,7 +824,7 @@ void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) int bytes=recv(conn->getFD(), conn->data, 2, 0); if(bytes==1) conn->state=TCPConnection::BYTE1; - if(bytes==2) { + if(bytes==2) { conn->qlen=(((unsigned char)conn->data[0]) << 8)+ (unsigned char)conn->data[1]; conn->bytesread=0; conn->state=TCPConnection::GETQUESTION; @@ -864,7 +864,7 @@ void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) dc=new DNSComboWriter(conn->data, conn->qlen, g_now); } catch(MOADNSException &mde) { - g_stats.clientParseError++; + g_stats.clientParseError++; if(g_logCommonErrors) L<d_remote.toString() <push_back(addr); if(t_allowFrom && !t_allowFrom->match(&addr)) { - if(!g_quiet) + if(!g_quiet) L<getTid()<<"] dropping TCP query from "< tc(new TCPConnection(newsock, addr)); tc->state=TCPConnection::BYTE0; - + t_fdm->addReadFD(tc->getFD(), handleRunningTCPQuestion, tc); struct timeval now; @@ -933,7 +933,7 @@ void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& ) t_fdm->setReadTTD(tc->getFD(), now, g_tcpTimeout); } } - + string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fromaddr, const ComboAddress& destaddr, struct timeval tv, int fd) { gettimeofday(&g_now, 0); @@ -956,7 +956,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr if(!g_quiet) L<push_back("packetcached"); - + g_stats.packetCacheHits++; SyncRes::s_queries++; ageDNSPacket(response, age); @@ -980,12 +980,12 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr g_stats.avgLatencyUsec=(1-1.0/g_latencyStatSize)*g_stats.avgLatencyUsec + 0.0; // we assume 0 usec return 0; } - } + } catch(std::exception& e) { L<get()) { if((*t_pdl)->ipfilter(fromaddr, destaddr)) { if(!g_quiet) @@ -1002,7 +1002,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr g_stats.overCapacityDrops++; return 0; } - + DNSComboWriter* dc = new DNSComboWriter(question.c_str(), question.size(), g_now); dc->setSocket(fd); dc->setRemote(&fromaddr); @@ -1011,8 +1011,8 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr dc->d_tcp=false; MT->makeThread(startDoResolve, (void*) dc); // deletes dc return 0; -} - +} + void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var) { @@ -1026,13 +1026,13 @@ void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var) fromaddr.sin6.sin6_family=AF_INET6; // this makes sure fromaddr is big enough fillMSGHdr(&msgh, &iov, cbuf, sizeof(cbuf), data, sizeof(data), &fromaddr); - for(;;) + for(;;) if((len=recvmsg(fd, &msgh, 0)) >= 0) { if(t_remotes) t_remotes->push_back(fromaddr); if(t_allowFrom && !t_allowFrom->match(&fromaddr)) { - if(!g_quiet) + if(!g_quiet) L<getTid()<<"] dropping UDP query from "<getTid()<<"] dropping UDP query from "<qr) { if(g_logCommonErrors) L<::const_iterator i=locals.begin();i!=locals.end();++i) { ServiceTuple st; st.port=::arg().asNum("local-port"); parseService(*i, st); - + ComboAddress sin; memset((char *)&sin,0, sizeof(sin)); @@ -1109,11 +1109,11 @@ void makeTCPServerSockets() if(!IpToU32(st.host, (uint32_t*)&sin.sin4.sin_addr.s_addr)) { sin.sin6.sin6_family = AF_INET6; if(makeIPv6sockaddr(st.host, &sin.sin6) < 0) - throw PDNSException("Unable to resolve local address for TCP server on '"+ st.host +"'"); + throw PDNSException("Unable to resolve local address for TCP server on '"+ st.host +"'"); } fd=socket(sin.sin6.sin6_family, SOCK_STREAM, 0); - if(fd<0) + if(fd<0) throw PDNSException("Making a TCP server socket for resolver: "+stringerror()); setCloseOnExec(fd); @@ -1139,9 +1139,9 @@ void makeTCPServerSockets() sin.sin4.sin_port = htons(st.port); int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6); - if (::bind(fd, (struct sockaddr *)&sin, socklen )<0) + if (::bind(fd, (struct sockaddr *)&sin, socklen )<0) throw PDNSException("Binding TCP server socket for "+ st.host +": "+stringerror()); - + setNonBlocking(fd); setSocketSendBuffer(fd, 65000); listen(fd, 128); @@ -1149,7 +1149,7 @@ void makeTCPServerSockets() g_tcpListenSockets.push_back(fd); // we don't need to update g_listenSocketsAddresses since it doesn't work for TCP/IP: // - fd is not that which we know here, but returned from accept() - if(sin.sin4.sin_family == AF_INET) + if(sin.sin4.sin_family == AF_INET) L<::const_iterator i=locals.begin();i!=locals.end();++i) { ServiceTuple st; st.port=::arg().asNum("local-port"); @@ -1177,9 +1177,9 @@ void makeUDPServerSockets() if(!IpToU32(st.host.c_str() , (uint32_t*)&sin.sin4.sin_addr.s_addr)) { sin.sin6.sin6_family = AF_INET6; if(makeIPv6sockaddr(st.host, &sin.sin6) < 0) - throw PDNSException("Unable to resolve local address for UDP server on '"+ st.host +"'"); + throw PDNSException("Unable to resolve local address for UDP server on '"+ st.host +"'"); } - + int fd=socket(sin.sin4.sin_family, SOCK_DGRAM, 0); if(fd < 0) { throw PDNSException("Making a UDP server socket for resolver: "+netstringerror()); @@ -1190,7 +1190,7 @@ void makeUDPServerSockets() if(IsAnyAddress(sin)) { setsockopt(fd, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)); // linux supports this, so why not - might fail on other systems #ifdef IPV6_RECVPKTINFO - setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)); #endif if(sin.sin6.sin6_family == AF_INET6 && setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)) < 0) { L<(st.port) +" for "+ st.host+": "+stringerror()); - + setNonBlocking(fd); deferredAdd.push_back(make_pair(fd, handleNewUDPQuestion)); g_listenSocketsAddresses[fd]=sin; // this is written to only from the startup thread, not from the workers - if(sin.sin4.sin_family == AF_INET) + if(sin.sin4.sin_family == AF_INET) L<(pleaseGetCacheHits); uint64_t cacheMisses = broadcastAccFunction(pleaseGetCacheMisses); - + if(g_stats.qcounter && (cacheHits + cacheMisses) && SyncRes::s_queries && SyncRes::s_outqueries) { L<(pleaseGetCacheSize)<< " cache entries, "<< broadcastAccFunction(pleaseGetNegCacheSize)<<" negative entries, "<< - (int)((cacheHits*100.0)/(cacheHits+cacheMisses))<<"% cache hits"<(pleaseGetThrottleSize) <<", ns speeds: " - << broadcastAccFunction(pleaseGetNsSpeedsSize)<(pleaseGetNsSpeedsSize)<(pleaseGetPacketCacheSize) << " packet cache entries, "<<(int)(100.0*broadcastAccFunction(pleaseGetPacketCacheHits)/SyncRes::s_queries) << "% packet cache hits"< (time_t)(5 + t_id)) { + + if(now.tv_sec - last_prune > (time_t)(5 + t_id)) { DTime dt; dt.setTimeval(now); t_RC->doPrune(); // this function is local to a thread, so fine anyhow t_packetCache->doPruneTo(::arg().asNum("max-packetcache-entries") / g_numWorkerThreads); - + pruneCollection(t_sstorage->negcache, ::arg().asNum("max-cache-entries") / (g_numWorkerThreads * 10), 200); - + if(!((cleanCounter++)%40)) { // this is a full scan! time_t limit=now.tv_sec-300; for(SyncRes::nsspeeds_t::iterator i = t_sstorage->nsSpeeds.begin() ; i!= t_sstorage->nsSpeeds.end(); ) @@ -1327,12 +1327,12 @@ static void houseKeeping(void *) } last_prune=time(0); } - + if(now.tv_sec - last_rootupdate > 7200) { SyncRes sr(now); sr.setDoEDNS0(true); vector ret; - + sr.setNoCache(); int res=-1; try { @@ -1349,13 +1349,13 @@ static void houseKeeping(void *) else L<func = func; tmsg->wantAnswer = true; if(write(tps.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) unixDie("write to thread pipe returned wrong size or error"); - + string* resp; if(read(tps.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) unixDie("read from thread pipe returned wrong size or error"); - + if(resp) { // cerr <<"got response: " << *resp << endl; delete resp; @@ -1428,32 +1428,33 @@ void broadcastFunction(const pipefunc_t& func, bool skipSelf) } uint32_t g_disthashseed; -void distributeAsyncFunction(const std::string& question, const pipefunc_t& func) +void distributeAsyncFunction(const DNSName& question, const pipefunc_t& func) { - unsigned int hash = hashQuestion(question.c_str(), question.length(), g_disthashseed); + string squestion = question.toString(); + unsigned int hash = hashQuestion(squestion.c_str(), squestion.length(), g_disthashseed); unsigned int target = 1 + (hash % (g_pipes.size()-1)); if(target == t_id) { func(); return; } - ThreadPipeSet& tps = g_pipes[target]; + ThreadPipeSet& tps = g_pipes[target]; ThreadMSG* tmsg = new ThreadMSG(); tmsg->func = func; tmsg->wantAnswer = false; - + if(write(tps.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) - unixDie("write to thread pipe returned wrong size or error"); + unixDie("write to thread pipe returned wrong size or error"); } void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& var) { ThreadMSG* tmsg; - - if(read(fd, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // fd == readToThread + + if(read(fd, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // fd == readToThread unixDie("read from thread pipe returned wrong size or error"); } - + void *resp=0; try { resp = tmsg->func(); @@ -1467,7 +1468,7 @@ void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& var) if(tmsg->wantAnswer) if(write(g_pipes[t_id].writeFromThread, &resp, sizeof(resp)) != sizeof(resp)) unixDie("write to thread pipe returned wrong size or error"); - + delete tmsg; } @@ -1488,12 +1489,18 @@ vector >& operator+=(vector >&a, c return a; } +vector >& operator+=(vector >&a, const vector >& b) +{ + a.insert(a.end(), b.begin(), b.end()); + return a; +} + template T broadcastAccFunction(const boost::function& func, bool skipSelf) { unsigned int n = 0; T ret=T(); - BOOST_FOREACH(ThreadPipeSet& tps, g_pipes) + BOOST_FOREACH(ThreadPipeSet& tps, g_pipes) { if(n++ == t_id) { if(!skipSelf) { @@ -1506,19 +1513,19 @@ template T broadcastAccFunction(const boost::function& func, bool } continue; } - + ThreadMSG* tmsg = new ThreadMSG(); tmsg->func = boost::bind(voider, func); tmsg->wantAnswer = true; - + if(write(tps.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) unixDie("write to thread pipe returned wrong size or error"); - - + + T* resp; if(read(tps.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) unixDie("read from thread pipe returned wrong size or error"); - + if(resp) { //~ cerr <<"got response: " << *resp << endl; ret += *resp; @@ -1531,7 +1538,7 @@ template T broadcastAccFunction(const boost::function& func, bool template string broadcastAccFunction(const boost::function& fun, bool skipSelf); // explicit instantiation template uint64_t broadcastAccFunction(const boost::function& fun, bool skipSelf); // explicit instantiation template vector broadcastAccFunction(const boost::function *()>& fun, bool skipSelf); // explicit instantiation -template vector > broadcastAccFunction(const boost::function > *()>& fun, bool skipSelf); // explicit instantiation +template vector > broadcastAccFunction(const boost::function > *()>& fun, bool skipSelf); // explicit instantiation void handleRCC(int fd, FDMultiplexer::funcparam_t& var) { @@ -1539,7 +1546,7 @@ void handleRCC(int fd, FDMultiplexer::funcparam_t& var) string msg=s_rcc.recv(&remote); RecursorControlParser rcp; RecursorControlParser::func_t* command; - + string answer=rcp.getAnswer(msg, &command); try { s_rcc.send(answer, &remote); @@ -1568,9 +1575,9 @@ void handleTCPClientReadable(int fd, FDMultiplexer::funcparam_t& var) // cerr<<"Got entire load of "<inMSG.size()<<" bytes"<inMSG; - + t_fdm->removeReadFD(fd); - MT->sendEvent(pid, &msg); + MT->sendEvent(pid, &msg); } else { // cerr<<"Still have "<inNeeded<<" left to go"<d_waiters.find(pid); - if(iter != MT->d_waiters.end()) + if(iter != MT->d_waiters.end()) doResends(iter, pid, empty); - + MT->sendEvent(pid, &empty); // this denotes error (does lookup again.. at least L1 will be hot) return; - } + } dnsheader dh; memcpy(&dh, data, sizeof(dh)); - + PacketID pident; pident.remote=fromaddr; pident.id=dh.id; @@ -1697,7 +1704,7 @@ retryWithName: } // be a bit paranoid here since we're weakening our matching - if(pident.domain.empty() && !mthread->key.domain.empty() && !pident.type && mthread->key.type && + if(pident.domain.empty() && !mthread->key.domain.empty() && !pident.type && mthread->key.type && pident.id == mthread->key.id && mthread->key.remote == pident.remote) { // cerr<<"Empty response, rest matches though, sending to a waiter"<key.domain; @@ -1735,7 +1742,7 @@ FDMultiplexer* getMultiplexer() exit(1); } - + string* doReloadLuaScript() { string fname= ::arg()["lua-dns-script"]; @@ -1753,18 +1760,18 @@ string* doReloadLuaScript() L<::const_iterator begin, vector::const_iterator end) { - if(begin != end) + if(begin != end) ::arg().set("lua-dns-script") = *begin; - + return broadcastAccFunction(doReloadLuaScript); -} +} string* pleaseUseNewTraceRegex(const std::string& newRegex) try @@ -1831,12 +1838,12 @@ char** g_argv; void parseACLs() { static bool l_initialized; - + if(l_initialized) { // only reload configuration file on second call string configname=::arg()["config-dir"]+"/recursor.conf"; cleanSlashes(configname); - - if(!::arg().preParseFile(configname.c_str(), "allow-from-file")) + + if(!::arg().preParseFile(configname.c_str(), "allow-from-file")) throw runtime_error("Unable to re-parse configuration file '"+configname+"'"); ::arg().preParseFile(configname.c_str(), "allow-from", LOCAL_NETS); ::arg().preParseFile(configname.c_str(), "include-dir"); @@ -1858,12 +1865,12 @@ void parseACLs() } NetmaskGroup* oldAllowFrom = t_allowFrom, *allowFrom=new NetmaskGroup; - + if(!::arg()["allow-from-file"].empty()) { string line; ifstream ifs(::arg()["allow-from-file"].c_str()); if(!ifs) { - delete allowFrom; + delete allowFrom; throw runtime_error("Could not open '"+::arg()["allow-from-file"]+"': "+stringerror()); } @@ -1883,7 +1890,7 @@ void parseACLs() else if(!::arg()["allow-from"].empty()) { vector ips; stringtok(ips, ::arg()["allow-from"], ", "); - + L<::const_iterator i = ips.begin(); i!= ips.end(); ++i) { allowFrom->addMask(*i); @@ -1894,16 +1901,16 @@ void parseACLs() L< addrs; + vector addrs; if(!::arg()["query-local-address6"].empty()) { SyncRes::s_doIPv6=true; L<(); - + try { if(!::arg()["lua-dns-script"].empty()) { *t_pdl = shared_ptr(new RecursorLua(::arg()["lua-dns-script"])); @@ -2120,28 +2127,28 @@ try L<(); unsigned int ringsize=::arg().asNum("stats-ringbuffer-entries") / g_numWorkerThreads; if(ringsize) { t_remotes = new addrringbuf_t(); if(g_weDistributeQueries) // if so, only 1 thread does recvfrom - t_remotes->set_capacity(::arg().asNum("stats-ringbuffer-entries")); + t_remotes->set_capacity(::arg().asNum("stats-ringbuffer-entries")); else - t_remotes->set_capacity(ringsize); + t_remotes->set_capacity(ringsize); t_servfailremotes = new addrringbuf_t(); - t_servfailremotes->set_capacity(ringsize); + t_servfailremotes->set_capacity(ringsize); t_largeanswerremotes = new addrringbuf_t(); - t_largeanswerremotes->set_capacity(ringsize); + t_largeanswerremotes->set_capacity(ringsize); t_queryring = new boost::circular_buffer >(); - t_queryring->set_capacity(ringsize); + t_queryring->set_capacity(ringsize); t_servfailqueryring = new boost::circular_buffer >(); - t_servfailqueryring->set_capacity(ringsize); + t_servfailqueryring->set_capacity(ringsize); } - + MT=new MTasker(::arg().asNum("stack-size")); - + PacketID pident; t_fdm=getMultiplexer(); @@ -2162,15 +2169,15 @@ try t_fdm->addReadFD(g_pipes[t_id].readToThread, handlePipeRequest); if(!g_weDistributeQueries || !t_id) // if we distribute queries, only t_id = 0 listens - for(deferredAdd_t::const_iterator i=deferredAdd.begin(); i!=deferredAdd.end(); ++i) + for(deferredAdd_t::const_iterator i=deferredAdd.begin(); i!=deferredAdd.end(); ++i) t_fdm->addReadFD(i->first, i->second); - + if(!t_id) { t_fdm->addReadFD(s_rcc.d_fd, handleRCC); // control channel } unsigned int maxTcpClients=::arg().asNum("max-tcp-clients"); - + bool listenOnTCP(true); time_t last_carbon=0; @@ -2178,7 +2185,7 @@ try counter=AtomicCounter(0); // used to periodically execute certain tasks for(;;) { while(MT->schedule(&g_now)); // MTasker letting the mthreads do their thing - + if(!(counter%500)) { MT->makeThread(houseKeeping, 0); } @@ -2186,7 +2193,7 @@ try if(!(counter%55)) { typedef vector > expired_t; expired_t expired=t_fdm->getTimeouts(g_now); - + for(expired_t::iterator i=expired.begin() ; i != expired.end(); ++i) { shared_ptr conn=any_cast >(i->second); if(g_logCommonErrors) @@ -2194,7 +2201,7 @@ try t_fdm->removeReadFD(i->first); } } - + counter++; if(!t_id && statsWanted) { @@ -2243,7 +2250,7 @@ catch(...) { } -int main(int argc, char **argv) +int main(int argc, char **argv) { g_argc = argc; g_argv = argv; @@ -2272,7 +2279,7 @@ int main(int argc, char **argv) ::arg().set("threads", "Launch this number of threads")="2"; ::arg().set("processes", "Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)")="1"; ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")=""; - ::arg().set( "experimental-logfile", "Filename of the log file for JSON parser" )= "/var/log/pdns.log"; + ::arg().set( "experimental-logfile", "Filename of the log file for JSON parser" )= "/var/log/pdns.log"; ::arg().setSwitch("experimental-webserver", "Start a webserver for monitoring") = "no"; ::arg().set("experimental-webserver-address", "IP Address of webserver to listen on") = "127.0.0.1"; ::arg().set("experimental-webserver-port", "Port of webserver to listen on") = "8082"; @@ -2290,7 +2297,7 @@ int main(int argc, char **argv) ::arg().set("socket-owner","Owner of socket")=""; ::arg().set("socket-group","Group of socket")=""; ::arg().set("socket-mode", "Permissions for socket")=""; - + ::arg().set("socket-dir","Where the controlsocket will live")=LOCALSTATEDIR; ::arg().set("delegation-only","Which domains we only accept delegations from")=""; ::arg().set("query-local-address","Source IP address for sending queries")="0.0.0.0"; @@ -2313,7 +2320,7 @@ int main(int argc, char **argv) ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse")=LOCAL_NETS; ::arg().set("allow-from-file", "If set, load allowed netmasks from this file")=""; ::arg().set("entropy-source", "If set, read entropy from this file")="/dev/urandom"; - ::arg().set("dont-query", "If set, do not query these netmasks for DNS data")=DONT_QUERY; + ::arg().set("dont-query", "If set, do not query these netmasks for DNS data")=DONT_QUERY; ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)")="0"; ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses")="20"; ::arg().set("single-socket", "If set, only use a single socket for outgoing queries")="off"; @@ -2327,9 +2334,9 @@ int main(int argc, char **argv) ::arg().set("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space")=""; ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers")=""; ::arg().set("latency-statistic-size","Number of latency values to calculate the qa-latency average")="10000"; -// ::arg().setSwitch( "disable-edns-ping", "Disable EDNSPing - EXPERIMENTAL, LEAVE DISABLED" )= "no"; - ::arg().setSwitch( "disable-edns", "Disable EDNS - EXPERIMENTAL, LEAVE DISABLED" )= ""; - ::arg().setSwitch( "disable-packetcache", "Disable packetcache" )= "no"; +// ::arg().setSwitch( "disable-edns-ping", "Disable EDNSPing - EXPERIMENTAL, LEAVE DISABLED" )= "no"; + ::arg().setSwitch( "disable-edns", "Disable EDNS - EXPERIMENTAL, LEAVE DISABLED" )= ""; + ::arg().setSwitch( "disable-packetcache", "Disable packetcache" )= "no"; ::arg().setSwitch( "pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads")=""; ::arg().setSwitch( "root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist")="no"; ::arg().setSwitch( "any-to-tcp","Answer ANY queries with tc=1, shunting to TCP" )="no"; @@ -2359,7 +2366,7 @@ int main(int argc, char **argv) exit(0); } - if(!::arg().file(configname.c_str())) + if(!::arg().file(configname.c_str())) L<clear(); - if(d_cachecache.first!=d_cachecache.second) { - for(cache_t::const_iterator i=d_cachecache.first; i != d_cachecache.second; ++i) - if(i->d_qtype == qt.getCode() || qt.getCode()==QType::ANY || + if(d_cachecache.first!=d_cachecache.second) { + for(cache_t::const_iterator i=d_cachecache.first; i != d_cachecache.second; ++i) + if(i->d_qtype == qt.getCode() || qt.getCode()==QType::ANY || (qt.getCode()==QType::ADDR && (i->d_qtype == QType::A || i->d_qtype == QType::AAAA) ) - ) { + ) { for(vector::const_iterator k=i->d_records.begin(); k != i->d_records.end(); ++k) { if(k->d_ttd < 1000000000 || k->d_ttd > (uint32_t) now) { // FIXME what does the 100000000 number mean? ttd=k->d_ttd; if(res) { - DNSResourceRecord rr=String2DNSRR(qname, QType(i->d_qtype), k->d_string, ttd); + DNSResourceRecord rr=String2DNSRR(qname, QType(i->d_qtype), k->d_string, ttd); res->insert(rr); } } @@ -154,7 +154,7 @@ int MemRecursorCache::get(time_t now, const DNSName &qname, const QType& qt, set } - + bool MemRecursorCache::attemptToRefreshNSTTL(const QType& qt, const set& content, const CacheEntry& stored) { if(!stored.d_auth) { @@ -212,8 +212,8 @@ void MemRecursorCache::replace(time_t now, const DNSName &qname, const QType& qt if(!auth && ce.d_auth) { // unauth data came in, we have some auth data, but is it fresh? vector::iterator j; - for(j = ce.d_records.begin() ; j != ce.d_records.end(); ++j) - if((time_t)j->d_ttd > now) + for(j = ce.d_records.begin() ; j != ce.d_records.end(); ++j) + if((time_t)j->d_ttd > now) break; if(j != ce.d_records.end()) { // we still have valid data, ignore unauth data // cerr<<"\tStill hold valid auth data, and the new data is unauth, return\n"; @@ -223,14 +223,14 @@ void MemRecursorCache::replace(time_t now, const DNSName &qname, const QType& qt ce.d_auth = false; // new data won't be auth } } - + // limit TTL of auth->auth NSset update if needed, except for root if(ce.d_auth && auth && qt.getCode()==QType::NS && !(qname == DNSName("."))) { // cerr<<"\tLimiting TTL of auth->auth NS set replace"<::iterator j; for(j = ce.d_records.begin() ; j != ce.d_records.end(); ++j) { maxTTD=min(maxTTD, j->d_ttd); - } + } } // make sure that we CAN refresh the root @@ -253,8 +253,8 @@ void MemRecursorCache::replace(time_t now, const DNSName &qname, const QType& qt // cerr<<"To store: "<content<<" with ttl/ttd "<ttl<ttl); dr.d_string=DNSRR2String(*i); - - if(isNew) + + if(isNew) ce.d_records.push_back(dr); else { range=equal_range(ce.d_records.begin(), ce.d_records.end(), dr); @@ -288,10 +288,10 @@ void MemRecursorCache::replace(time_t now, const DNSName &qname, const QType& qt // cerr<<"\tSorting (because of isNew)\n"; sort(ce.d_records.begin(), ce.d_records.end()); } - + if(ce.d_records.capacity() != ce.d_records.size()) vector(ce.d_records).swap(ce.d_records); - + d_cache.replace(stored, ce); } @@ -339,12 +339,12 @@ bool MemRecursorCache::doAgeCache(time_t now, const DNSName& name, uint16_t qtyp d_cachecachevalid=false; uint32_t newTTD = now + newTTL; - + for(vector::iterator j = ce.d_records.begin() ; j != ce.d_records.end(); ++j) { if(j->d_ttd>newTTD) // do never renew expired or older TTLs j->d_ttd = newTTD; } - + d_cache.replace(iter, ce); return true; } @@ -409,4 +409,3 @@ void MemRecursorCache::doPrune(void) unsigned int maxCached=::arg().asNum("max-cache-entries") / g_numThreads; pruneCollection(d_cache, maxCached); } - diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 704f2b11f6..5f4236d538 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -191,7 +191,7 @@ bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vectorfirst) && wcarddomain.chopOff()) { LOG(prefix<second.d_records.equal_range(boost::make_tuple(DNSName("*")+wcarddomain)); + range=iter->second.d_records.equal_range(boost::make_tuple(DNSName("*")+wcarddomain)); if(range.first==range.second) continue; @@ -211,7 +211,7 @@ bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vectorfirst)) { - range=iter->second.d_records.equal_range(boost::make_tuple(nsdomain,QType(QType::NS))); + range=iter->second.d_records.equal_range(boost::make_tuple(nsdomain,QType(QType::NS))); if(range.first==range.second) continue; @@ -221,7 +221,7 @@ bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vectorsecond.d_records.find(boost::make_tuple(authdomain, QType(QType::SOA))); if(ziter!=iter->second.d_records.end()) { @@ -251,7 +251,7 @@ void SyncRes::doEDNSDumpAndClose(int fd) fclose(fp); } -int SyncRes::asyncresolveWrapper(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res) +int SyncRes::asyncresolveWrapper(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res) { /* what is your QUEST? the goal is to get as many remotes as possible on the highest level of hipness: EDNS PING responders. @@ -432,7 +432,7 @@ int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vectordomainmap->end()) { if( iter->second.d_servers.empty() ) @@ -657,14 +657,14 @@ bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector res=RCode::ServFail; return true; } - + LOG(prefix< cset; if(t_RC->get(d_now.tv_sec, qname,QType(QType::CNAME),&cset) > 0) { for(set::const_iterator j=cset.begin();j!=cset.end();++j) { if(j->ttl>(unsigned int) d_now.tv_sec) { - LOG(prefix<content<<"'"<content<<"'"< "< range; QType qtnull(0); @@ -711,9 +711,9 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vectornegcache.find(tie(getLastLabel(qname), qtnull))) != t_sstorage->negcache.end() && range.first->d_qname=="." && (uint32_t)d_now.tv_sec < range.first->d_ttd ) { sttl=range.first->d_ttd - d_now.tv_sec; - + LOG(prefix<d_name.toString()<<"' & '"<d_qname.toString()<<"' for another "<d_qname; sqt=QType::SOA; moveCacheItemToBack(t_sstorage->negcache, range.first); @@ -735,7 +735,7 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vectord_qname.toString()<<"' for another "<d_qname; @@ -795,12 +795,12 @@ bool SyncRes::moreSpecificThan(const DNSName& a, const DNSName &b) struct speedOrder { - speedOrder(map &speeds) : d_speeds(speeds) {} - bool operator()(const string &a, const string &b) const + speedOrder(map &speeds) : d_speeds(speeds) {} + bool operator()(const DNSName &a, const DNSName &b) const { return d_speeds[a] < d_speeds[b]; } - map& d_speeds; + map& d_speeds; }; inline vector SyncRes::shuffleInSpeedOrder(set &tnameservers, const string &prefix) @@ -823,14 +823,14 @@ inline vector SyncRes::shuffleInSpeedOrder(set &tnameservers, if(doLog()) { LOG(prefix<<"Nameservers: "); - for(const auto & i: rnameservers) { - if(i!=rnameservers.begin()) { + for(vector::const_iterator i=rnameservers.begin();i!=rnameservers.end();++i) { + if(i!=rnameservers.begin()) { LOG(", "); if(!((i-rnameservers.begin())%3)) { LOG(endl<toString()<<"(" << (boost::format("%0.2f") % (speeds[*i]/1000.0)).str() <<"ms)"); } LOG(endl); } @@ -839,14 +839,9 @@ inline vector SyncRes::shuffleInSpeedOrder(set &tnameservers, struct TCacheComp { - bool operator()(const pair& a, const pair& b) const + bool operator()(const pair& a, const pair& b) const { - if(pdns_ilexicographical_compare(a.first, b.first)) - return true; - if(pdns_ilexicographical_compare(b.first, a.first)) - return false; - - return a.second < b.second; + return tie(a.first, a.second) < tie(b.first, b.second); } }; @@ -858,8 +853,8 @@ static bool magicAddrMatch(const QType& query, const QType& answer) } /** returns -1 in case of no results, rcode otherwise */ -int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, - vector&ret, +int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, + vector&ret, int depth, set&beenthere) { string prefix; @@ -867,13 +862,13 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe prefix=d_prefix; prefix.append(depth, ' '); } - + LOG(prefix< rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix+qname.toString()+": ") : string() ); - - for(const auto &tns: rnameservers) { + + for(vector::const_iterator tns=rnameservers.begin();;++tns) { if(tns==rnameservers.end()) { LOG(prefix< nameservers, DNSName auth, bool flawedNSSe return -1; } // this line needs to identify the 'self-resolving' behaviour, but we get it wrong now - if(pdns_iequals(qname, *tns) && qtype.getCode()==QType::A && rnameservers.size() > (unsigned)(1+1*s_doIPv6)) { + if(pdns_iequals(qname, *tns) && qtype.getCode()==QType::A && rnameservers.size() > (unsigned)(1+1*s_doIPv6)) { LOG(prefix< nameservers, DNSName auth, bool flawedNSSe lwr.d_aabit=true; } else { - LOG(prefix<toString()<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<toString(); if(!tns->empty()) { sendRDQuery = txtAddr[0] == '+'; txtAddr=txtAddr.c_str()+1; @@ -925,7 +920,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe } if(remoteIPs.empty()) { - LOG(prefix<toString()<<", trying next if available"< nameservers, DNSName auth, bool flawedNSSe LOG(prefix<toStringWithPort() < s_maxtotusec) + + if(s_maxtotusec && d_totUsec > s_maxtotusec) throw ImmediateServFailException("Too much time waiting for "+qname.toString()+"|"+qtype.getName()+", timeouts: "+boost::lexical_cast(d_timeouts) +", throttles: "+boost::lexical_cast(d_throttledqueries) + ", queries: "+lexical_cast(d_outqueries)+", "+lexical_cast(d_totUsec/1000)+"msec"); if(d_pdl && d_pdl->preoutquery(*remoteIP, d_requestor, qname, qtype, lwr.d_result, resolveret)) { @@ -1017,7 +1012,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe // if(d_timeouts + 0.5*d_throttledqueries > 6.0 && d_timeouts > 2) throw ImmediateServFailException("Too much work resolving "+qname+"|"+qtype.getName()+", timeouts: "+boost::lexical_cast(d_timeouts) +", throttles: "+boost::lexical_cast(d_throttledqueries)); if(lwr.d_rcode==RCode::ServFail || lwr.d_rcode==RCode::Refused) { - LOG(prefix<toString()<<" returned a "<< (lwr.d_rcode==RCode::ServFail ? "ServFail" : "Refused") << ", trying sibling IP or NS"<throttle.throttle(d_now.tv_sec,boost::make_tuple(*remoteIP, qname, qtype.getCode()),60,3); // servfail or refused continue; } @@ -1027,7 +1022,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe break; // this IP address worked! wasLame:; // well, it didn't - LOG(prefix<toString() <<") is lame for '"<toString()<<" ("<< remoteIP->toString() <<") is lame for '"<throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // lame } } @@ -1044,8 +1039,8 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe LOG(prefix<toString() <<"), rcode="<toString()<<" ("<< remoteIP->toString() <<"), rcode="<sin4.sin_family==AF_INET6) @@ -1076,7 +1071,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe LOG("NO! - we don't accept 'ANY' data"<qname.isPartOf(auth)) { if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && i->d_place==DNSResourceRecord::ANSWER && ::arg().contains("delegation-only",auth.toString() /* ugh */)) { LOG("NO! Is from delegation-only zone"< nameservers, DNSName auth, bool flawedNSSe t_RC->replace(d_now.tv_sec, i->first.first, i->first.second, i->second, lwr.d_aabit); } - set nsset; + set nsset; LOG(prefix< nameservers, DNSName auth, bool flawedNSSe if(i->d_place==DNSResourceRecord::AUTHORITY && i->qtype.getCode()==QType::SOA && lwr.d_rcode==RCode::NXDomain && dottedEndsOn(qname,i->qname) && dottedEndsOn(i->qname, auth)) { LOG(prefix<ttl = min(i->ttl, s_maxnegttl); if(!newtarget.length()) // only add a SOA if we're not going anywhere after this ret.push_back(*i); @@ -1159,7 +1154,7 @@ int SyncRes::doResolveAt(set nameservers, DNSName auth, bool flawedNSSe ) ) { - + LOG(prefix<content<<"|"<qtype.getName()<<"'"< nameservers, DNSName auth, bool flawedNSSe LOG(prefix<qname.toString()<<"' -> '"<content<<"'"<qname.toString()<<"' -> '"<content<<"', had '"<content); } else if(!done && i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA && lwr.d_rcode==RCode::NoError) { LOG(prefix< nameservers, DNSName auth, bool flawedNSSe } } - if(done){ + if(done){ LOG(prefix<second.ttd > e.ttd || (i->second.count) < e.count) + } + else if(i->second.ttd > e.ttd || (i->second.count) < e.count) d_cont[t]=e; } - + unsigned int size() { return (unsigned int)d_cont.size(); @@ -91,7 +91,7 @@ private: unsigned int d_limit; time_t d_ttl; time_t d_last_clean; - struct entry + struct entry { time_t ttd; unsigned int count; @@ -108,7 +108,7 @@ private: class DecayingEwma { public: - DecayingEwma() : d_val(0.0) + DecayingEwma() : d_val(0.0) { d_needinit=true; d_last.tv_sec = d_last.tv_usec = 0; @@ -145,7 +145,7 @@ public: d_last=now; double factor=exp(diff)/2.0; // might be '0.5', or 0.0001 - d_val=(float)((1-factor)*val+ (float)factor*d_val); + d_val=(float)((1-factor)*val+ (float)factor*d_val); } } @@ -235,7 +235,7 @@ private: class SyncRes : public boost::noncopyable { public: - enum LogMode { LogNone, Log, Store}; + enum LogMode { LogNone, Log, Store}; explicit SyncRes(const struct timeval& now); @@ -249,15 +249,15 @@ public: { s_lm = lm; } - - void setLogMode(LogMode lm) + + void setLogMode(LogMode lm) { d_lm = lm; } bool doLog() { - return d_lm != LogNone; + return d_lm != LogNone; } void setCacheOnly(bool state=true) @@ -286,7 +286,7 @@ public: int asyncresolveWrapper(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res); - + static void doEDNSDumpAndClose(int fd); static uint64_t s_queries; @@ -320,16 +320,16 @@ public: >, composite_key_compare, std::less > >, - sequenced<> + sequenced<> > > negcache_t; - - //! This represents a number of decaying Ewmas, used to store performance per nameserver-name. + + //! This represents a number of decaying Ewmas, used to store performance per nameserver-name. /** Modelled to work mostly like the underlying DecayingEwma. After you've called get, d_best is filled out with the best address for this collection */ struct DecayingEwmaCollection { - void submit(const ComboAddress& remote, int usecs, struct timeval* now) + void submit(const ComboAddress& remote, int usecs, struct timeval* now) { collection_t::iterator pos; for(pos=d_collection.begin(); pos != d_collection.end(); ++pos) @@ -357,13 +357,13 @@ public: d_best=pos->first; } } - + return ret; } - + bool stale(time_t limit) const { - for(collection_t::const_iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos) + for(collection_t::const_iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos) if(!pos->second.stale(limit)) return false; return true; @@ -374,7 +374,7 @@ public: ComboAddress d_best; }; - typedef map nsspeeds_t; + typedef map nsspeeds_t; struct EDNSStatus { @@ -395,8 +395,8 @@ public: bool d_rdForward; typedef multi_index_container < DNSResourceRecord, - indexed_by < - ordered_non_unique< + indexed_by < + ordered_non_unique< composite_key< DNSResourceRecord, member, member @@ -405,17 +405,17 @@ public: > > > records_t; - records_t d_records; + records_t d_records; }; - + typedef map domainmap_t; - + typedef Throttle > throttle_t; typedef Counters fails_t; - + struct timeval d_now; static unsigned int s_maxnegttl; static unsigned int s_maxcachettl; @@ -425,10 +425,10 @@ public: static unsigned int s_serverdownthrottletime; static bool s_nopacketcache; static string s_serverID; - - + + struct StaticStorage { - negcache_t negcache; + negcache_t negcache; nsspeeds_t nsSpeeds; ednsstatus_t ednsstatus; throttle_t throttle; @@ -468,7 +468,7 @@ private: uint8_t qtype; // only A and AAAA anyhow bool operator<(const GetBestNSAnswer &b) const { - return boost::tie(qname, qtype, bestns) < + return boost::tie(qname, qtype, bestns) < boost::tie(b.qname, b.qtype, b.bestns); } }; @@ -491,7 +491,7 @@ struct PacketID uint16_t id; // wait for a specific id/remote pair ComboAddress remote; // this is the remote - DNSName domain; // this is the question + DNSName domain; // this is the question uint16_t type; // and this is its type Socket* sock; // or wait for an event on a TCP fd @@ -520,7 +520,7 @@ struct PacketID } }; -struct PacketIDBirthdayCompare: public std::binary_function +struct PacketIDBirthdayCompare: public std::binary_function { bool operator()(const PacketID& a, const PacketID& b) const { @@ -579,7 +579,7 @@ class TCPConnection : public boost::noncopyable public: TCPConnection(int fd, const ComboAddress& addr); ~TCPConnection(); - + int getFD() { return d_fd; diff --git a/pdns/ws-recursor.cc b/pdns/ws-recursor.cc index 8f582bfe92..0baa019aab 100644 --- a/pdns/ws-recursor.cc +++ b/pdns/ws-recursor.cc @@ -149,7 +149,7 @@ static void fillZone(const string& zonename, HttpResponse* resp) string url = "/servers/localhost/zones/" + zoneId; Value jurl(url.c_str(), doc.GetAllocator()); // copy doc.AddMember("url", jurl, doc.GetAllocator()); - doc.AddMember("name", iter->first.c_str(), doc.GetAllocator()); + doc.AddMember("name", iter->first.toString().c_str(), doc.GetAllocator()); doc.AddMember("kind", zone.d_servers.empty() ? "Native" : "Forwarded", doc.GetAllocator()); Value servers; servers.SetArray(); @@ -166,7 +166,7 @@ static void fillZone(const string& zonename, HttpResponse* resp) BOOST_FOREACH(const SyncRes::AuthDomain::records_t::value_type& rr, zone.d_records) { Value object; object.SetObject(); - Value jname(rr.qname.c_str(), doc.GetAllocator()); // copy + Value jname(rr.qname.toString().c_str(), doc.GetAllocator()); // copy object.AddMember("name", jname, doc.GetAllocator()); Value jtype(rr.qtype.getName().c_str(), doc.GetAllocator()); // copy object.AddMember("type", jtype, doc.GetAllocator()); @@ -311,13 +311,13 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) Value jdi; jdi.SetObject(); // id is the canonical lookup key, which doesn't actually match the name (in some cases) - string zoneId = apiZoneNameToId(val.first); + string zoneId = apiZoneNameToId(val.first.toString()); Value jzoneid(zoneId.c_str(), doc.GetAllocator()); // copy jdi.AddMember("id", jzoneid, doc.GetAllocator()); string url = "/servers/localhost/zones/" + zoneId; Value jurl(url.c_str(), doc.GetAllocator()); // copy jdi.AddMember("url", jurl, doc.GetAllocator()); - jdi.AddMember("name", val.first.c_str(), doc.GetAllocator()); + jdi.AddMember("name", val.first.toString().c_str(), doc.GetAllocator()); jdi.AddMember("kind", zone.d_servers.empty() ? "Native" : "Forwarded", doc.GetAllocator()); Value servers; servers.SetArray(); @@ -379,14 +379,14 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { doc.SetArray(); BOOST_FOREACH(const SyncRes::domainmap_t::value_type& val, *t_sstorage->domainmap) { - string zoneId = apiZoneNameToId(val.first); - if (pdns_ci_find(val.first, q) != string::npos) { + string zoneId = apiZoneNameToId(val.first.toString()); + if (pdns_ci_find(val.first.toString(), q) != string::npos) { Value object; object.SetObject(); object.AddMember("type", "zone", doc.GetAllocator()); Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy object.AddMember("zone_id", jzoneId, doc.GetAllocator()); - Value jzoneName(val.first.c_str(), doc.GetAllocator()); // copy + Value jzoneName(val.first.toString().c_str(), doc.GetAllocator()); // copy object.AddMember("name", jzoneName, doc.GetAllocator()); doc.PushBack(object, doc.GetAllocator()); } @@ -399,7 +399,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { const SyncRes::AuthDomain& zone = val.second; BOOST_FOREACH(const SyncRes::AuthDomain::records_t::value_type& rr, zone.d_records) { - if (pdns_ci_find(rr.qname, q) == string::npos && pdns_ci_find(rr.content, q) == string::npos) + if (pdns_ci_find(rr.qname.toString(), q) == string::npos && pdns_ci_find(rr.content, q) == string::npos) continue; Value object; @@ -407,9 +407,9 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { object.AddMember("type", "record", doc.GetAllocator()); Value jzoneId(zoneId.c_str(), doc.GetAllocator()); // copy object.AddMember("zone_id", jzoneId, doc.GetAllocator()); - Value jzoneName(val.first.c_str(), doc.GetAllocator()); // copy + Value jzoneName(val.first.toString().c_str(), doc.GetAllocator()); // copy object.AddMember("zone_name", jzoneName, doc.GetAllocator()); - Value jname(rr.qname.c_str(), doc.GetAllocator()); // copy + Value jname(rr.qname.toString().c_str(), doc.GetAllocator()); // copy object.AddMember("name", jname, doc.GetAllocator()); Value jcontent(rr.content.c_str(), doc.GetAllocator()); // copy object.AddMember("content", jcontent, doc.GetAllocator()); @@ -424,7 +424,7 @@ static void apiServerFlushCache(HttpRequest* req, HttpResponse* resp) { if(req->method != "PUT") throw HttpMethodNotAllowedException(); - string canon = toCanonic("", req->getvars["domain"]); + DNSName canon = req->getvars["domain"]; int count = broadcastAccFunction(boost::bind(pleaseWipeCache, canon)); count += broadcastAccFunction(boost::bind(pleaseWipeAndCountNegCache, canon)); map object; @@ -465,31 +465,31 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) req->getvars.erase("command"); } - map stats; + map stats; if(command == "get-query-ring") { - typedef pair query_t; + typedef pair query_t; vector queries; bool filter=!req->getvars["public-filtered"].empty(); - + if(req->getvars["name"]=="servfail-queries") queries=broadcastAccFunction >(pleaseGetServfailQueryRing); else if(req->getvars["name"]=="queries") queries=broadcastAccFunction >(pleaseGetQueryRing); - + typedef map counts_t; counts_t counts; unsigned int total=0; BOOST_FOREACH(const query_t& q, queries) { total++; if(filter) - counts[make_pair(getRegisteredName(toLower(q.first)), q.second)]++; - else - counts[make_pair(toLower(q.first), q.second)]++; + counts[make_pair(getRegisteredName(q.first), q.second)]++; + else + counts[make_pair(q.first, q.second)]++; } - + typedef std::multimap rcounts_t; rcounts_t rcounts; - + for(counts_t::const_iterator i=counts.begin(); i != counts.end(); ++i) rcounts.insert(make_pair(-i->second, i->first)); @@ -500,11 +500,11 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) unsigned int tot=0, totIncluded=0; BOOST_FOREACH(const rcounts_t::value_type& q, rcounts) { Value arr; - + arr.SetArray(); totIncluded-=q.first; arr.PushBack(-q.first, doc.GetAllocator()); - arr.PushBack(q.second.first.c_str(), doc.GetAllocator()); + arr.PushBack(q.second.first.toString().c_str(), doc.GetAllocator()); arr.PushBack(DNSRecordContent::NumberToType(q.second.second).c_str(), doc.GetAllocator()); entries.PushBack(arr, doc.GetAllocator()); if(tot++>=100) @@ -518,7 +518,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) arr.PushBack("", doc.GetAllocator()); entries.PushBack(arr, doc.GetAllocator()); } - doc.AddMember("entries", entries, doc.GetAllocator()); + doc.AddMember("entries", entries, doc.GetAllocator()); resp->setBody(doc); return; } @@ -530,7 +530,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) queries=broadcastAccFunction >(pleaseGetServfailRemotes); else if(req->getvars["name"]=="large-answer-remotes") queries=broadcastAccFunction >(pleaseGetLargeAnswerRemotes); - + typedef map counts_t; counts_t counts; unsigned int total=0; @@ -538,14 +538,14 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) total++; counts[q]++; } - + typedef std::multimap rcounts_t; rcounts_t rcounts; - + for(counts_t::const_iterator i=counts.begin(); i != counts.end(); ++i) rcounts.insert(make_pair(-i->second, i->first)); - + Document doc; doc.SetObject(); Value entries; @@ -554,10 +554,10 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) BOOST_FOREACH(const rcounts_t::value_type& q, rcounts) { totIncluded-=q.first; Value arr; - + arr.SetArray(); arr.PushBack(-q.first, doc.GetAllocator()); - Value jname(q.second.toString().c_str(), doc.GetAllocator()); // copy + Value jname(q.second.toString().c_str(), doc.GetAllocator()); // copy arr.PushBack(jname, doc.GetAllocator()); entries.PushBack(arr, doc.GetAllocator()); if(tot++>=100) @@ -571,7 +571,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse *resp) entries.PushBack(arr, doc.GetAllocator()); } - doc.AddMember("entries", entries, doc.GetAllocator()); + doc.AddMember("entries", entries, doc.GetAllocator()); resp->setBody(doc); return; } else { @@ -611,7 +611,7 @@ void AsyncWebServer::serveConnection(Socket *client) YaHTTP::AsyncRequestLoader yarl; yarl.initialize(&req); client->setNonBlocking(); - + string data; try { while(!req.complete) {