// empty
}
-bool RecursorLua::nxdomain(const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
+bool RecursorLua::nxdomain(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
{
return false;
}
-bool RecursorLua::nodata(const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
+bool RecursorLua::nodata(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
{
return false;
}
-bool RecursorLua::postresolve(const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
+bool RecursorLua::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
{
return false;
}
-bool RecursorLua::preresolve(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
+bool RecursorLua::preresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable)
{
return false;
}
-bool RecursorLua::preoutquery(const ComboAddress& remote, const ComboAddress& local,const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+bool RecursorLua::preoutquery(const ComboAddress& remote, const ComboAddress& local,const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
{
return false;
}
public:
explicit RecursorLua(const std::string& fname);
// ~RecursorLua();
- bool preresolve(const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
- bool nxdomain(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
- bool nodata(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
- bool postresolve(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
- bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret);
+ bool preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
+ bool nxdomain(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
+ bool nodata(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
+ bool postresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
+ bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret);
bool ipfilter(const ComboAddress& remote, const ComboAddress& local);
private:
- bool passthrough(const string& func, const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable);
+ bool passthrough(const string& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable);
struct NoFuncs
{
/** lwr is only filled out in case 1 was returned, and even when returning 1 for 'success', lwr might contain DNS errors
Never throws!
*/
-int asyncresolve(const ComboAddress& ip, const string& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, LWResult *lwr)
+int asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, LWResult *lwr)
{
int len;
int bufsize=1500;
}
if(!pdns_iequals(domain, mdp.d_qname)) {
- if(!mdp.d_qname.empty() && domain.find((char)0) == string::npos) {// embedded nulls are too noisy, plus empty domains are too
+ if(!mdp.d_qname.empty() && domain.toString().find((char)0) == string::npos /* ugly */) {// embedded nulls are too noisy, plus empty domains are too
L<<Logger::Notice<<"Packet purporting to come from remote server "<<ip.toString()<<" contained wrong answer: '" << domain << "' != '" << mdp.d_qname << "'" << endl;
}
// unexpected count has already been done @ pdns_recursor.cc
#include "namespaces.hh"
int asendto(const char *data, int len, int flags, const ComboAddress& ip, uint16_t id,
- const string& domain, uint16_t qtype, int* fd);
+ const DNSName& domain, uint16_t qtype, int* fd);
int arecvfrom(char *data, int len, int flags, const ComboAddress& ip, int *d_len, uint16_t id,
- const string& domain, uint16_t, int fd, struct timeval* now);
+ const DNSName& domain, uint16_t, int fd, struct timeval* now);
class LWResException : public PDNSException
{
bool d_haveEDNS;
};
-int asyncresolve(const ComboAddress& ip, const string& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, LWResult* res);
+int asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, LWResult* res);
#endif // PDNS_LWRES_HH
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 chopOffDotted(string &domain);
bool endsOn(const string &domain, const string &suffix);
+bool dottedEndsOn(const DNSName &domain, const DNSName &suffix); // REMOVE ME
bool dottedEndsOn(const string &domain, const string &suffix);
string nowTime();
const string unquotify(const string &item);
return true;
}
-// FIXME remove this
+// FIXME remove this, it's just here to move faster while we DNSName the things
inline bool pdns_iequals(const DNSName& a, const DNSName& b) __attribute__((pure));
inline bool pdns_iequals(const DNSName& a, const DNSName& b)
{
#endif
};
-
+// FIXME this should probably go?
struct CIStringCompare: public std::binary_function<string, string, bool>
{
bool operator()(const string& a, const string& b) const
return dom[dom.size()-1]=='.';
}
+// get rid of this?
inline string toCanonic(const DNSName& zone, const string& domain)
{
return toCanonic(zone.toString(), domain);
}
+// and this?
inline string toCanonic(const string& zone, const string& domain)
{
if(domain.length()==1 && domain[0]=='@')
{
CacheEntry() { qtype = ctype = 0; zoneID = -1; meritsRecursion=false; dnssecOk=false; hasEDNS=false;}
- string qname;
+ DNSName qname;
uint16_t qtype;
uint16_t ctype;
int zoneID;
#include "version.hh"
#include "responsestats.hh"
#include "secpoll-recursor.hh"
+#include "dnsname.hh"
#ifndef RECURSOR
#include "statbag.hh"
StatBag S;
__thread addrringbuf_t* t_remotes, *t_servfailremotes, *t_largeanswerremotes;
-__thread boost::circular_buffer<pair<std::string, uint16_t> >* t_queryring, *t_servfailqueryring;
+__thread boost::circular_buffer<pair<DNSName, uint16_t> >* t_queryring, *t_servfailqueryring;
__thread shared_ptr<Regex>* t_traceRegex;
RecursorControlChannel s_rcc; // only active in thread 0
/* 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 string& domain, uint16_t qtype, int* fd)
+ const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, int* fd)
{
PacketID pident;
// -1 is error, 0 is timeout, 1 is success
int arecvfrom(char *data, int len, int flags, const ComboAddress& fromaddr, int *d_len,
- uint16_t id, const string& domain, uint16_t qtype, int fd, struct timeval* now)
+ uint16_t id, const DNSName& domain, uint16_t qtype, int fd, struct timeval* now)
{
static optional<unsigned int> nearMissLimit;
if(!nearMissLimit)
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.
-void updateResponseStats(int res, const ComboAddress& remote, unsigned int packetsize, const std::string* query, uint16_t qtype)
+void updateResponseStats(int res, const ComboAddress& remote, unsigned int packetsize, const DNSName* query, uint16_t qtype)
{
if(packetsize > 1000 && t_largeanswerremotes)
t_largeanswerremotes->push_back(remote);
static string makeLoginfo(DNSComboWriter* dc)
try
{
- return "("+dc->d_mdp.d_qname+"/"+DNSRecordContent::NumberToType(dc->d_mdp.d_qtype)+" from "+(dc->d_remote.toString())+")";
+ return "("+dc->d_mdp.d_qname.toString()+"/"+DNSRecordContent::NumberToType(dc->d_mdp.d_qtype)+" from "+(dc->d_remote.toString())+")";
}
catch(...)
{
goto sendit;
}
- if(t_traceRegex->get() && (*t_traceRegex)->match(dc->d_mdp.d_qname)) {
+ if(t_traceRegex->get() && (*t_traceRegex)->match(dc->d_mdp.d_qname.toString())) {
sr.setLogMode(SyncRes::Store);
tracedQuery=true;
}
t_largeanswerremotes = new addrringbuf_t();
t_largeanswerremotes->set_capacity(ringsize);
- t_queryring = new boost::circular_buffer<pair<string, uint16_t> >();
+ t_queryring = new boost::circular_buffer<pair<DNSName, uint16_t> >();
t_queryring->set_capacity(ringsize);
- t_servfailqueryring = new boost::circular_buffer<pair<string, uint16_t> >();
+ t_servfailqueryring = new boost::circular_buffer<pair<DNSName, uint16_t> >();
t_servfailqueryring->set_capacity(ringsize);
}
#include <sys/un.h>
#include <pthread.h>
#include "iputils.hh"
+#include "dnsname.hh"
/** this class is used both to send and answer channel commands to the PowerDNS Recursor */
class RecursorControlChannel
std::map<std::string, std::string> getAllStatsMap();
extern pthread_mutex_t g_carbon_config_lock;
void sortPublicSuffixList();
-std::vector<std::pair<std::string, uint16_t> >* pleaseGetQueryRing();
-std::vector<std::pair<std::string, uint16_t> >* pleaseGetServfailQueryRing();
+std::vector<std::pair<DNSName, uint16_t> >* pleaseGetQueryRing();
+std::vector<std::pair<DNSName, uint16_t> >* pleaseGetServfailQueryRing();
std::vector<ComboAddress>* pleaseGetRemotes();
std::vector<ComboAddress>* pleaseGetServfailRemotes();
std::vector<ComboAddress>* pleaseGetLargeAnswerRemotes();
-std::string getRegisteredName(const std::string& dom);
+DNSName getRegisteredName(const DNSName& dom);
#endif
BOOST_FOREACH(const NegCacheEntry& neg, sidx)
{
++count;
- fprintf(fp, "%s IN %s %d VIA %s\n", neg.d_name.c_str(), neg.d_qtype.getName().c_str(), (unsigned int) (neg.d_ttd - now), neg.d_qname.c_str());
+ fprintf(fp, "%s IN %s %d VIA %s\n", neg.d_name.toString().c_str(), neg.d_qtype.getName().c_str(), (unsigned int) (neg.d_ttd - now), neg.d_qname.toString().c_str());
}
fclose(fp);
return count;
return "done\n";
}
-uint64_t* pleaseWipeCache(const std::string& canon)
+uint64_t* pleaseWipeCache(const DNSName& canon)
{
// clear packet cache too
return new uint64_t(t_RC->doWipeCache(canon) + t_packetCache->doWipePacketCache(canon));
}
-uint64_t* pleaseWipeAndCountNegCache(const std::string& canon)
+uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon)
{
uint64_t res = t_sstorage->negcache.count(tie(canon));
pair<SyncRes::negcache_t::iterator, SyncRes::negcache_t::iterator> range=t_sstorage->negcache.equal_range(tie(canon));
{
int count=0, countNeg=0;
for(T i=begin; i != end; ++i) {
- string canon=toCanonic("", *i);
+ DNSName canon=DNSName(*i);
count+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, canon));
countNeg+=broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, canon));
}
for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end() && n < 100; ++mthread, ++n) {
const PacketID& pident = mthread->key;
ostr << (fmt
- % pident.domain % DNSRecordContent::NumberToType(pident.type)
+ % pident.domain.toString() /* ?? */ % DNSRecordContent::NumberToType(pident.type)
% pident.remote.toString() % (pident.sock ? 'Y' : 'n')
% (pident.fd == -1 ? 'Y' : 'n')
);
doExitGeneric(true);
}
-vector<pair<string, uint16_t> >* pleaseGetQueryRing()
+vector<pair<DNSName, uint16_t> >* pleaseGetQueryRing()
{
- typedef pair<string,uint16_t> query_t;
+ typedef pair<DNSName,uint16_t> query_t;
vector<query_t >* ret = new vector<query_t>();
if(!t_queryring)
return ret;
}
return ret;
}
-vector<pair<string,uint16_t> >* pleaseGetServfailQueryRing()
+vector<pair<DNSName,uint16_t> >* pleaseGetServfailQueryRing()
{
- typedef pair<string,uint16_t> query_t;
+ typedef pair<DNSName,uint16_t> query_t;
vector<query_t>* ret = new vector<query_t>();
if(!t_servfailqueryring)
return ret;
typedef boost::function<vector<ComboAddress>*()> pleaseremotefunc_t;
-typedef boost::function<vector<pair<string,uint16_t> >*()> pleasequeryfunc_t;
+typedef boost::function<vector<pair<DNSName,uint16_t> >*()> pleasequeryfunc_t;
vector<ComboAddress>* pleaseGetRemotes()
{
sort(g_pubs.begin(), g_pubs.end());
}
-string getRegisteredName(const std::string& dom)
+DNSName getRegisteredName(const DNSName& dom)
{
- vector<string> parts;
- stringtok(parts, dom, ".");
+ auto parts=dom.getRawLabels();
if(parts.size()<=2)
return dom;
reverse(parts.begin(), parts.end());
return "??";
}
-static string nopFilter(const std::string& str)
+static DNSName nopFilter(const DNSName& name)
{
- return str;
+ return name;
}
-string doGenericTopQueries(pleasequeryfunc_t func, boost::function<string(const std::string&)> filter=nopFilter)
+string doGenericTopQueries(pleasequeryfunc_t func, boost::function<DNSName(const DNSName&)> filter=nopFilter)
{
- typedef pair<string,uint16_t> query_t;
+ typedef pair<DNSName,uint16_t> query_t;
typedef map<query_t, int> counts_t;
counts_t counts;
vector<query_t> queries=broadcastAccFunction<vector<query_t> >(func);
unsigned int total=0;
BOOST_FOREACH(const query_t& q, queries) {
total++;
- counts[make_pair(toLower(filter(q.first)),q.second)]++;
+ counts[make_pair(filter(q.first),q.second)]++;
}
typedef std::multimap<int, query_t> rcounts_t;
int limit=0, accounted=0;
if(total) {
for(rcounts_t::const_iterator i=rcounts.begin(); i != rcounts.end() && limit < 20; ++i, ++limit) {
- ret<< fmt % (-100.0*i->first/total) % (i->second.first+"|"+DNSRecordContent::NumberToType(i->second.second));
+ ret<< fmt % (-100.0*i->first/total) % (i->second.first.toString()+"|"+DNSRecordContent::NumberToType(i->second.second));
accounted+= -i->first;
}
ret<< '\n' << fmt % (100.0*(total-accounted)/total) % "rest";
d_hits = d_misses = 0;
}
-int RecursorPacketCache::doWipePacketCache(const string& name, uint16_t qtype)
+int RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype)
{
vector<uint8_t> packet;
- DNSPacketWriter pw(packet, toLower(name), 0);
+ DNSPacketWriter pw(packet, name, 0);
pw.getHeader()->rd=1;
Entry e;
e.d_packet.assign((const char*)&*packet.begin(), packet.size());
bool getResponsePacket(const std::string& queryPacket, time_t now, std::string* responsePacket, uint32_t* age);
void insertResponsePacket(const std::string& responsePacket, time_t now, uint32_t ttd);
void doPruneTo(unsigned int maxSize=250000);
- int doWipePacketCache(const string& name, uint16_t qtype=0xffff);
+ int doWipePacketCache(const DNSName& name, uint16_t qtype=0xffff);
void prune();
uint64_t d_hits, d_misses;
rr.content=regen->getZoneRepresentation();
}
rr.content.reserve(0);
- rr.qname.reserve(0);
+ // rr.qname.reserve(0);
return rr;
}
return string((char*)&ca.sin6.sin6_addr.s6_addr, 16);
}
else if(type==QType::NS || type==QType::CNAME)
- return simpleCompress(rr.content, rr.qname);
+ return simpleCompress(rr.content, rr.qname.toString());
else {
string ret;
shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(type, 1, rr.content));
for(cache_t::const_iterator i=d_cache.begin(); i!=d_cache.end(); ++i) {
ret+=sizeof(struct CacheEntry);
- ret+=(unsigned int)i->d_qname.length();
+ ret+=(unsigned int)i->d_qname.toString().length();
for(vector<StoredRecord>::const_iterator j=i->d_records.begin(); j!= i->d_records.end(); ++j)
ret+=j->size();
}
return ret;
}
-int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res)
+int MemRecursorCache::get(time_t now, const DNSName &qname, const QType& qt, set<DNSResourceRecord>* res)
{
unsigned int ttd=0;
// cerr<<"looking up "<< qname+"|"+qt.getName()<<"\n";
/* the code below is rather tricky - it basically replaces the stuff cached for qname by content, but it is special
cased for when inserting identical records with only differing ttls, in which case the entry is not
touched, but only given a new ttd */
-void MemRecursorCache::replace(time_t now, const string &qname, const QType& qt, const set<DNSResourceRecord>& content, bool auth)
+void MemRecursorCache::replace(time_t now, const DNSName &qname, const QType& qt, const set<DNSResourceRecord>& content, bool auth)
{
d_cachecachevalid=false;
- boost::tuple<string, uint16_t> key=boost::make_tuple(qname, qt.getCode());
+ boost::tuple<DNSName, uint16_t> key=boost::make_tuple(qname, qt.getCode());
cache_t::iterator stored=d_cache.find(key);
uint32_t maxTTD=UINT_MAX;
}
// limit TTL of auth->auth NSset update if needed, except for root
- if(ce.d_auth && auth && qt.getCode()==QType::NS && !((qname.length()==1 && qname[0]=='.'))) {
+ if(ce.d_auth && auth && qt.getCode()==QType::NS && !(qname == DNSName("."))) {
// cerr<<"\tLimiting TTL of auth->auth NS set replace"<<endl;
vector<StoredRecord>::iterator j;
for(j = ce.d_records.begin() ; j != ce.d_records.end(); ++j) {
}
// make sure that we CAN refresh the root
- if(auth && ((qname.length()==1 && qname[0]=='.') || !attemptToRefreshNSTTL(qt, content, ce) ) ) {
+ if(auth && ((qname == DNSName(".")) || !attemptToRefreshNSTTL(qt, content, ce) ) ) {
// cerr<<"\tGot auth data, and it was not refresh attempt of an unchanged NS set, nuking storage"<<endl;
ce.d_records.clear(); // clear non-auth data
ce.d_auth = true;
d_cache.replace(stored, ce);
}
-int MemRecursorCache::doWipeCache(const string& name, uint16_t qtype)
+int MemRecursorCache::doWipeCache(const DNSName& name, uint16_t qtype)
{
int count=0;
d_cachecachevalid=false;
for(SyncRes::nsspeeds_t::iterator i = t_sstorage->nsSpeeds.begin() ; i!= t_sstorage->nsSpeeds.end(); ++i)
{
count++;
- fprintf(fp, "%s -> ", i->first.c_str());
+ fprintf(fp, "%s -> ", i->first.toString().c_str());
for(SyncRes::DecayingEwmaCollection::collection_t::iterator j = i->second.d_collection.begin(); j!= i->second.d_collection.end(); ++j)
{
// typedef vector<pair<ComboAddress, DecayingEwma> > collection_t;
count++;
try {
DNSResourceRecord rr=String2DNSRR(i->d_qname, QType(i->d_qtype), j->d_string, j->d_ttd - now);
- fprintf(fp, "%s %d IN %s %s\n", rr.qname.c_str(), rr.ttl, rr.qtype.getName().c_str(), rr.content.c_str());
+ fprintf(fp, "%s %d IN %s %s\n", rr.qname.toString().c_str(), rr.ttl, rr.qtype.getName().c_str(), rr.content.c_str());
}
catch(...) {
- fprintf(fp, "; error printing '%s'\n", i->d_qname.c_str());
+ fprintf(fp, "; error printing '%s'\n", i->d_qname.toString().c_str());
}
}
}
#include "dns.hh"
#include "qtype.hh"
#include "misc.hh"
+#include "dnsname.hh"
#include <iostream>
#include <boost/utility.hpp>
}
unsigned int size();
unsigned int bytes();
- int get(time_t, const string &qname, const QType& qt, set<DNSResourceRecord>* res);
+ int get(time_t, const DNSName &qname, const QType& qt, set<DNSResourceRecord>* res);
int getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]);
- void replace(time_t, const string &qname, const QType& qt, const set<DNSResourceRecord>& content, bool auth);
+ void replace(time_t, const DNSName &qname, const QType& qt, const set<DNSResourceRecord>& content, bool auth);
void doPrune(void);
void doSlash(int perc);
uint64_t doDump(int fd);
uint64_t doDumpNSSpeeds(int fd);
- int doWipeCache(const string& name, uint16_t qtype=0xffff);
+ int doWipeCache(const DNSName& name, uint16_t qtype=0xffff);
bool doAgeCache(time_t now, const string& name, uint16_t qtype, int32_t newTTL);
uint64_t cacheHits, cacheMisses;
struct CacheEntry
{
- CacheEntry(const boost::tuple<string, uint16_t>& key, const vector<StoredRecord>& records, bool auth) :
+ CacheEntry(const boost::tuple<DNSName, uint16_t>& key, const vector<StoredRecord>& records, bool auth) :
d_qname(key.get<0>()), d_qtype(key.get<1>()), d_auth(auth), d_records(records)
{}
return earliest;
}
- string d_qname;
+ DNSName d_qname;
uint16_t d_qtype;
bool d_auth;
records_t d_records;
ordered_unique<
composite_key<
CacheEntry,
- member<CacheEntry,string,&CacheEntry::d_qname>,
+ member<CacheEntry,DNSName,&CacheEntry::d_qname>,
member<CacheEntry,uint16_t,&CacheEntry::d_qtype>
>,
- composite_key_compare<CIStringCompare, std::less<uint16_t> >
+ composite_key_compare<std::less<DNSName>, std::less<uint16_t> >
>,
sequenced<>
>
cache_t d_cache;
pair<cache_t::iterator, cache_t::iterator> d_cachecache;
- string d_cachedqname;
+ DNSName d_cachedqname;
bool d_cachecachevalid;
bool attemptToRefreshNSTTL(const QType& qt, const set<DNSResourceRecord>& content, const CacheEntry& stored);
};
string DNSRR2String(const DNSResourceRecord& rr);
-DNSResourceRecord String2DNSRR(const string& qname, const QType& qt, const string& serial, uint32_t ttd);
+DNSResourceRecord String2DNSRR(const DNSName& qname, const QType& qt, const string& serial, uint32_t ttd);
#endif
t_RC->replace(time(0),".", QType(QType::NS), nsset, true); // and stuff in the cache (auth)
}
-static void makeNameToIPZone(SyncRes::domainmap_t* newMap, const string& hostname, const string& ip)
+static void makeNameToIPZone(SyncRes::domainmap_t* newMap, const DNSName& hostname, const string& ip)
{
SyncRes::AuthDomain ad;
ad.d_rdForward=false;
DNSResourceRecord rr;
- rr.qname=toCanonic("", hostname);
+ rr.qname=hostname;
rr.d_place=DNSResourceRecord::ANSWER;
rr.ttl=86400;
rr.qtype=QType::SOA;
DNSResourceRecord rr;
for(int n=ipparts.size()-1; n>=0 ; --n) {
- rr.qname.append(ipparts[n]);
- rr.qname.append(1,'.');
+ rr.qname.appendRawLabel(ipparts[n]);
}
- rr.qname.append("in-addr.arpa.");
+ rr.qname.appendRawLabel("in-addr");
+ rr.qname.appendRawLabel("arpa");
rr.d_place=DNSResourceRecord::ANSWER;
rr.ttl=86400;
if(ipparts.size()==4) // otherwise this is a partial zone
for(unsigned int n=1; n < parts.size(); ++n) {
- rr.content=toCanonic("", parts[n]);
+ rr.content=DNSName(parts[n]).toString();
ad.d_records.insert(rr);
}
pair<string,string> headers=splitField(*iter, '=');
trim(headers.first);
trim(headers.second);
- headers.first=toCanonic("", headers.first);
+ // headers.first=toCanonic("", headers.first);
if(n==0) {
ad.d_rdForward = false;
L<<Logger::Error<<"Parsing authoritative data for zone '"<<headers.first<<"' from file '"<<headers.second<<"'"<<endl;
- ZoneParserTNG zpt(headers.second, headers.first);
+ ZoneParserTNG zpt(headers.second, DNSName(headers.first));
DNSResourceRecord rr;
while(zpt.get(rr)) {
try {
}
catch(std::exception &e) {
delete newMap;
- throw PDNSException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what());
+ throw PDNSException("Error parsing record '"+rr.qname.toString()+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what());
}
catch(...) {
delete newMap;
- throw PDNSException("Error parsing record '"+rr.qname+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'");
+ throw PDNSException("Error parsing record '"+rr.qname.toString()+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'");
}
ad.d_records.insert(rr);
throw PDNSException("Conversion error parsing line "+lexical_cast<string>(linenum)+" of " +::arg()["forward-zones-file"]);
}
- (*newMap)[toCanonic("", domain)]=ad;
+ (*newMap)[domain]=ad;
}
L<<Logger::Warning<<"Done parsing " << newMap->size() - before<<" forwarding instructions from file '"<<::arg()["forward-zones-file"]<<"'"<<endl;
}
}
/** everything begins here - this is the entry point just after receiving a packet */
-int SyncRes::beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret)
+int SyncRes::beginResolve(const DNSName &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret)
{
s_queries++;
return -1;
if( (qtype.getCode()==QType::PTR && pdns_iequals(qname, "1.0.0.127.in-addr.arpa.")) ||
- (qtype.getCode()==QType::A && qname.length()==10 && pdns_iequals(qname, "localhost."))) {
+ (qtype.getCode()==QType::A && pdns_iequals(qname, "localhost."))) {
ret.clear();
DNSResourceRecord rr;
rr.qname=qname;
}
//! This is the 'out of band resolver', in other words, the authoritative server
-bool SyncRes::doOOBResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int& res)
+bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int& res)
{
string prefix;
if(doLog()) {
prefix.append(depth, ' ');
}
- LOG(prefix<<qname<<": checking auth storage for '"<<qname<<"|"<<qtype.getName()<<"'"<<endl);
- string authdomain(qname);
+ LOG(prefix<<qname.toString()<<": checking auth storage for '"<<qname.toString()<<"|"<<qtype.getName()<<"'"<<endl);
+ DNSName authdomain(qname);
domainmap_t::const_iterator iter=getBestAuthZone(&authdomain);
if(iter==t_sstorage->domainmap->end()) {
- LOG(prefix<<qname<<": auth storage has no zone for this query!"<<endl);
+ LOG(prefix<<qname.toString()<<": auth storage has no zone for this query!"<<endl);
return false;
}
- LOG(prefix<<qname<<": auth storage has data, zone='"<<authdomain<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": auth storage has data, zone='"<<authdomain.toString()<<"'"<<endl);
pair<AuthDomain::records_t::const_iterator, AuthDomain::records_t::const_iterator> range;
range=iter->second.d_records.equal_range(tie(qname)); // partial lookup
ret.push_back(*ziter);
}
if(!ret.empty()) {
- LOG(prefix<<qname<<": exact match in zone '"<<authdomain<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": exact match in zone '"<<authdomain.toString()<<"'"<<endl);
res=0;
return true;
}
if(somedata) {
- LOG(prefix<<qname<<": found record in '"<<authdomain<<"', but nothing of the right type, sending SOA"<<endl);
+ LOG(prefix<<qname.toString()<<": found record in '"<<authdomain.toString()<<"', but nothing of the right type, sending SOA"<<endl);
ziter=iter->second.d_records.find(boost::make_tuple(authdomain, QType(QType::SOA)));
if(ziter!=iter->second.d_records.end()) {
DNSResourceRecord rr=*ziter;
ret.push_back(rr);
}
else
- LOG(prefix<<qname<<": can't find SOA record '"<<authdomain<<"' in our zone!"<<endl);
+ LOG(prefix<<qname.toString()<<": can't find SOA record '"<<authdomain.toString()<<"' in our zone!"<<endl);
res=RCode::NoError;
return true;
}
- LOG(prefix<<qname<<": nothing found so far in '"<<authdomain<<"', trying wildcards"<<endl);
- string wcarddomain(qname);
- while(!pdns_iequals(wcarddomain, iter->first) && chopOffDotted(wcarddomain)) {
- LOG(prefix<<qname<<": trying '*."+wcarddomain+"' in "<<authdomain<<endl);
- range=iter->second.d_records.equal_range(boost::make_tuple("*."+wcarddomain));
+ LOG(prefix<<qname.toString()<<": nothing found so far in '"<<authdomain.toString()<<"', trying wildcards"<<endl);
+ DNSName wcarddomain(qname);
+ while(!pdns_iequals(wcarddomain, iter->first) && wcarddomain.chopOff()) {
+ LOG(prefix<<qname.toString()<<": trying '*."+wcarddomain.toString()+"' in "<<authdomain.toString()<<endl);
+ range=iter->second.d_records.equal_range(boost::make_tuple(DNSName("*")+wcarddomain));
if(range.first==range.second)
continue;
ret.push_back(rr);
}
}
- LOG(prefix<<qname<<": in '"<<authdomain<<"', had wildcard match on '*."+wcarddomain+"'"<<endl);
+ LOG(prefix<<qname.toString()<<": in '"<<authdomain.toString()<<"', had wildcard match on '*."+wcarddomain.toString()+"'"<<endl);
res=RCode::NoError;
return true;
}
- string nsdomain(qname);
+ DNSName nsdomain(qname);
- while(chopOffDotted(nsdomain) && !pdns_iequals(nsdomain, iter->first)) {
- range=iter->second.d_records.equal_range(boost::make_tuple(nsdomain,QType(QType::NS)));
+ while(nsdomain.chopOff() && !pdns_iequals(nsdomain, iter->first)) {
+ range=iter->second.d_records.equal_range(boost::make_tuple(nsdomain,QType(QType::NS)));
if(range.first==range.second)
continue;
ret.push_back(rr);
}
}
- if(ret.empty()) {
- LOG(prefix<<qname<<": no NS match in zone '"<<authdomain<<"' either, handing out SOA"<<endl);
+ if(ret.empty()) {
+ LOG(prefix<<qname.toString()<<": no NS match in zone '"<<authdomain.toString()<<"' either, handing out SOA"<<endl);
ziter=iter->second.d_records.find(boost::make_tuple(authdomain, QType(QType::SOA)));
if(ziter!=iter->second.d_records.end()) {
DNSResourceRecord rr=*ziter;
ret.push_back(rr);
}
else
- LOG(prefix<<qname<<": can't find SOA record '"<<authdomain<<"' in our zone!"<<endl);
+ LOG(prefix<<qname.toString()<<": can't find SOA record '"<<authdomain.toString()<<"' in our zone!"<<endl);
res=RCode::NXDomain;
}
else
fclose(fp);
}
-int SyncRes::asyncresolveWrapper(const ComboAddress& ip, const string& 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.
return ret;
}
-int SyncRes::doResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, set<GetBestNSAnswer>& beenthere)
+int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, set<GetBestNSAnswer>& beenthere)
{
string prefix;
if(doLog()) {
if(!(d_nocache && qtype.getCode()==QType::NS && qname==".")) {
if(d_cacheonly) { // very limited OOB support
LWResult lwr;
- LOG(prefix<<qname<<": Recursion not requested for '"<<qname<<"|"<<qtype.getName()<<"', peeking at auth/forward zones"<<endl);
- string authname(qname);
+ LOG(prefix<<qname.toString()<<": Recursion not requested for '"<<qname.toString()<<"|"<<qtype.getName()<<"', peeking at auth/forward zones"<<endl);
+ DNSName authname(qname);
domainmap_t::const_iterator iter=getBestAuthZone(&authname);
if(iter != t_sstorage->domainmap->end()) {
const vector<ComboAddress>& servers = iter->second.d_servers;
}
else {
const ComboAddress remoteIP = servers.front();
- LOG(prefix<<qname<<": forwarding query to hardcoded nameserver '"<< remoteIP.toStringWithPort()<<"' for zone '"<<authname<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": forwarding query to hardcoded nameserver '"<< remoteIP.toStringWithPort()<<"' for zone '"<<authname.toString()<<"'"<<endl);
res=asyncresolveWrapper(remoteIP, qname, qtype.getCode(), false, false, &d_now, &lwr);
// filter out the good stuff from lwr.result()
if(d_cacheonly)
return 0;
+
+ LOG(prefix<<qname.toString()<<": No cache hit for '"<<qname.toString()<<"|"<<qtype.getName()<<"', trying to find an appropriate NS record"<<endl);
- LOG(prefix<<qname<<": No cache hit for '"<<qname<<"|"<<qtype.getName()<<"', trying to find an appropriate NS record"<<endl);
+ DNSName subdomain(qname);
- string subdomain(qname);
-
- set<string, CIStringCompare> nsset;
+ set<DNSName> nsset;
bool flawedNSSet=false;
// the two retries allow getBestNSNamesFromCache&co to reprime the root
if(!(res=doResolveAt(nsset, subdomain, flawedNSSet, qname, qtype, ret, depth, beenthere)))
return 0;
-
- LOG(prefix<<qname<<": failed (res="<<res<<")"<<endl);
+
+ LOG(prefix<<qname.toString()<<": failed (res="<<res<<")"<<endl);
return res<0 ? RCode::ServFail : res;
}
/** This function explicitly goes out for A or AAAA addresses
*/
-vector<ComboAddress> SyncRes::getAddrs(const string &qname, int depth, set<GetBestNSAnswer>& beenthere)
+vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, int depth, set<GetBestNSAnswer>& beenthere)
{
typedef vector<DNSResourceRecord> res_t;
res_t res;
return ret;
}
-void SyncRes::getBestNSFromCache(const string &qname, const QType& qtype, set<DNSResourceRecord>&bestns, bool* flawedNSSet, int depth, set<GetBestNSAnswer>& beenthere)
+void SyncRes::getBestNSFromCache(const DNSName &qname, const QType& qtype, set<DNSResourceRecord>&bestns, bool* flawedNSSet, int depth, set<GetBestNSAnswer>& beenthere)
{
- string prefix, subdomain(qname);
+ string prefix;
+ DNSName subdomain(qname);
if(doLog()) {
prefix=d_prefix;
prefix.append(depth, ' ');
bool brokeloop;
do {
brokeloop=false;
- LOG(prefix<<qname<<": Checking if we have NS in cache for '"<<subdomain<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": Checking if we have NS in cache for '"<<subdomain.toString()<<"'"<<endl);
set<DNSResourceRecord> ns;
*flawedNSSet = false;
if(t_RC->get(d_now.tv_sec, subdomain, QType(QType::NS), &ns) > 0) {
DNSResourceRecord rr=*k;
rr.content=k->content;
- if(!dottedEndsOn(rr.content, subdomain) || t_RC->get(d_now.tv_sec, rr.content, s_doIPv6 ? QType(QType::ADDR) : QType(QType::A),
+ if(!DNSName(rr.content).isPartOf(subdomain) || t_RC->get(d_now.tv_sec, rr.content, s_doIPv6 ? QType(QType::ADDR) : QType(QType::A),
doLog() ? &aset : 0) > 5) {
bestns.insert(rr);
- LOG(prefix<<qname<<": NS (with ip, or non-glue) in cache for '"<<subdomain<<"' -> '"<<rr.content<<"'"<<endl);
- LOG(prefix<<qname<<": within bailiwick: "<<dottedEndsOn(rr.content, subdomain));
+ LOG(prefix<<qname.toString()<<": NS (with ip, or non-glue) in cache for '"<<subdomain.toString()<<"' -> '"<<rr.content<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": within bailiwick: "<<DNSName(rr.content).isPartOf(subdomain) /* ugh */);
if(!aset.empty()) {
LOG(", in cache, ttl="<<(unsigned int)(((time_t)aset.begin()->ttl- d_now.tv_sec ))<<endl);
}
}
else {
*flawedNSSet=true;
- LOG(prefix<<qname<<": NS in cache for '"<<subdomain<<"', but needs glue ("<<k->content<<") which we miss or is expired"<<endl);
+ LOG(prefix<<qname.toString()<<": NS in cache for '"<<subdomain.toString()<<"', but needs glue ("<<k->content<<") which we miss or is expired"<<endl);
}
}
}
if(beenthere.count(answer)) {
brokeloop=true;
- LOG(prefix<<qname<<": We have NS in cache for '"<<subdomain<<"' but part of LOOP (already seen "<<answer.qname<<")! Trying less specific NS"<<endl);
+ LOG(prefix<<qname.toString()<<": We have NS in cache for '"<<subdomain.toString()<<"' but part of LOOP (already seen "<<answer.qname.toString()<<")! Trying less specific NS"<<endl);
if(doLog())
for( set<GetBestNSAnswer>::const_iterator j=beenthere.begin();j!=beenthere.end();++j) {
bool neo = !(*j< answer || answer<*j);
- LOG(prefix<<qname<<": beenthere"<<(neo?"*":"")<<": "<<j->qname<<"|"<<DNSRecordContent::NumberToType(j->qtype)<<" ("<<(unsigned int)j->bestns.size()<<")"<<endl);
+ LOG(prefix<<qname.toString()<<": beenthere"<<(neo?"*":"")<<": "<<j->qname.toString()<<"|"<<DNSRecordContent::NumberToType(j->qtype)<<" ("<<(unsigned int)j->bestns.size()<<")"<<endl);
}
bestns.clear();
}
else {
beenthere.insert(answer);
- LOG(prefix<<qname<<": We have NS in cache for '"<<subdomain<<"' (flawedNSSet="<<*flawedNSSet<<")"<<endl);
+ LOG(prefix<<qname.toString()<<": We have NS in cache for '"<<subdomain.toString()<<"' (flawedNSSet="<<*flawedNSSet<<")"<<endl);
return;
}
}
}
- LOG(prefix<<qname<<": no valid/useful NS in cache for '"<<subdomain<<"'"<<endl);
- if(subdomain=="." && !brokeloop) {
- primeHints();
- LOG(prefix<<qname<<": reprimed the root"<<endl);
+ LOG(prefix<<qname.toString()<<": no valid/useful NS in cache for '"<<subdomain.toString()<<"'"<<endl);
+ if(subdomain=="." && !brokeloop) {
+ primeHints();
+ LOG(prefix<<qname.toString()<<": reprimed the root"<<endl);
}
- }while(chopOffDotted(subdomain));
+ }while(subdomain.chopOff());
}
-SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(string* qname)
+SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(DNSName* qname)
{
SyncRes::domainmap_t::const_iterator ret;
do {
ret=t_sstorage->domainmap->find(*qname);
if(ret!=t_sstorage->domainmap->end())
break;
- }while(chopOffDotted(*qname));
+ }while(qname->chopOff());
return ret;
}
/** doesn't actually do the work, leaves that to getBestNSFromCache */
-string SyncRes::getBestNSNamesFromCache(const string &qname, const QType& qtype, set<string, CIStringCompare>& nsset, bool* flawedNSSet, int depth, set<GetBestNSAnswer>&beenthere)
+DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType& qtype, set<DNSName>& nsset, bool* flawedNSSet, int depth, set<GetBestNSAnswer>&beenthere)
{
- string subdomain(qname);
- string authdomain(qname);
-
+ DNSName subdomain(qname);
+ DNSName authdomain(qname);
+
domainmap_t::const_iterator iter=getBestAuthZone(&authdomain);
if(iter!=t_sstorage->domainmap->end()) {
if( iter->second.d_servers.empty() )
return subdomain;
}
-bool SyncRes::doCNAMECacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
+bool SyncRes::doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
{
string prefix;
if(doLog()) {
}
if((depth>9 && d_outqueries>10 && d_throttledqueries>5) || depth > 15) {
- LOG(prefix<<qname<<": recursing (CNAME or other indirection) too deep, depth="<<depth<<endl);
+ LOG(prefix<<qname.toString()<<": recursing (CNAME or other indirection) too deep, depth="<<depth<<endl);
res=RCode::ServFail;
return true;
}
-
- LOG(prefix<<qname<<": Looking for CNAME cache hit of '"<<(qname+"|CNAME")<<"'"<<endl);
+
+ LOG(prefix<<qname.toString()<<": Looking for CNAME cache hit of '"<<(qname.toString()+"|CNAME")<<"'"<<endl);
set<DNSResourceRecord> cset;
if(t_RC->get(d_now.tv_sec, qname,QType(QType::CNAME),&cset) > 0) {
for(set<DNSResourceRecord>::const_iterator j=cset.begin();j!=cset.end();++j) {
if(j->ttl>(unsigned int) d_now.tv_sec) {
- LOG(prefix<<qname<<": Found cache CNAME hit for '"<< (qname+"|CNAME") <<"' to '"<<j->content<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": Found cache CNAME hit for '"<< (qname.toString()+"|CNAME") <<"' to '"<<j->content<<"'"<<endl);
DNSResourceRecord rr=*j;
rr.ttl-=d_now.tv_sec;
ret.push_back(rr);
}
}
}
- LOG(prefix<<qname<<": No CNAME cache hit of '"<< (qname+"|CNAME") <<"' found"<<endl);
+ LOG(prefix<<qname.toString()<<": No CNAME cache hit of '"<< (qname.toString()+"|CNAME") <<"' found"<<endl);
return false;
}
// accepts . terminated names, www.powerdns.com. -> com.
-static const string getLastLabel(const std::string& qname)
+static const string getLastLabel(const DNSName& qname)
{
- if(qname.empty() || qname == ".")
- return qname;
-
- labelparts_t parts;
- labeltokUnescape(parts, qname);
- int offset = (parts.end()-1)->first;
-
- return qname.substr(offset, qname.size()-offset);
+ auto parts = qname.getRawLabels();
+ return parts[parts.size()-1];
}
-bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
+bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
{
bool giveNegative=false;
prefix.append(depth, ' ');
}
- string sqname(qname);
+ DNSName sqname(qname);
QType sqt(qtype);
uint32_t sttl=0;
// cout<<"Lookup for '"<<qname<<"|"<<qtype.getName()<<"' -> "<<getLastLabel(qname)<<endl;
(range.first=t_sstorage->negcache.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<<qname<<": Entire record '"<<qname<<"', is negatively cached via '"<<range.first->d_name<<"' & '"<<range.first->d_qname<<"' for another "<<sttl<<" seconds"<<endl);
- res = RCode::NXDomain;
+
+ LOG(prefix<<qname.toString()<<": Entire name '"<<qname.toString()<<"', is negatively cached via '"<<range.first->d_name.toString()<<"' & '"<<range.first->d_qname.toString()<<"' for another "<<sttl<<" seconds"<<endl);
+ res = RCode::NXDomain;
sqname=range.first->d_qname;
sqt=QType::SOA;
moveCacheItemToBack(t_sstorage->negcache, range.first);
if((uint32_t)d_now.tv_sec < ni->d_ttd) {
sttl=ni->d_ttd - d_now.tv_sec;
if(ni->d_qtype.getCode()) {
- LOG(prefix<<qname<<": "<<qtype.getName()<<" is negatively cached via '"<<ni->d_qname<<"' for another "<<sttl<<" seconds"<<endl);
+ LOG(prefix<<qname.toString()<<": "<<qtype.getName()<<" is negatively cached via '"<<ni->d_qname<<"' for another "<<sttl<<" seconds"<<endl);
res = RCode::NoError;
}
else {
- LOG(prefix<<qname<<": Entire record '"<<qname<<"', is negatively cached via '"<<ni->d_qname<<"' for another "<<sttl<<" seconds"<<endl);
- res= RCode::NXDomain;
+ LOG(prefix<<qname.toString()<<": Entire name '"<<qname.toString()<<"', is negatively cached via '"<<ni->d_qname<<"' for another "<<sttl<<" seconds"<<endl);
+ res= RCode::NXDomain;
}
giveNegative=true;
sqname=ni->d_qname;
break;
}
else {
- LOG(prefix<<qname<<": Entire record '"<<qname<<"' or type was negatively cached, but entry expired"<<endl);
+ LOG(prefix<<qname.toString()<<": Entire name '"<<qname<<"' or type was negatively cached, but entry expired"<<endl);
moveCacheItemToFront(t_sstorage->negcache, ni);
}
}
bool found=false, expired=false;
if(t_RC->get(d_now.tv_sec, sqname, sqt, &cset) > 0) {
- LOG(prefix<<sqname<<": Found cache hit for "<<sqt.getName()<<": ");
+ LOG(prefix<<sqname.toString()<<": Found cache hit for "<<sqt.getName()<<": ");
for(set<DNSResourceRecord>::const_iterator j=cset.begin();j!=cset.end();++j) {
LOG(j->content);
if(j->ttl>(unsigned int) d_now.tv_sec) {
return true;
}
else
- LOG(prefix<<qname<<": cache had only stale entries"<<endl);
+ LOG(prefix<<qname.toString()<<": cache had only stale entries"<<endl);
}
return false;
}
+// FIXME use DNSName.isPartOf
bool SyncRes::moreSpecificThan(const string& a, const string &b)
{
static string dot(".");
}
/** returns -1 in case of no results, rcode otherwise */
-int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth, bool flawedNSSet, const string &qname, const QType &qtype,
- vector<DNSResourceRecord>&ret,
+int SyncRes::doResolveAt(set<DNSName> nameservers, string auth, bool flawedNSSet, const string &qname, const QType &qtype,
+ vector<DNSResourceRecord>&ret,
int depth, set<GetBestNSAnswer>&beenthere)
{
string prefix;
prefix=d_prefix;
prefix.append(depth, ' ');
}
-
- LOG(prefix<<qname<<": Cache consultations done, have "<<(unsigned int)nameservers.size()<<" NS to contact"<<endl);
+
+ LOG(prefix<<qname.toString()<<": Cache consultations done, have "<<(unsigned int)nameservers.size()<<" NS to contact"<<endl);
for(;;) { // we may get more specific nameservers
vector<string > rnameservers = shuffleInSpeedOrder(nameservers, doLog() ? (prefix+qname+": ") : string() );
for(vector<string >::const_iterator tns=rnameservers.begin();;++tns) {
if(tns==rnameservers.end()) {
- LOG(prefix<<qname<<": Failed to resolve via any of the "<<(unsigned int)rnameservers.size()<<" offered NS at level '"<<auth<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": Failed to resolve via any of the "<<(unsigned int)rnameservers.size()<<" offered NS at level '"<<auth<<"'"<<endl);
if(auth!="." && flawedNSSet) {
- LOG(prefix<<qname<<": Ageing nameservers for level '"<<auth<<"', next query might succeed"<<endl);
+ LOG(prefix<<qname.toString()<<": Ageing nameservers for level '"<<auth<<"', next query might succeed"<<endl);
if(t_RC->doAgeCache(d_now.tv_sec, auth, QType::NS, 10))
g_stats.nsSetInvalidations++;
}
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)) {
- LOG(prefix<<qname<<": Not using NS to resolve itself!"<<endl);
+ if(pdns_iequals(qname, *tns) && qtype.getCode()==QType::A && rnameservers.size() > (unsigned)(1+1*s_doIPv6)) {
+ LOG(prefix<<qname.toString()<<": Not using NS to resolve itself!"<<endl);
continue;
}
bool sendRDQuery=false;
LWResult lwr;
if(tns->empty()) {
- LOG(prefix<<qname<<": Domain is out-of-band"<<endl);
+ LOG(prefix<<qname.toString()<<": Domain is out-of-band"<<endl);
doOOBResolve(qname, qtype, lwr.d_result, depth, lwr.d_rcode);
lwr.d_tcbit=false;
lwr.d_aabit=true;
}
else {
- LOG(prefix<<qname<<": Trying to resolve NS '"<<*tns<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<<endl);
+ LOG(prefix<<qname.toString()<<": Trying to resolve NS '"<<*tns<< "' ("<<1+tns-rnameservers.begin()<<"/"<<(unsigned int)rnameservers.size()<<")"<<endl);
if(!isCanonical(*tns)) {
- LOG(prefix<<qname<<": Domain has hardcoded nameserver(s)"<<endl);
+ LOG(prefix<<qname.toString()<<": Domain has hardcoded nameserver(s)"<<endl);
string txtAddr = *tns;
if(!tns->empty()) {
}
if(remoteIPs.empty()) {
- LOG(prefix<<qname<<": Failed to get IP for NS "<<*tns<<", trying next if available"<<endl);
+ LOG(prefix<<qname.toString()<<": Failed to get IP for NS "<<*tns<<", trying next if available"<<endl);
flawedNSSet=true;
continue;
}
else {
- LOG(prefix<<qname<<": Resolved '"+auth+"' NS "<<*tns<<" to: ");
+ LOG(prefix<<qname.toString()<<": Resolved '"+auth+"' NS "<<*tns<<" to: ");
for(remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) {
if(remoteIP != remoteIPs.begin()) {
LOG(", ");
}
for(remoteIP = remoteIPs.begin(); remoteIP != remoteIPs.end(); ++remoteIP) {
- LOG(prefix<<qname<<": Trying IP "<< remoteIP->toStringWithPort() <<", asking '"<<qname<<"|"<<qtype.getName()<<"'"<<endl);
+ LOG(prefix<<qname.toString()<<": Trying IP "<< remoteIP->toStringWithPort() <<", asking '"<<qname.toString()<<"|"<<qtype.getName()<<"'"<<endl);
extern NetmaskGroup* g_dontQuery;
if(t_sstorage->throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(*remoteIP, "", 0))) {
- LOG(prefix<<qname<<": server throttled "<<endl);
+ LOG(prefix<<qname.toString()<<": server throttled "<<endl);
s_throttledqueries++; d_throttledqueries++;
continue;
}
else if(t_sstorage->throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()))) {
- LOG(prefix<<qname<<": query throttled "<<endl);
+ LOG(prefix<<qname.toString()<<": query throttled "<<endl);
s_throttledqueries++; d_throttledqueries++;
continue;
}
else if(!pierceDontQuery && g_dontQuery && g_dontQuery->match(&*remoteIP)) {
- LOG(prefix<<qname<<": not sending query to " << remoteIP->toString() << ", blocked by 'dont-query' setting" << endl);
+ LOG(prefix<<qname.toString()<<": not sending query to " << remoteIP->toString() << ", blocked by 'dont-query' setting" << endl);
s_dontqueries++;
continue;
}
if(d_outqueries + d_throttledqueries > s_maxqperq) throw ImmediateServFailException("more than "+lexical_cast<string>(s_maxqperq)+" (max-qperq) queries sent while resolving "+qname);
TryTCP:
if(doTCP) {
- LOG(prefix<<qname<<": using TCP with "<< remoteIP->toStringWithPort() <<endl);
+ LOG(prefix<<qname.toString()<<": using TCP with "<< remoteIP->toStringWithPort() <<endl);
s_tcpoutqueries++; d_tcpoutqueries++;
}
throw ImmediateServFailException("Too much time waiting for "+qname+"|"+qtype.getName()+", timeouts: "+boost::lexical_cast<string>(d_timeouts) +", throttles: "+boost::lexical_cast<string>(d_throttledqueries) + ", queries: "+lexical_cast<string>(d_outqueries)+", "+lexical_cast<string>(d_totUsec/1000)+"msec");
if(d_pdl && d_pdl->preoutquery(*remoteIP, d_requestor, qname, qtype, lwr.d_result, resolveret)) {
- LOG(prefix<<qname<<": query handled by Lua"<<endl);
+ LOG(prefix<<qname.toString()<<": query handled by Lua"<<endl);
}
else
resolveret=asyncresolveWrapper(*remoteIP, qname, qtype.getCode(),
class RecursorLua;
struct NegCacheEntry
{
- string d_name;
+ DNSName d_name;
QType d_qtype;
- string d_qname;
+ DNSName d_qname;
uint32_t d_ttd;
uint32_t getTTD() const
{
explicit SyncRes(const struct timeval& now);
- int beginResolve(const string &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret);
+ int beginResolve(const DNSName &qname, const QType &qtype, uint16_t qclass, vector<DNSResourceRecord>&ret);
void setId(int id)
{
if(doLog())
}
- int asyncresolveWrapper(const ComboAddress& ip, const string& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res);
+ int asyncresolveWrapper(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res);
static void doEDNSDumpAndClose(int fd);
ordered_unique<
composite_key<
NegCacheEntry,
- member<NegCacheEntry, string, &NegCacheEntry::d_name>,
+ member<NegCacheEntry, DNSName, &NegCacheEntry::d_name>,
member<NegCacheEntry, QType, &NegCacheEntry::d_qtype>
>,
- composite_key_compare<CIStringCompare, std::less<QType> >
+ composite_key_compare<std::less<DNSName>, std::less<QType> >
>,
sequenced<>
>
ComboAddress d_best;
};
- typedef map<string, DecayingEwmaCollection, CIStringCompare> nsspeeds_t;
+ typedef map<DNSName, DecayingEwmaCollection, CIStringCompare> nsspeeds_t;
struct EDNSStatus
{
indexed_by <
ordered_non_unique<
composite_key< DNSResourceRecord,
- member<DNSResourceRecord, string, &DNSResourceRecord::qname>,
+ member<DNSResourceRecord, DNSName, &DNSResourceRecord::qname>,
member<DNSResourceRecord, QType, &DNSResourceRecord::qtype>
>,
- composite_key_compare<CIStringCompare, std::less<QType> >
+ composite_key_compare<std::less<DNSName>, std::less<QType> >
>
>
> records_t;
};
- typedef map<string, AuthDomain, CIStringCompare> domainmap_t;
+ typedef map<DNSName, AuthDomain> domainmap_t;
- typedef Throttle<boost::tuple<ComboAddress,string,uint16_t> > throttle_t;
+ typedef Throttle<boost::tuple<ComboAddress,DNSName,uint16_t> > throttle_t;
typedef Counters<ComboAddress> fails_t;
private:
struct GetBestNSAnswer;
- int doResolveAt(set<string, CIStringCompare> nameservers, string auth, bool flawedNSSet, const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret,
+ int doResolveAt(set<DNSName> nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret,
int depth, set<GetBestNSAnswer>&beenthere);
- int doResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, set<GetBestNSAnswer>& beenthere);
- bool doOOBResolve(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res);
- domainmap_t::const_iterator getBestAuthZone(string* qname);
- bool doCNAMECacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res);
- bool doCacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res);
- void getBestNSFromCache(const string &qname, const QType &qtype, set<DNSResourceRecord>&bestns, bool* flawedNSSet, int depth, set<GetBestNSAnswer>& beenthere);
- string getBestNSNamesFromCache(const string &qname, const QType &qtype, set<string, CIStringCompare>& nsset, bool* flawedNSSet, int depth, set<GetBestNSAnswer>&beenthere);
-
- inline vector<string> shuffleInSpeedOrder(set<string, CIStringCompare> &nameservers, const string &prefix);
+ int doResolve(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, set<GetBestNSAnswer>& beenthere);
+ bool doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res);
+ domainmap_t::const_iterator getBestAuthZone(DNSName* qname);
+ bool doCNAMECacheCheck(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res);
+ bool doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res);
+ void getBestNSFromCache(const DNSName &qname, const QType &qtype, set<DNSResourceRecord>&bestns, bool* flawedNSSet, int depth, set<GetBestNSAnswer>& beenthere);
+ DNSName getBestNSNamesFromCache(const DNSName &qname, const QType &qtype, set<DNSName>& nsset, bool* flawedNSSet, int depth, set<GetBestNSAnswer>&beenthere);
+
+ inline vector<DNSName> shuffleInSpeedOrder(set<DNSName> &nameservers, const string &prefix);
bool moreSpecificThan(const string& a, const string &b);
- vector<ComboAddress> getAddrs(const string &qname, int depth, set<GetBestNSAnswer>& beenthere);
+ vector<ComboAddress> getAddrs(const DNSName &qname, int depth, set<GetBestNSAnswer>& beenthere);
private:
ostringstream d_trace;
shared_ptr<RecursorLua> d_pdl;
struct GetBestNSAnswer
{
- string qname;
- set<pair<string,string> > bestns;
+ DNSName qname;
+ set<pair<DNSName,string> > bestns; // FIXME right side really should be DNSName too
uint8_t qtype; // only A and AAAA anyhow
bool operator<(const GetBestNSAnswer &b) const
{
uint16_t id; // wait for a specific id/remote pair
ComboAddress remote; // this is the remote
- string 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
if( tie(remote, ourSock, type) > tie(b.remote, bSock, b.type))
return false;
- if(pdns_ilexicographical_compare(domain, b.domain))
- return true;
- if(pdns_ilexicographical_compare(b.domain, domain))
- return false;
-
- return tie(fd, id) < tie(b.fd, b.id);
+ return tie(domain, fd, id) < tie(b.domain, b.fd, b.id);
}
};
if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type))
return false;
- return pdns_ilexicographical_compare(a.domain, b.domain);
+ return pdns_ilexicographical_compare(a.domain.toString(), b.domain.toString()); // FIXME
}
};
extern __thread MemRecursorCache* t_RC;
#endif
extern __thread addrringbuf_t* t_servfailremotes, *t_largeanswerremotes, *t_remotes;
-extern __thread boost::circular_buffer<pair<std::string,uint16_t> >* t_queryring, *t_servfailqueryring;
+extern __thread boost::circular_buffer<pair<DNSName,uint16_t> >* t_queryring, *t_servfailqueryring;
extern __thread NetmaskGroup* t_allowFrom;
string doQueueReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
string doTraceRegex(vector<string>::const_iterator begin, vector<string>::const_iterator end);
ComboAddress getQueryLocalAddress(int family, uint16_t port);
typedef boost::function<void*(void)> pipefunc_t;
void broadcastFunction(const pipefunc_t& func, bool skipSelf = false);
-void distributeAsyncFunction(const std::string& question, const pipefunc_t& func);
+void distributeAsyncFunction(const DNSName& question, const pipefunc_t& func);
-int directResolve(const std::string& qname, const QType& qtype, int qclass, vector<DNSResourceRecord>& ret);
+int directResolve(const DNSName& qname, const QType& qtype, int qclass, vector<DNSResourceRecord>& ret);
template<class T> T broadcastAccFunction(const boost::function<T*()>& func, bool skipSelf=false);
uint64_t* pleaseGetThrottleSize();
uint64_t* pleaseGetPacketCacheHits();
uint64_t* pleaseGetPacketCacheSize();
-uint64_t* pleaseWipeCache(const std::string& canon);
-uint64_t* pleaseWipeAndCountNegCache(const std::string& canon);
+uint64_t* pleaseWipeCache(const DNSName& canon);
+uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon);
void doCarbonDump(void*);
#endif