From: bert hubert Date: Sun, 25 Oct 2015 09:48:49 +0000 (+0100) Subject: teach ixplore many new tricks X-Git-Tag: dnsdist-1.0.0-alpha1~252^2~6^2~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=18ca5fa46a208a8d2d9c621b58a74dc2b141cd61;p=pdns teach ixplore many new tricks --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 01dcc57e8..8db0c57a8 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -571,8 +571,10 @@ endif ixplore_SOURCES = \ + arguments.cc \ base32.cc \ base64.cc base64.hh \ + dns.cc \ dns_random.cc dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ @@ -587,6 +589,7 @@ ixplore_SOURCES = \ nsecrecords.cc \ qtype.cc \ rcpgenerator.cc rcpgenerator.hh \ + resolver.cc \ ixplore.cc \ sillyrecords.cc \ sstuff.hh \ diff --git a/pdns/ixplore.cc b/pdns/ixplore.cc index f694231d8..4d09f3aa1 100644 --- a/pdns/ixplore.cc +++ b/pdns/ixplore.cc @@ -1,6 +1,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include "arguments.hh" #include "base64.hh" #include "dnsparser.hh" #include "sstuff.hh" @@ -15,17 +16,18 @@ #include "gss_context.hh" #include "zoneparser-tng.hh" #include +#include "resolver.hh" #include using namespace boost::multi_index; StatBag S; -struct CanonStruct : public std::binary_function + +ArgvMap &arg() { - bool operator()(const DNSName&a, const DNSName& b) const - { - return a.canonCompare(b); - } -}; + static ArgvMap theArg; + return theArg; +} + struct CIContentCompareStruct { @@ -45,13 +47,13 @@ typedef multi_index_container< member, member, member, &DNSRecord::d_content> >, - composite_key_compare, std::less, CIContentCompareStruct > + composite_key_compare, std::less, CIContentCompareStruct > > > >records_t; -uint32_t getSerial(const ComboAddress& master, const DNSName& zone, shared_ptr& sr) +uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr& sr) { vector packet; DNSPacketWriter pw(packet, zone, QType::SOA); @@ -67,14 +69,13 @@ uint32_t getSerial(const ComboAddress& master, const DNSName& zone, shared_ptr(r.first.d_content); - cout<<"Current serial number: "<d_st.serial<d_st.serial; } } return 0; } -vector, vector > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, shared_ptr sr) +vector, vector > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& sr) { vector, vector > > ret; vector packet; @@ -82,7 +83,7 @@ vector, vector > > getIXFRDeltas(const Combo pw.getHeader()->qr=0; pw.getHeader()->rd=0; pw.startRecord(zone, QType::SOA, 3600, QClass::IN, DNSPacketWriter::AUTHORITY); - sr->toPacket(pw); + sr.d_content->toPacket(pw); pw.commit(); @@ -156,20 +157,120 @@ vector, vector > > getIXFRDeltas(const Combo } -uint32_t getHighestSerialFromDir(const std::string& dir) +uint32_t getSerialsFromDir(const std::string& dir) +{ + uint32_t ret=0; + DIR* dirhdl=opendir(dir.c_str()); + if(!dirhdl) + throw runtime_error("Could not open IXFR directory"); + struct dirent *entry; + + while((entry = readdir(dirhdl))) { + uint32_t num = atoi(entry->d_name); + if(std::to_string(num) == entry->d_name) + ret = max(num, ret); + } + closedir(dirhdl); + return ret; +} + +uint32_t getSerialFromRecords(const records_t& records, DNSRecord& soaret) +{ + DNSName root("."); + uint16_t t=QType::SOA; + + auto found = records.equal_range(tie(root, t)); + + for(auto iter = found.first; iter != found.second; ++iter) { + auto soa = std::dynamic_pointer_cast(iter->d_content); + soaret = *iter; + return soa->d_st.serial; + } + return 0; +} + +void writeZoneToDisk(const records_t& records, const DNSName& zone, const std::string& directory) +{ + DNSRecord soa; + int serial = getSerialFromRecords(records, soa); + string fname=directory +"/"+std::to_string(serial); + FILE* fp=fopen((fname+".partial").c_str(), "w"); + records_t soarecord; + soarecord.insert(soa); + + for(const auto& outer : {soarecord, records, soarecord} ) { + for(const auto& r: outer) { + fprintf(fp, "%s\t%d\tIN\t%s\t%s\n", (r.d_name+zone).toString().c_str(), + r.d_ttl, + DNSRecordContent::NumberToType(r.d_type).c_str(), + r.d_content->getZoneRepresentation().c_str()); + } + } + fclose(fp); + rename( (fname+".partial").c_str(), fname.c_str()); +} + +void loadZoneFromDisk(records_t& records, const string& fname, const DNSName& zone) { - return 1445497587; + ZoneParserTNG zpt(fname, zone); + + DNSResourceRecord rr; + bool seenSOA=false; + unsigned int nrecords=0; + while(zpt.get(rr)) { + ++nrecords; + if(rr.qtype.getCode() == QType::CNAME && rr.content.empty()) + rr.content="."; + rr.qname = rr.qname.makeRelative(zone); + + if(rr.qtype.getCode() != QType::SOA || seenSOA==false) + records.insert(DNSRecord(rr)); + if(rr.qtype.getCode() == QType::SOA) { + seenSOA=true; + } + } + cout<<"Parsed "< diff; + + set_difference(before.cbegin(), before.cend(), after.cbegin(), after.cend(), back_inserter(diff), before.value_comp()); + for(const auto& d : diff) { + cout<<'-'<< (d.d_name+zone) <<" IN "<getZoneRepresentation()<getZoneRepresentation()< sr; - uint32_t serial = getSerial(master, zone, sr); - uint32_t ourSerial = getHighestSerialFromDir(argv[4]); - - cout<<"Our serial: "<d_st.serial= ourSerial; - - auto deltas = getIXFRDeltas(master, zone, sr); - cout<<"Got "<(r.d_content)->d_st.serial; - cout<<"Serial before application: "<< oldserial < chunk; + char wheel[]="|/-\\"; + int count=0; + time_t last=0; + while(axfr.getChunk(nop, &chunk)) { + for(auto& dr : chunk) { + dr.d_name.makeUsRelative(zone); + records.insert(dr); + nrecords++; + } + + if(last != time(0)) { + cout << '\r' << wheel[count % (sizeof(wheel)-1)] << ' ' < toremove; - ofstream report(string(argv[4]) +"/delta."+std::to_string(oldserial)); - for(const auto& rr : remove) { - auto range = records.equal_range(tie(rr.d_name, rr.d_type, rr.d_class, rr.d_content)); - if(range.first == range.second) { - cerr<<"Could not find record "< sr; + uint32_t serial = getSerialFromMaster(master, zone, sr); + if(ourSerial == serial) { + cout<<"still up to date, their serial is "<d_st.refresh<<" seconds"<d_st.refresh); + continue; + } + + cout<<"got new serial: "<(rr.d_content)->d_st.serial; + } } - if(rr.d_type == QType::SOA) { - cout<<"Serial to remove: "<< std::dynamic_pointer_cast(rr.d_content)->d_st.serial <getZoneRepresentation()<getZoneRepresentation()<(rr.d_content)->d_st.serial; - cout<<"Serial to ADD: "<< newserial <getZoneRepresentation()<getZoneRepresentation()<getZoneRepresentation().c_str()); + if(stop) { + cerr<<"Had error condition, stopping.."<