Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
#include <iostream>
#include <errno.h>
#include <map>
typedef map<string,set<DNSResourceRecord> > cache_t;
cache_t cache;
+int cacheHits, cacheMisses;
int getCache(const string &qname, const QType& qt, set<DNSResourceRecord>* res)
{
cache_t::const_iterator j=cache.find(toLower(qname)+"|"+qt.getName());
if(j!=cache.end() && j->first==toLower(qname)+"|"+qt.getName() && j->second.begin()->ttl>(unsigned int)time(0)) {
if(res)
*res=j->second;
+ cacheHits++;
return (unsigned int)j->second.begin()->ttl-time(0);
}
+ cacheMisses++;
return -1;
}
PacketID pident;
init();
+ int counter=0;
for(;;) {
while(MT.schedule()); // housekeeping, let threads do their thing
else {
cout<<"new question arrived for '"<<P.qdomain<<"|"<<P.qtype.getName()<<"' from "<<P.getRemote()<<endl;
MT.makeThread(startDoResolve,(void*)new DNSPacket(P));
+ if(!((counter++)%100)) {
+ cout<<"stats: "<<counter<<" questions, "<<cache.size()<<" cache entries, "<<(cacheHits*100.0)/(cacheHits+cacheMisses)<<"% cache hits"<<endl;
+ }
}
}
}
template<class MultiPlexor>bool SyncRes<MultiPlexor>::doCNAMECacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
{
+ if(depth>10) {
+ cout<<prefix<<qname<<": CNAME loop too deep, depth="<<depth<<endl;
+ res=RCode::ServFail;
+ return true;
+ }
+
string prefix, tuple=toLower(qname)+"|CNAME";
prefix.assign(3*depth, ' ');
cout<<prefix<<qname<<": determining status after receiving this packet"<<endl;
bool done=false, realreferral=false, negindic=false;
- string newauth, soaname;
+ string newauth, soaname, newtarget;
for(LWRes::res_t::const_iterator i=result.begin();i!=result.end();++i) {
if(i->d_place==DNSResourceRecord::AUTHORITY && endsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA) {
negindic=true;
}
else if(i->d_place==DNSResourceRecord::ANSWER && i->qname==qname && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) {
- cout<<prefix<<qname<<": got a CNAME referral, starting over with "<<i->content<<endl<<endl;
ret.push_back(*i);
- set<GetBestNSAnswer>beenthere2;
- return doResolve(i->content, qtype, ret,0,beenthere2);
+ newtarget=i->content;
}
// for ANY answers we *must* have an authoritive answer
else if(i->d_place==DNSResourceRecord::ANSWER && i->qname==qname && (i->qtype==qtype || ( qtype==QType(QType::ANY) && aabit))) {
cout<<prefix<<qname<<": status=noerror, other types may exist, but we are done "<<(negindic ? "(have negative SOA)" : "")<<endl;
return 0;
}
+ if(!newtarget.empty()) {
+ cout<<prefix<<qname<<": status=got a CNAME referral, starting over with "<<newtarget<<endl<<endl;
+ set<GetBestNSAnswer>beenthere2;
+ return doResolve(newtarget, qtype, ret,0,beenthere2);
+ }
else if(realreferral) {
cout<<prefix<<qname<<": status=did not resolve, got "<<nsset.size()<<" NS, looping to them"<<endl;
auth=newauth;