From 4db8fd44b90b5ac61498ead4d8d1dae2032d7f8c Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Wed, 10 Jan 2018 13:36:26 +0100 Subject: [PATCH] ixplore: Move defs and functs to header for reuse --- pdns/Makefile.am | 2 + pdns/ixfrdist.cc | 4 ++ pdns/ixfrutils.cc | 146 ++++++++++++++++++++++++++++++++++++++++++++ pdns/ixfrutils.hh | 56 +++++++++++++++++ pdns/ixplore.cc | 152 +--------------------------------------------- 5 files changed, 209 insertions(+), 151 deletions(-) create mode 100644 pdns/ixfrutils.cc create mode 100644 pdns/ixfrutils.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index d497358d6..77051ad47 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -607,6 +607,7 @@ ixfrdist_SOURCES = \ qtype.cc \ rcpgenerator.cc rcpgenerator.hh \ resolver.cc \ + ixfrutils.cc ixfrutils.hh \ ixfr.cc ixfr.hh \ ixfrdist.cc \ sillyrecords.cc \ @@ -654,6 +655,7 @@ ixplore_SOURCES = \ rcpgenerator.cc rcpgenerator.hh \ resolver.cc \ ixfr.cc ixfr.hh \ + ixfrutils.cc ixfrutils.hh \ ixplore.cc \ sillyrecords.cc \ sstuff.hh \ diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index fb59ac0ff..7d796051f 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -44,6 +44,7 @@ #include "resolver.hh" #include #include "ixfr.hh" +#include "ixfrutils.hh" using namespace boost::multi_index; StatBag S; @@ -61,6 +62,9 @@ void usage(po::options_description &desc) { cerr << desc << "\n"; } +void updateThread() { +} + int main(int argc, char** argv) { po::options_description desc("IXFR distribution tool"); desc.add_options() diff --git a/pdns/ixfrutils.cc b/pdns/ixfrutils.cc new file mode 100644 index 000000000..5be193137 --- /dev/null +++ b/pdns/ixfrutils.cc @@ -0,0 +1,146 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include "ixfrutils.hh" +#include "sstuff.hh" +#include "dnssecinfra.hh" +#include "zoneparser-tng.hh" + +uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr& sr, const TSIGTriplet& tt) +{ + vector packet; + DNSPacketWriter pw(packet, zone, QType::SOA); + if(!tt.algo.empty()) { + TSIGRecordContent trc; + trc.d_algoName = tt.algo; + trc.d_time = time(nullptr); + trc.d_fudge = 300; + trc.d_origID=ntohs(pw.getHeader()->id); + trc.d_eRcode=0; + addTSIG(pw, trc, tt.name, tt.secret, "", false); + } + + 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(false, reply); + if(mdp.d_header.rcode) { + throw std::runtime_error("Unable to retrieve SOA serial from master '"+master.toStringWithPort()+"': "+RCode::to_s(mdp.d_header.rcode)); + } + for(const auto& r: mdp.d_answers) { + if(r.first.d_type == QType::SOA) { + sr = std::dynamic_pointer_cast(r.first.d_content); + return sr->d_st.serial; + } + } + return 0; +} + +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"); + if(!fp) + throw runtime_error("Unable to open file '"+fname+".partial' for writing: "+string(strerror(errno))); + + records_t soarecord; + soarecord.insert(soa); + fprintf(fp, "$ORIGIN %s\n", zone.toString().c_str()); + for(const auto& outer : {soarecord, records, soarecord} ) { + for(const auto& r: outer) { + fprintf(fp, "%s\tIN\t%s\t%s\n", + r.d_name.isRoot() ? "@" : r.d_name.toStringNoDot().c_str(), + 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) +{ + 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 "< +#include +#include "dnsparser.hh" +#include "dnsrecords.hh" + +using namespace boost::multi_index; + +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 > + > /* ordered_non_uniquw */ + > /* indexed_by */ +> /* multi_index_container */ records_t; + +uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr& sr, const TSIGTriplet& tt = TSIGTriplet()); +uint32_t getSerialsFromDir(const std::string& dir); +uint32_t getSerialFromRecords(const records_t& records, DNSRecord& soaret); +void writeZoneToDisk(const records_t& records, const DNSName& zone, const std::string& directory); +void loadZoneFromDisk(records_t& records, const string& fname, const DNSName& zone); diff --git a/pdns/ixplore.cc b/pdns/ixplore.cc index 43f8cddcc..b06eaf0f3 100644 --- a/pdns/ixplore.cc +++ b/pdns/ixplore.cc @@ -24,13 +24,8 @@ #endif #include "arguments.hh" #include "base64.hh" -#include -#include -#include "dnsparser.hh" -#include "sstuff.hh" #include "misc.hh" -#include "dnswriter.hh" #include "dnsrecords.hh" #include "statbag.hh" #include "base32.hh" @@ -38,12 +33,11 @@ #include "dns_random.hh" #include "gss_context.hh" -#include "zoneparser-tng.hh" #include #include "resolver.hh" #include #include "ixfr.hh" -using namespace boost::multi_index; +#include "ixfrutils.hh" StatBag S; ArgvMap &arg() @@ -52,150 +46,6 @@ ArgvMap &arg() return theArg; } - -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 > - > /* ordered_non_uniquw */ - > /* indexed_by */ -> /* multi_index_container */ records_t; - -uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr& sr, const TSIGTriplet& tt = TSIGTriplet()) -{ - vector packet; - DNSPacketWriter pw(packet, zone, QType::SOA); - if(!tt.algo.empty()) { - TSIGRecordContent trc; - trc.d_algoName = tt.algo; - trc.d_time = time((time_t*)NULL); - trc.d_fudge = 300; - trc.d_origID=ntohs(pw.getHeader()->id); - trc.d_eRcode=0; - addTSIG(pw, trc, tt.name, tt.secret, "", false); - } - - 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(false, reply); - if(mdp.d_header.rcode) { - throw std::runtime_error("Unable to retrieve SOA serial from master '"+master.toStringWithPort()+"': "+RCode::to_s(mdp.d_header.rcode)); - } - for(const auto& r: mdp.d_answers) { - if(r.first.d_type == QType::SOA) { - sr = std::dynamic_pointer_cast(r.first.d_content); - return sr->d_st.serial; - } - } - return 0; -} - - -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"); - if(!fp) - throw runtime_error("Unable to open file '"+fname+".partial' for writing: "+string(strerror(errno))); - - records_t soarecord; - soarecord.insert(soa); - fprintf(fp, "$ORIGIN %s\n", zone.toString().c_str()); - for(const auto& outer : {soarecord, records, soarecord} ) { - for(const auto& r: outer) { - fprintf(fp, "%s\tIN\t%s\t%s\n", - r.d_name.isRoot() ? "@" : r.d_name.toStringNoDot().c_str(), - 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) -{ - 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 "<