From: Pieter Lexis Date: Wed, 10 Jan 2018 16:15:06 +0000 (+0100) Subject: ixfrdist: first implementation of the update thread X-Git-Tag: dnsdist-1.3.0~111^2~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38e6a9ee48505f3428e660990584ba0a18e30d99;p=pdns ixfrdist: first implementation of the update thread --- diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 8de866c31..74bf3882d 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -23,8 +23,11 @@ #include "config.h" #endif #include +#include #include "ixfr.hh" #include "ixfrutils.hh" +#include "resolver.hh" +#include "dns_random.hh" /* BEGIN Needed because of deeper dependencies */ #include "arguments.hh" @@ -42,20 +45,110 @@ using namespace boost::multi_index; namespace po = boost::program_options; po::variables_map g_vm; +string g_workdir; +ComboAddress g_master; +bool g_verbose = false; void usage(po::options_description &desc) { cerr << "Usage: ixfrdist [OPTION]... DOMAIN [DOMAIN]..."< &domains) { + std::map serials; + std::map lastCheck; + + // Initialize the serials we have + for (const auto &domain : domains) { + lastCheck[domain] = 0; + string dir = g_workdir + "/" + domain.toString(); + try { + serials[domain] = getSerialsFromDir(dir); + } catch (runtime_error &e) { + // Most likely, the directory does not exist. + cerr<<"[INFO] "< sr; + try { + auto newSerial = getSerialFromMaster(g_master, domain, sr); // TODO TSIG + if (g_verbose) { + cerr<<"[INFO] Got SOA Serial: "<< newSerial<<", had Serial: "< chunk; + records_t records; + while(axfr.getChunk(nop, &chunk)) { + for(auto& dr : chunk) { + if(dr.d_type == QType::TSIG) + continue; + dr.d_name.makeUsRelative(domain); + records.insert(dr); + nrecords++; + } + } + if (g_verbose) { + cerr<<"[INFO] Done! Received "<>(), "IP Address(es) to listen on") ("server-address", po::value()->default_value("127.0.0.1:5300"), "server address") ("work-dir", po::value()->default_value("."), "Directory for storing AXFR and IXFR data") @@ -82,6 +175,10 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; } + if (g_vm.count("verbose")) { + g_verbose = true; + } + bool had_error = false; vector listen_addresses = {ComboAddress("127.0.0.1:53")}; @@ -99,7 +196,7 @@ int main(int argc, char** argv) { } try { - ComboAddress serverAddress = ComboAddress(g_vm["server-address"].as(), 53); + g_master = ComboAddress(g_vm["server-address"].as(), 53); } catch(PDNSException &e) { cerr<<"[Error] server-address '"<()<<"' is not an IP address: "<(); + if (had_error) { // We have already sent the errors to stderr, just die return EXIT_FAILURE; } + + // It all starts here + // Init the things we need + reportAllTypes(); + dns_random_init("0123456789abcdef"); + + // Updater thread (TODO: actually thread it :)) + updateThread(domains); } diff --git a/pdns/ixfrutils.cc b/pdns/ixfrutils.cc index 5be193137..d21e107a1 100644 --- a/pdns/ixfrutils.cc +++ b/pdns/ixfrutils.cc @@ -21,10 +21,12 @@ */ #include +#include #include "ixfrutils.hh" #include "sstuff.hh" #include "dnssecinfra.hh" #include "zoneparser-tng.hh" +#include "dnsparser.hh" uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr& sr, const TSIGTriplet& tt) { @@ -53,8 +55,10 @@ uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, sh } 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; + sr = getRR(r.first); + if(sr != nullptr) { + return sr->d_st.serial; + } } } return 0; @@ -65,7 +69,7 @@ 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"); + throw runtime_error("Could not open IXFR directory '" + dir + "': " + strerror(errno)); struct dirent *entry; while((entry = readdir(dirhdl))) {