qtype.cc \
rcpgenerator.cc rcpgenerator.hh \
resolver.cc \
+ ixfrutils.cc ixfrutils.hh \
ixfr.cc ixfr.hh \
ixfrdist.cc \
sillyrecords.cc \
rcpgenerator.cc rcpgenerator.hh \
resolver.cc \
ixfr.cc ixfr.hh \
+ ixfrutils.cc ixfrutils.hh \
ixplore.cc \
sillyrecords.cc \
sstuff.hh \
#include "resolver.hh"
#include <fstream>
#include "ixfr.hh"
+#include "ixfrutils.hh"
using namespace boost::multi_index;
StatBag S;
cerr << desc << "\n";
}
+void updateThread() {
+}
+
int main(int argc, char** argv) {
po::options_description desc("IXFR distribution tool");
desc.add_options()
--- /dev/null
+/*
+ * 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 <dirent.h>
+#include "ixfrutils.hh"
+#include "sstuff.hh"
+#include "dnssecinfra.hh"
+#include "zoneparser-tng.hh"
+
+uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& sr, const TSIGTriplet& tt)
+{
+ vector<uint8_t> 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<SOARecordContent>(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<SOARecordContent>(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 "<<nrecords<<" records"<<endl;
+ if(rr.qtype.getCode() == QType::SOA && seenSOA) {
+ cout<<"Zone was complete (SOA at end)"<<endl;
+ }
+ else {
+ records.clear();
+ throw runtime_error("Zone not complete!");
+ }
+}
--- /dev/null
+/*
+ * 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 <sys/types.h>
+#include <boost/multi_index_container.hpp>
+#include "dnsparser.hh"
+#include "dnsrecords.hh"
+
+using namespace boost::multi_index;
+
+struct CIContentCompareStruct
+{
+ bool operator()(const shared_ptr<DNSRecordContent>&a, const shared_ptr<DNSRecordContent>& b) const
+ {
+ return toLower(a->getZoneRepresentation()) < toLower(b->getZoneRepresentation());
+ }
+};
+
+
+typedef multi_index_container <
+ DNSRecord,
+ indexed_by<
+ ordered_non_unique<
+ composite_key<DNSRecord,
+ member<DNSRecord, DNSName, &DNSRecord::d_name>,
+ member<DNSRecord, uint16_t, &DNSRecord::d_type>,
+ member<DNSRecord, uint16_t, &DNSRecord::d_class>,
+ member<DNSRecord, shared_ptr<DNSRecordContent>, &DNSRecord::d_content> >,
+ composite_key_compare<CanonDNSNameCompare, std::less<uint16_t>, std::less<uint16_t>, CIContentCompareStruct >
+ > /* ordered_non_uniquw */
+ > /* indexed_by */
+> /* multi_index_container */ records_t;
+
+uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& 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);
#endif
#include "arguments.hh"
#include "base64.hh"
-#include <sys/types.h>
-#include <dirent.h>
-#include "dnsparser.hh"
-#include "sstuff.hh"
#include "misc.hh"
-#include "dnswriter.hh"
#include "dnsrecords.hh"
#include "statbag.hh"
#include "base32.hh"
#include "dns_random.hh"
#include "gss_context.hh"
-#include "zoneparser-tng.hh"
#include <boost/multi_index_container.hpp>
#include "resolver.hh"
#include <fstream>
#include "ixfr.hh"
-using namespace boost::multi_index;
+#include "ixfrutils.hh"
StatBag S;
ArgvMap &arg()
return theArg;
}
-
-struct CIContentCompareStruct
-{
- bool operator()(const shared_ptr<DNSRecordContent>&a, const shared_ptr<DNSRecordContent>& b) const
- {
- return toLower(a->getZoneRepresentation()) < toLower(b->getZoneRepresentation());
- }
-};
-
-
-typedef multi_index_container <
- DNSRecord,
- indexed_by<
- ordered_non_unique<
- composite_key<DNSRecord,
- member<DNSRecord, DNSName, &DNSRecord::d_name>,
- member<DNSRecord, uint16_t, &DNSRecord::d_type>,
- member<DNSRecord, uint16_t, &DNSRecord::d_class>,
- member<DNSRecord, shared_ptr<DNSRecordContent>, &DNSRecord::d_content> >,
- composite_key_compare<CanonDNSNameCompare, std::less<uint16_t>, std::less<uint16_t>, CIContentCompareStruct >
- > /* ordered_non_uniquw */
- > /* indexed_by */
-> /* multi_index_container */ records_t;
-
-uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& sr, const TSIGTriplet& tt = TSIGTriplet())
-{
- vector<uint8_t> 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<SOARecordContent>(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<SOARecordContent>(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 "<<nrecords<<" records"<<endl;
- if(rr.qtype.getCode() == QType::SOA && seenSOA) {
- cout<<"Zone was complete (SOA at end)"<<endl;
- }
- else {
- records.clear();
- throw runtime_error("Zone not complete!");
- }
-}
-
void usage() {
cerr<<"Syntax: ixplore diff ZONE BEFORE_FILE AFTER_FILE"<<endl;
cerr<<"Syntax: ixplore track IP-ADDRESS PORT ZONE DIRECTORY [TSIGKEY TSIGALGO TSIGSECRET]"<<endl;