From: Bert Hubert Date: Sat, 11 Jan 2003 21:09:57 +0000 (+0000) Subject: I horked the recursor code for now but it WILL get better! X-Git-Tag: pdns-2.9.5~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7bf2638379826e89d655194bf5834bd7deda450a;p=thirdparty%2Fpdns.git I horked the recursor code for now but it WILL get better! git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@126 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 57435c1fdc..4759dfdc58 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -35,7 +35,7 @@ backends/bind/bindbackend.cc backends/bind/zoneparser2.cc \ backends/bind/bindparser.cc backends/bind/bindlexer.c \ backends/bind/huffman.cc backends/gsql/gsqlbackend.cc \ backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh \ -sillyrecords.cc +sillyrecords.cc recbcomm.hh recbcomm.cc # pdns_server_LDFLAGS= @moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index 8a5fe2475d..553c728481 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -17,6 +17,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "common_startup.hh" +#include "recbcomm.hh" typedef Distributor DNSDistributor; @@ -30,6 +31,7 @@ CommunicatorClass Communicator; UDPNameserver *N; int avg_latency; TCPNameserver *TN; +SyncresCommunicator* SRC; ArgvMap &arg() { @@ -254,9 +256,6 @@ void mainthread() // NOW SAFE TO CREATE THREADS! dl->go(); - - - pthread_t qtid; StatWebServer sws; @@ -266,6 +265,8 @@ void mainthread() if(arg().mustDo("slave") || arg().mustDo("master")) Communicator.go(); + SRC=new SyncresCommunicator(); + if(TN) TN->go(); // tcp nameserver launch diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index 5978321f19..3eb54a651f 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -// $Id: dnspacket.cc,v 1.9 2003/01/10 18:43:01 ahu Exp $ +// $Id: dnspacket.cc,v 1.10 2003/01/11 21:09:57 ahu Exp $ #include "utility.hh" #include @@ -247,18 +247,11 @@ void DNSPacket::addARecord(const string &name, u_int32_t ip, u_int32_t ttl, DNSR p[2]=0; p[3]=1; // IN - u_int32_t *ttlp=(u_int32_t *)(p+4); - - *ttlp=htonl(ttl); // 4, 5, 6, 7 - + putLong(p+4, ttl); p[8]=0; p[9]=4; // length of data - p[10]=(ip>>24)&0xff; - p[11]=(ip>>16)&0xff; - p[12]=(ip>>8)&0xff; - p[13]=ip&0xff; - + putLong(p+10,ip); stringbuffer.append(piece1); stringbuffer.append(p,14); @@ -296,10 +289,7 @@ void DNSPacket::addAAAARecord(const string &name, unsigned char addr[16], u_int3 p[2]=0; p[3]=1; // IN - u_int32_t *ttlp=(u_int32_t *)(p+4); - - *ttlp=htonl(ttl); // 4, 5, 6, 7 - + putLong(p+4,ttl); p[8]=0; p[9]=16; // length of data @@ -332,9 +322,7 @@ void DNSPacket::addMXRecord(const string &domain, const string &mx, int priority piece2[2]=0; piece2[3]=1; // IN - u_int32_t *ttlp=(u_int32_t *)(piece2+4); - *ttlp=htonl(ttl); // 4, 5, 6, 7 - + putLong(piece2+4,ttl); piece2[8]=0; piece2[9]=0; // need to fill this in @@ -421,13 +409,10 @@ void DNSPacket::fillSOAData(const string &content, SOAData &data) string DNSPacket::serializeSOAData(const SOAData &d) { ostringstream o; - // nameservername hostmaster serial-number [refresh [retry [expire [ minimum] ] ] ] - o<1024) + addGenericRecord(rr); + else + L< DNSPacket::getAnswers() rr.content=tmp; break; - default: - throw AhuException("Unknown type number "+itoa(rr.qtype.getCode())+" for: '"+rr.qname+"'"); + rr.qtype=rr.qtype.getCode()+1024; + rr.content.assign((const char *)datapos,length); + // throw AhuException("Unknown type number "+itoa(rr.qtype.getCode())+" for: '"+rr.qname+"'"); } if(pos - v2.1 $Date: 2003/01/10 18:43:01 $ + v2.1 $Date: 2003/01/11 21:09:57 $ @@ -3954,20 +3954,20 @@ local0.err /var/log/pdns.err Only operates on the foreground, it does not fork. - - Can only answer queries for types and classes it knows about - it is not transparent as it should be. - Only ignores stale cache entries, does not actually clean them up. May replace them with newer data, however. - Not very IPv6 aware - does no AAAA additional processing. + Not very IPv6 aware - does no AAAA additional processing. Should not actually break anything. Only compiles on Linux and possibly Solaris. FreeBSD 4.x decided not to support the POSIX get/set/swapcontext functions. Bug your favorite FreeBSD kernel or libc maintainer for a fix, or ask him to port MTasker (see below) to your operating system. + + It does not do TCP yet, and may have big problems with truncated packets. + @@ -3980,7 +3980,7 @@ local0.err /var/log/pdns.err PowerDNS author bert hubert has the pdns recursor in production and browsing with it works for him. Furthermore, the LARTC - mailinglist (2000 subscribers) is using the pdns recursing nameserver. + mailinglist (2000 subscribers) is using the pdns recursing nameserver. diff --git a/pdns/misc.hh b/pdns/misc.hh index c449699e08..8651631a3b 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -56,6 +56,18 @@ string urlEncode(const string &text); int waitForData(int fd, int seconds); u_int16_t getShort(const unsigned char *p); u_int16_t getShort(const char *p); +inline void putLong(unsigned char* p, u_int32_t val) +{ + *p++=(val>>24)&0xff; + *p++=(val>>16)&0xff; + *p++=(val>>8)&0xff; + *p++=(val )&0xff; + +} +inline void putLong(char* p, u_int32_t val) +{ + putLong((unsigned char *)p,val); +} void upperCase(string& s); diff --git a/pdns/qtype.cc b/pdns/qtype.cc index f0b7a1dfb5..922fb4a3ea 100644 --- a/pdns/qtype.cc +++ b/pdns/qtype.cc @@ -48,10 +48,10 @@ QType::QType() insert("MX",15); insert("TXT",16); insert("RP",17); + insert("AAAA",28); insert("LOC",29); insert("SRV",33); insert("A6",38); - insert("AAAA",28); insert("NAPTR",35); insert("AXFR",252); insert("ANY",255); diff --git a/pdns/recns.cc b/pdns/recns.cc index fe1304a293..fcfdcb850c 100644 --- a/pdns/recns.cc +++ b/pdns/recns.cc @@ -124,7 +124,7 @@ void startDoResolve(void *p) delete R; } catch(AhuException &ae) { - cerr<<"startDoResolve timeout: "< > cache_t; cache_t cache; map negcache; +struct GetBestNSAnswer +{ + string qname; + set bestns; + bool operator<(const GetBestNSAnswer &b) const + { + if(qname nameservers, string auth, const string &qname, const QType &qtype, vector&ret,int depth=0); -int doResolve(const string &qname, const QType &qtype, vector&ret, int depth=0); +int doResolveAt(set nameservers, string auth, const string &qname, const QType &qtype, vector&ret, + int depth, set&beenthere); +int doResolve(const string &qname, const QType &qtype, vector&ret, int depth, set& beenthere); bool doCNAMECacheCheck(const string &qname, const QType &qtype, vector&ret, int depth, int &res); bool doCacheCheck(const string &qname, const QType &qtype, vector&ret, int depth, int &res); -void getBestNSFromCache(const string &qname, set&bestns, int depth); +void getBestNSFromCache(const string &qname, set&bestns, int depth, set& beenthere); void addCruft(const string &qname, vector& ret); -string getBestNSNamesFromCache(const string &qname,set& nsset, int depth); +string getBestNSNamesFromCache(const string &qname,set& nsset, int depth, set&beenthere); void addAuthorityRecords(const string& qname, vector& ret, int depth); /** everything begins here - this is the entry point just after receiving a packet */ int beginResolve(const string &qname, const QType &qtype, vector&ret) { - int res=doResolve(qname, qtype, ret,0); + set beenthere; + int res=doResolve(qname, qtype, ret,0,beenthere); if(!res) addCruft(qname, ret); cout<&ret, int depth) +int doResolve(const string &qname, const QType &qtype, vector&ret, int depth, set& beenthere) { string prefix; prefix.assign(3*depth, ' '); @@ -69,26 +85,43 @@ int doResolve(const string &qname, const QType &qtype, vector string subdomain(qname); set nsset; - subdomain=getBestNSNamesFromCache(subdomain,nsset,depth); - if(!(res=doResolveAt(nsset,subdomain,qname,qtype,ret,depth))) + subdomain=getBestNSNamesFromCache(subdomain,nsset,depth, beenthere); // pass beenthere to both occasions/ + if(!(res=doResolveAt(nsset,subdomain,qname,qtype,ret,depth, beenthere))) return 0; cout<& beenthere) { vector res; string ret; - if(!doResolve(qname,QType(QType::A), res,depth+1) && !res.empty()) + if(!doResolve(qname,QType(QType::A), res,depth+1,beenthere) && !res.empty()) ret=res[res.size()-1].content; // last entry, in case of CNAME in between return ret; } -void getBestNSFromCache(const string &qname, set&bestns, int depth) +int getCache(const string &qname, const QType& qt, set* res=0) +{ + 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; + return (unsigned int)j->second.begin()->ttl-time(0); + } + return -1; +} + +void replaceCache(const string &tuple, const set& content) +{ + cache[tuple]=content; +} + + +void getBestNSFromCache(const string &qname, set&bestns, int depth, set& beenthere) { string prefix, subdomain(qname); prefix.assign(3*depth, ' '); @@ -96,28 +129,38 @@ void getBestNSFromCache(const string &qname, set&bestns, int do { cout<first==toLower(subdomain)+"|NS") { - for(set::const_iterator k=j->second.begin();k!=j->second.end();++k) { - if(k->ttl>(unsigned int)time(0)) { // the below is fugly - if(!endsOn(k->content,subdomain) || // glue risk - (cache.find(toLower(k->content)+"|A")!=cache.end() && ((time_t)cache[toLower(k->content)+"|A"].begin()->ttl-time(0))>5)) { + setns; + if(getCache(subdomain,QType(QType::NS),&ns)>0) { + for(set::const_iterator k=ns.begin();k!=ns.end();++k) { + if(k->ttl>(unsigned int)time(0)) { + setaset; + if(!endsOn(k->content,subdomain) || getCache(k->content,QType(QType::A),&aset) > 5) { bestns.insert(*k); cout< '"<content<<"'"<content,subdomain); - if(cache.find(toLower(k->content)+"|A")!=cache.end()) - cout<<", in cache, ttl="<<((time_t)cache[toLower(k->content)+"|A"].begin()->ttl-time(0))<content<<") which we miss or is expired"<content<<") which we miss or is expired"<::const_iterator j=beenthere.begin();j!=beenthere.end();++j) + cout<qname<<" ("<bestns.size()<<")"<&bestns, int void addAuthorityRecords(const string& qname, vector& ret, int depth) { set bestns; - getBestNSFromCache(qname, bestns, depth); + setbeenthere; + getBestNSFromCache(qname, bestns, depth,beenthere); for(set::const_iterator k=bestns.begin();k!=bestns.end();++k) { DNSResourceRecord ns=*k; ns.d_place=DNSResourceRecord::AUTHORITY; @@ -134,13 +178,13 @@ void addAuthorityRecords(const string& qname, vector& ret, in ret.push_back(ns); } } - -string getBestNSNamesFromCache(const string &qname,set& nsset, int depth) +/** doesn't actually do the work, leaves that to getBestNSFromCache */ +string getBestNSNamesFromCache(const string &qname,set& nsset, int depth, set&beenthere) { string subdomain(qname); set bestns; - getBestNSFromCache(subdomain, bestns, depth); + getBestNSFromCache(subdomain, bestns, depth, beenthere); for(set::const_iterator k=bestns.begin();k!=bestns.end();++k) { nsset.insert(k->content); @@ -155,16 +199,18 @@ bool doCNAMECacheCheck(const string &qname, const QType &qtype, vectorfirst==tuple) { // found it - for(set::const_iterator j=i->second.begin();j!=i->second.end();++j) { + set cset; + if(getCache(qname,QType(QType::CNAME),&cset) > 0) { + for(set::const_iterator j=cset.begin();j!=cset.end();++j) { if(j->ttl>(unsigned int)time(0)) { - cout<second.begin()->content<<"'"<content<<"'"<second.begin()->content, qtype, ret, depth); + if(!(qtype==QType(QType::CNAME))) {// perhaps they really wanted a CNAME! + setbeenthere; + res=doResolve(j->content, qtype, ret, depth, beenthere); + } return true; } } @@ -189,11 +235,11 @@ bool doCacheCheck(const string &qname, const QType &qtype, vectorsecond+"|SOA"; } - cache_t::const_iterator i=cache.find(tuple); + set cset; bool found=false, expired=false; - if(i!=cache.end() && i->first==tuple) { // found it + if(getCache(qname,qtype,&cset)>0) { cout<::const_iterator j=i->second.begin();j!=i->second.end();++j) { + for(set::const_iterator j=cset.begin();j!=cset.end();++j) { cout<content; if(j->ttl>(unsigned int)time(0)) { DNSResourceRecord rr=*j; @@ -243,7 +289,8 @@ inline vectorshuffle(set &nameservers) } /** returns -1 in case of no results, rcode otherwise */ -int doResolveAt(set nameservers, string auth, const string &qname, const QType &qtype, vector&ret, int depth) +int doResolveAt(set nameservers, string auth, const string &qname, const QType &qtype, vector&ret, + int depth, set&beenthere) { string prefix; prefix.assign(3*depth, ' '); @@ -251,7 +298,7 @@ int doResolveAt(set nameservers, string auth, const string &qname, const LWRes r; LWRes::res_t result; - cout< nameservers, string auth, const string &qname, const cout< nameservers, string auth, const string &qname, const result=r.result(aabit); cout<qtype.getName()].insert(rr); } else @@ -310,7 +357,7 @@ int doResolveAt(set nameservers, string auth, const string &qname, const // supplant for(cache_t::const_iterator i=tcache.begin();i!=tcache.end();++i) - cache[i->first]=i->second; + replaceCache(i->first,i->second); set nsset; cout< nameservers, string auth, const string &qname, const else if(i->d_place==DNSResourceRecord::ANSWER && i->qname==qname && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) { cout<content<content, qtype, ret,0); + setbeenthere2; + return doResolve(i->content, qtype, ret,0,beenthere2); } // 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))) { @@ -342,9 +390,8 @@ int doResolveAt(set nameservers, string auth, const string &qname, const cout<qname<<"' -> '"<content<<"'"<qname<<"' -> '"<content<<"', already had '"<qname<<"' -> '"<content<<"', had '"<content)); } } @@ -368,7 +415,7 @@ int doResolveAt(set nameservers, string auth, const string &qname, const break; } else { - cout<& ret) if((k->d_place==DNSResourceRecord::ANSWER && k->qtype==QType(QType::MX)) || (k->d_place==DNSResourceRecord::AUTHORITY && k->qtype==QType(QType::NS))) { cout<content<<"|"<qtype.getName()<<"' needs an IP address"<content,QType(QType::A),addit,1); + setbeenthere; + doResolve(k->content,QType(QType::A),addit,1,beenthere); } for(vector::iterator k=addit.begin();k!=addit.end();++k) {