From: Pieter Lexis Date: Wed, 24 Jan 2018 15:26:02 +0000 (+0100) Subject: ixfrdist: clean up downloaded zones X-Git-Tag: dnsdist-1.3.0~111^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=37499e32e58deeeda61d040e07ccaaa397db5af9;p=thirdparty%2Fpdns.git ixfrdist: clean up downloaded zones --- diff --git a/docs/manpages/ixfrdist.1.rst b/docs/manpages/ixfrdist.1.rst index 5539950f48..4f19d920d6 100644 --- a/docs/manpages/ixfrdist.1.rst +++ b/docs/manpages/ixfrdist.1.rst @@ -32,6 +32,8 @@ Options 127.0.0.1:5300 by default. --work-dir Path to a directory where the AXFR data are saved. By default, this is the current working directory. +--keep Keep at most *NUM* versions of any zone. + By default, 20 versions are kept. See also -------- diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 83fba33d44..a6bcb686f4 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include "ixfr.hh" #include "ixfrutils.hh" #include "resolver.hh" @@ -70,9 +71,21 @@ bool g_debug = false; bool g_exiting = false; +#define KEEP_DEFAULT 20 +uint16_t g_keep = KEEP_DEFAULT; + void handleSignal(int signum) { if (g_verbose) { - cerr<<"[INFO] Got "< zoneVersions; + struct dirent *d; + while ((d = readdir(dp)) != nullptr) { + if(!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) { + continue; + } + zoneVersions.push_back(std::stoi(d->d_name)); + } + closedir(dp); + if (g_verbose) { + cerr<<"[INFO] Found "< guard(g_soas_mutex); + for (auto iter = zoneVersions.cbegin(); iter != zoneVersions.cend() - g_keep; ++iter) { + string fname = dir + "/" + std::to_string(*iter); + if (g_debug) { + cerr<<"[DEBUG] Removing "< lastCheck; @@ -99,6 +163,10 @@ void updateThread() { g_soas[domain] = soa; } } + if (soa != nullptr) { + // Initial cleanup + cleanUpDomain(domain); + } } catch (runtime_error &e) { // Most likely, the directory does not exist. cerr<<"[INFO] "< guard(g_soas_mutex); g_soas[domain] = soa; } + + // Now clean up the directory + cleanUpDomain(domain); } /* for (const auto &domain : domains) */ sleep(1); } /* while (true) */ @@ -342,11 +414,6 @@ bool makeIXFRPackets(const MOADNSParser& mdp, const shared_ptr // updateThread. uint32_t newSerial = g_soas[mdp.d_qname]->d_st.serial; - // Let's see if we have the old zone - // TODO lock the zone from clean up (when implemented) - string oldZoneFname = dir + "/" + std::to_string(clientSOA->d_st.serial); - string newZoneFname = dir + "/" + std::to_string(newSerial); - if (rfc1982LessThan(newSerial, clientSOA->d_st.serial)){ /* RFC 1995 Section 2 * If an IXFR query with the same or newer version number than that of @@ -361,31 +428,39 @@ bool makeIXFRPackets(const MOADNSParser& mdp, const shared_ptr return ret; } - // Check if we can actually make an IXFR - struct stat s; - if (stat(oldZoneFname.c_str(), &s) == -1) { - if (errno == ENOENT) { - if (g_verbose) { - cerr<<"[INFO] IXFR for "<d_st.serial<<", sending out AXFR"<d_st.serial); + string newZoneFname = dir + "/" + std::to_string(newSerial); + records_t oldRecords, newRecords; + shared_ptr newSOA; + { + // Make sure the update thread does not clean this in front of our feet + std::lock_guard guard(g_soas_mutex); + + // Check if we can actually make an IXFR + struct stat s; + if (stat(oldZoneFname.c_str(), &s) == -1) { + if (errno == ENOENT) { + if (g_verbose) { + cerr<<"[INFO] IXFR for "<d_st.serial<<", sending out AXFR"< newSOA; - loadSOAFromDisk(mdp.d_qname, newZoneFname, newSOA); + loadSOAFromDisk(mdp.d_qname, newZoneFname, newSOA); - if (newSOA == nullptr) { - // :( - cerr<<"[WARNING] Could not retrieve SOA record from "<>(), "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") + ("keep", po::value()->default_value(KEEP_DEFAULT), "Number of old zone versions to retain") ; po::options_description alloptions; po::options_description hidden("hidden options"); @@ -639,6 +715,7 @@ int main(int argc, char** argv) { if (g_vm.count("debug") > 0) { g_debug = true; } + } catch (po::error &e) { cerr<<"[ERROR] "<(); + } + vector listen_addresses = {ComboAddress("127.0.0.1:53")}; if (g_vm.count("listen-address") > 0) {