struct timeval d_now;
-static bool magicAddrMatch(const QType& query, const QType& answer)
-{
- if(query.getCode() != QType::ADDR)
- return false;
- return answer.getCode() == QType::A || answer.getCode() == QType::AAAA;
-}
-
-
-bool moreSpecificThan(const string& a, const string &b)
-{
- static string dot(".");
- int counta=(a!=dot), countb=(b!=dot);
-
- for(string::size_type n=0;n<a.size();++n)
- if(a[n]=='.')
- counta++;
- for(string::size_type n=0;n<b.size();++n)
- if(b[n]=='.')
- countb++;
- return counta>countb;
-}
struct ParsePacketTest
lwr.d_result.push_back(rr);
}
-
-
-
- // reap all answers from this packet that are acceptable
- for(vector<DNSResourceRecord>::iterator i=lwr.d_result.begin();i != lwr.d_result.end();++i) {
- if(i->qtype.getCode() == QType::OPT) {
- // <<prefix<<qname<<": skipping OPT answer '"<<i->qname<<"' from '"<<auth<<"' nameservers" <<endl;
- continue;
- }
- // LOG<<prefix<<qname<<": accept answer '"<<i->qname<<"|"<<i->qtype.getName()<<"|"<<i->content<<"' from '"<<auth<<"' nameservers? ";
- if(i->qtype.getCode()==QType::ANY) {
- // LOG<<"NO! - we don't accept 'ANY' data"<<endl;
- continue;
- }
- string auth(".");
- if(dottedEndsOn(i->qname, auth)) {
- if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && i->d_place==DNSResourceRecord::ANSWER && 0) {
- // LOG<<"NO! Is from delegation-only zone"<<endl;
- // s_nodelegated++;
- return; // RCode::NXDomain;
- }
- else {
- // LOG<<"YES!"<<endl;
-
- // i->ttl=min(s_maxcachettl, i->ttl);
-
- DNSResourceRecord rr=*i;
- rr.d_place=DNSResourceRecord::ANSWER;
-
- // rr.ttl += d_now.tv_sec;
-
- if(rr.qtype.getCode() == QType::NS) // people fiddle with the case
- rr.content=toLower(rr.content); // this must stay! (the cache can't be case-insensitive on the RHS of records)
- tcache[make_pair(i->qname,i->qtype)].insert(rr);
- }
- }
- else
- ; // LOG<<"NO!"<<endl;
- }
-
- // supplant
- for(tcache_t::iterator i=tcache.begin();i!=tcache.end();++i) {
- if(i->second.size() > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2)
- uint32_t lowestTTL=std::numeric_limits<uint32_t>::max();
- for(tcache_t::value_type::second_type::iterator j=i->second.begin(); j != i->second.end(); ++j)
- lowestTTL=min(lowestTTL, j->ttl);
-
- for(tcache_t::value_type::second_type::iterator j=i->second.begin(); j != i->second.end(); ++j)
- ((tcache_t::value_type::second_type::value_type*)&(*j))->ttl=lowestTTL;
- }
-
- // RC.replace(d_now.tv_sec, i->first.first, i->first.second, i->second, lwr.d_aabit);
- }
- set<string, CIStringCompare> nsset;
- // LOG<<prefix<<qname<<": determining status after receiving this packet"<<endl;
-
- bool done=false;
- string newauth, soaname, newtarget;
- string qname(".");
- vector<DNSResourceRecord> ret;
- QType qtype(QType::A);
- string auth(".");
-
- for(vector<DNSResourceRecord>::const_iterator i=lwr.d_result.begin();i!=lwr.d_result.end();++i) {
- if(i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA &&
- lwr.d_rcode==RCode::NXDomain) {
- // LOG<<prefix<<qname<<": got negative caching indication for RECORD '"<<qname+"'"<<endl;
- ret.push_back(*i);
-
- NegCacheEntry ne;
-
- ne.d_qname=i->qname;
- ne.d_ttd=d_now.tv_sec + min(i->ttl, 3600U); // controversial
- ne.d_name=qname;
- ne.d_qtype=QType(0); // this encodes 'whole record'
-
- {
- // Lock l(&s_negcachelock);
- // replacing_insert(s_negcache, ne);
- }
- }
- else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) {
- ret.push_back(*i);
- newtarget=i->content;
- }
- // for ANY answers we *must* have an authoritative answer
- else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) &&
- (
- i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) )
- )
- )
- {
-
- // LOG<<prefix<<qname<<": answer is in: resolved to '"<< i->content<<"|"<<i->qtype.getName()<<"'"<<endl;
-
- done=true;
- ret.push_back(*i);
- }
- else if(i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::NS) {
- if(moreSpecificThan(i->qname,auth)) {
- newauth=i->qname;
- // LOG<<prefix<<qname<<": got NS record '"<<i->qname<<"' -> '"<<i->content<<"'"<<endl;
- }
- else
- ;// // LOG<<prefix<<qname<<": got upwards/level NS record '"<<i->qname<<"' -> '"<<i->content<<"', had '"<<auth<<"'"<<endl;
- nsset.insert(i->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<<qname<<": got negative caching indication for '"<< (qname+"|"+i->qtype.getName()+"'") <<endl;
- ret.push_back(*i);
-
- NegCacheEntry ne;
- ne.d_qname=i->qname;
- ne.d_ttd=d_now.tv_sec + i->ttl;
- ne.d_name=qname;
- ne.d_qtype=qtype;
- if(qtype.getCode()) { // prevents us from blacking out a whole domain
- // Lock l(&s_negcachelock);
- // replacing_insert(s_negcache, ne);
- }
- }
- }
}
const vector<uint8_t>& d_packet;
};
+struct DNSNameParseTest
+{
+ string getName() const
+ {
+ return "DNSName parse";
+ }
+
+ void operator()() const
+ {
+ DNSName name("www.powerdns.com");
+ }
+
+};
+
+struct DNSNameRootTest
+{
+ string getName() const
+ {
+ return "DNSName root";
+ }
+
+ void operator()() const
+ {
+ DNSName name(".");
+ }
+
+};
+
struct IEqualsTest
doRun(VStringtokTest());
doRun(StringAppendTest());
+ doRun(DNSNameParseTest());
+ doRun(DNSNameRootTest());
+
cerr<<"Total runs: " << g_totalRuns<<endl;
}