From 7cc1c3505f5b4cec17bf2c5ab99dccad41819bbc Mon Sep 17 00:00:00 2001 From: bert hubert Date: Fri, 23 Oct 2015 12:48:14 +0200 Subject: [PATCH] further interim --- pdns/Makefile.am | 2 +- pdns/ixplore.cc | 254 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 237 insertions(+), 19 deletions(-) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index ead56997a..b4bd4e310 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -591,7 +591,7 @@ ixplore_SOURCES = \ sillyrecords.cc \ sstuff.hh \ statbag.cc \ - unix_utility.cc + unix_utility.cc zoneparser-tng.cc ixplore_LDADD = $(MBEDTLS_LIBS) diff --git a/pdns/ixplore.cc b/pdns/ixplore.cc index f4f6cafc7..c1b692392 100644 --- a/pdns/ixplore.cc +++ b/pdns/ixplore.cc @@ -13,9 +13,172 @@ #include #include "dns_random.hh" #include "gss_context.hh" - +#include "zoneparser-tng.hh" +#include +#include +using namespace boost::multi_index; StatBag S; +struct CanonStruct : public std::binary_function +{ + bool operator()(const DNSName&a, const DNSName& b) const + { + return a.canonCompare(b); + } +}; + +struct CIContentCompareStruct +{ + bool operator()(const shared_ptr&a, const shared_ptr& b) const + { + return toLower(a->getZoneRepresentation()) < toLower(b->getZoneRepresentation()); + } +}; + + +typedef multi_index_container< + DNSRecord, + indexed_by< + ordered_non_unique< + composite_key, + member, + member, + member, &DNSRecord::d_content> >, + composite_key_compare, std::less, CIContentCompareStruct > + + > + > + >records_t; + +uint32_t getSerial(const ComboAddress& master, const DNSName& zone, shared_ptr& sr) +{ + vector packet; + DNSPacketWriter pw(packet, zone, QType::SOA); + + Socket s(master.sin4.sin_family, SOCK_DGRAM); + s.connect(master); + string msg((const char*)&packet[0], packet.size()); + s.writen(msg); + + string reply; + s.read(reply); + MOADNSParser mdp(reply); + for(const auto& r: mdp.d_answers) { + if(r.first.d_type == QType::SOA) { + sr = std::dynamic_pointer_cast(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 > > ret; + vector packet; + DNSPacketWriter pw(packet, zone, QType::IXFR); + pw.getHeader()->qr=0; + pw.getHeader()->rd=0; + pw.startRecord(zone, QType::SOA, 3600, QClass::IN, DNSPacketWriter::AUTHORITY); + sr->toPacket(pw); + pw.commit(); + + + uint16_t len=htons(packet.size()); + string msg((const char*)&len, 2); + msg.append((const char*)&packet[0], packet.size()); + + Socket s(master.sin4.sin_family, SOCK_STREAM); + s.connect(master); + s.writen(msg); + + // CURRENT MASTER SOA + // REPEAT: + // SOA WHERE THIS DELTA STARTS + // RECORDS TO REMOVE + // SOA WHERE THIS DELTA GOES + // RECORDS TO ADD + // CURRENT MASTER SOA + shared_ptr masterSOA; + vector records; + for(;;) { + if(s.read((char*)&len, 2)!=2) + break; + len=ntohs(len); + // cout<<"Got chunk of "<(r.first.d_content); + if(!masterSOA) { + masterSOA=sr; + } + else if(sr->d_st.serial == masterSOA->d_st.serial) + goto done; + + } + } + } + done:; + for(unsigned int pos = 1;pos < records.size();) { + auto sr = std::dynamic_pointer_cast(records[pos].d_content); + if(sr->d_st.serial == masterSOA->d_st.serial) + break; + + // cout<<"Got delta going from "<d_st.serial< remove, add; + remove.push_back(records[pos]); // this adds the SOA + for(pos++; pos < records.size() && records[pos].d_type != QType::SOA; ++pos) { + // cout<<"Should remove "<getZoneRepresentation()<(records[pos].d_content); + // cout<<"This delta goes to "<d_st.serial<getZoneRepresentation()<getZoneRepresentation()); + if(b.d_content) + rzrp=toLower(b.d_content->getZoneRepresentation()); + auto atype = a.d_type == QType::SOA ? 0 : a.d_type; + auto btype = b.d_type == QType::SOA ? 0 : b.d_type; + + return tie(atype, a.d_class, lzrp) < + tie(btype, b.d_class, rzrp); +} int main(int argc, char** argv) try @@ -26,9 +189,8 @@ try } reportAllTypes(); - dns_random_init("0123456789abcdef"); - /* goal in life: + /* goal in life: in directory/zone-name we leave files with their name the serial number at startup, retrieve current SOA SERIAL for domain from master server @@ -38,26 +200,82 @@ try Next up, loop this every REFRESH seconds */ DNSName zone(argv[3]); - vector packet; - DNSPacketWriter pw(packet, zone, QType::SOA); + ComboAddress master(argv[1], atoi(argv[2])); - Socket s(master.sin4.sin_family, SOCK_DGRAM); - s.connect(master); - string msg((const char*)&packet[0], packet.size()); - s.writen(msg); + shared_ptr sr; + uint32_t serial = getSerial(master, zone, sr); + uint32_t ourSerial = getHighestSerialFromDir(argv[4]); - string reply; - s.read(reply); - MOADNSParser mdp(reply); - for(const auto& r: mdp.d_answers) { - if(r.first.d_type == QType::SOA) { - auto sr = std::dynamic_pointer_cast(r.first.d_content); - cout<<"Current serial number: "<d_st.serial<d_st.serial= ourSerial; + + auto deltas = getIXFRDeltas(master, zone, sr); + cout<<"Got "<(r.d_content)->d_st.serial; + cout<<"Serial before application: "<< oldserial < 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 "<(rr.d_content)->d_st.serial <getZoneRepresentation()<(rr.d_content)->d_st.serial; + cout<<"Serial to ADD: "<< newserial <getZoneRepresentation()<getZoneRepresentation().c_str()); + } + fclose(fp); + + } + } } catch(PDNSException &e2) { cerr<<"Fatal: "<