From a31fe0607164962fe1956ac71cdb679b70f511fc Mon Sep 17 00:00:00 2001 From: Pavel Boldin Date: Sun, 18 Aug 2013 08:26:42 +0400 Subject: [PATCH] bind-add-zone: add bind zones using pdns_control Add pdns_control for loading new zones without reloading named.conf. Zone is added but not loaded, you should do it manually, by querying something. Beware of cache, it is better to purge it before. --- pdns/backends/bind/bindbackend2.cc | 80 +++++++++++++++++------ pdns/backends/bind/bindbackend2.hh | 6 +- pdns/responsestats.cc | 2 +- regression-tests/add-zone/command | 13 ++++ regression-tests/add-zone/description | 2 + regression-tests/add-zone/expected_result | 42 ++++++++++++ regression-tests/addzone.com | 38 +++++++++++ 7 files changed, 162 insertions(+), 21 deletions(-) create mode 100755 regression-tests/add-zone/command create mode 100644 regression-tests/add-zone/description create mode 100644 regression-tests/add-zone/expected_result create mode 100644 regression-tests/addzone.com diff --git a/pdns/backends/bind/bindbackend2.cc b/pdns/backends/bind/bindbackend2.cc index ccaa2d2fb..36da7ce0d 100644 --- a/pdns/backends/bind/bindbackend2.cc +++ b/pdns/backends/bind/bindbackend2.cc @@ -531,6 +531,36 @@ string Bind2Backend::DLListRejectsHandler(const vector&parts, Utility::p return ret.str(); } +string Bind2Backend::DLAddDomainHandler(const vector&parts, Utility::pid_t ppid) +{ + if(parts.size() < 3) + return "Not enough arguments"; + + string domainname = canonic(parts[1]); + const string &filename = parts[2]; + + if(getState()->name_id_map.count(domainname)) + return "Already loaded"; + + Bind2Backend bb2; + BB2DomainInfo& bbd = bb2.createDomain(domainname, filename); + + bbd.d_filename=filename; + bbd.d_checknow=true; + bbd.d_loaded=true; + bbd.d_lastcheck=0; + bbd.d_status="parsing into memory"; + + { + Lock l(&s_state_lock); + s_state->name_id_map[bbd.d_name]=bbd.d_id; + } + + L<registerFunc("BIND-RELOAD-NOW", &DLReloadNowHandler, "bindbackend: reload domains", ""); dl->registerFunc("BIND-DOMAIN-STATUS", &DLDomStatusHandler, "bindbackend: list status of all domains", "[domains]"); dl->registerFunc("BIND-LIST-REJECTS", &DLListRejectsHandler, "bindbackend: list rejected domains"); + dl->registerFunc("BIND-ADD-ZONE", &DLAddDomainHandler, "bindbackend: add zone", " "); } Bind2Backend::~Bind2Backend() @@ -654,9 +685,9 @@ void Bind2Backend::doEmptyNonTerminals(shared_ptr stage, int id, bool nse void Bind2Backend::loadConfig(string* status) { - // Interference with createSlaveDomain() + // Interference with createDomain() Lock l(&s_state_lock); - + static int domain_id=1; shared_ptr staging = shared_ptr(new State); @@ -1300,11 +1331,32 @@ bool Bind2Backend::superMasterBackend(const string &ip, const string &domain, co return true; } -bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &account) +BB2DomainInfo &Bind2Backend::createDomain(const string &domain, const string &filename) { // Interference with loadConfig(), use locking Lock l(&s_state_lock); + int newid=1; + // Find a free zone id nr. + + if (!s_state->id_zone_map.empty()) { + id_zone_map_t::reverse_iterator i = s_state->id_zone_map.rbegin(); + newid = i->second.d_id + 1; + } + + BB2DomainInfo &bbd = s_state->id_zone_map[newid]; + + bbd.d_id = newid; + bbd.d_records = shared_ptr(new recordstorage_t); + bbd.d_name = domain; + bbd.setCheckInterval(getArgAsNum("check-interval")); + bbd.d_filename = filename; + + return bbd; +} + +bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, const string &account) +{ string filename = getArg("supermaster-destdir")+'/'+domain; L << Logger::Warning << d_logprefix @@ -1326,25 +1378,15 @@ bool Bind2Backend::createSlaveDomain(const string &ip, const string &domain, con c_of << "};" << endl; c_of.close(); - int newid=1; - // Find a free zone id nr. - - if (!s_state->id_zone_map.empty()) { - id_zone_map_t::reverse_iterator i = s_state->id_zone_map.rbegin(); - newid = i->second.d_id + 1; - } - - BB2DomainInfo &bbd = s_state->id_zone_map[newid]; + BB2DomainInfo &bbd = createDomain(canonic(domain), filename); - bbd.d_id = newid; - bbd.d_records = shared_ptr(new recordstorage_t); - bbd.d_name = domain; - bbd.setCheckInterval(getArgAsNum("check-interval")); bbd.d_masters.push_back(ip); - bbd.d_filename = filename; - - s_state->name_id_map[domain] = bbd.d_id; + { + Lock l(&s_state_lock); + s_state->name_id_map[bbd.d_name] = bbd.d_id; + } + return true; } diff --git a/pdns/backends/bind/bindbackend2.hh b/pdns/backends/bind/bindbackend2.hh index 9880dccbd..3a7cfadac 100644 --- a/pdns/backends/bind/bindbackend2.hh +++ b/pdns/backends/bind/bindbackend2.hh @@ -181,7 +181,8 @@ public: // for supermaster support bool superMasterBackend(const string &ip, const string &domain, const vector&nsset, string *account, DNSBackend **db); bool createSlaveDomain(const string &ip, const string &domain, const string &account); - + + private: void setupDNSSEC(); shared_ptr d_dnssecdb; @@ -229,6 +230,8 @@ private: set alsoNotify; //!< this is used to store the also-notify list of interested peers. + BB2DomainInfo& createDomain(const string &domain, const string &filename); + int d_transaction_id; string d_transaction_tmpname; @@ -241,6 +244,7 @@ private: static string DLDomStatusHandler(const vector&parts, Utility::pid_t ppid); static string DLListRejectsHandler(const vector&parts, Utility::pid_t ppid); static string DLReloadNowHandler(const vector&parts, Utility::pid_t ppid); + static string DLAddDomainHandler(const vector&parts, Utility::pid_t ppid); static void fixupAuth(shared_ptr records); static void doEmptyNonTerminals(shared_ptr stage, int id, bool nsec3zone, NSEC3PARAMRecordContent ns3pr); void loadConfig(string *status=0); diff --git a/pdns/responsestats.cc b/pdns/responsestats.cc index 2d9c287a7..92bf8899d 100644 --- a/pdns/responsestats.cc +++ b/pdns/responsestats.cc @@ -52,4 +52,4 @@ map ResponseStats::getSizeResponseCounts() ret[iter->first]=iter->second; } return ret; -} \ No newline at end of file +} diff --git a/regression-tests/add-zone/command b/regression-tests/add-zone/command new file mode 100755 index 000000000..bffa60e2d --- /dev/null +++ b/regression-tests/add-zone/command @@ -0,0 +1,13 @@ +#!/bin/sh +cleandig ns1.addzone.com A +cleandig ns1.test.com A +sleep 2 +../pdns/pdns_control --config-dir=. bind-add-zone addzone.com addzone.com +../pdns/pdns_control --config-dir=. purge addzone.com +sleep 2 +../pdns/pdns_control --config-dir=. bind-add-zone addzone.com addzone.com +sleep 2 +cleandig ns1.addzone.com A +sleep 2 +cleandig ns1.addzone.com A +cleandig ns1.test.com A diff --git a/regression-tests/add-zone/description b/regression-tests/add-zone/description new file mode 100644 index 000000000..863d5dfa4 --- /dev/null +++ b/regression-tests/add-zone/description @@ -0,0 +1,2 @@ +Test whether bind-add-zone is actually adding zone and does not ruin +other zones. diff --git a/regression-tests/add-zone/expected_result b/regression-tests/add-zone/expected_result new file mode 100644 index 000000000..e531b86ce --- /dev/null +++ b/regression-tests/add-zone/expected_result @@ -0,0 +1,42 @@ +1 . IN NS 518400 a.root-servers.net. +1 . IN NS 518400 b.root-servers.net. +1 . IN NS 518400 c.root-servers.net. +1 . IN NS 518400 d.root-servers.net. +1 . IN NS 518400 e.root-servers.net. +1 . IN NS 518400 f.root-servers.net. +1 . IN NS 518400 g.root-servers.net. +1 . IN NS 518400 h.root-servers.net. +1 . IN NS 518400 i.root-servers.net. +1 . IN NS 518400 j.root-servers.net. +1 . IN NS 518400 k.root-servers.net. +1 . IN NS 518400 l.root-servers.net. +1 . IN NS 518400 m.root-servers.net. +2 a.root-servers.net. IN A 3600000 198.41.0.4 +2 b.root-servers.net. IN A 3600000 192.228.79.201 +2 c.root-servers.net. IN A 3600000 192.33.4.12 +2 d.root-servers.net. IN A 3600000 199.7.91.13 +2 e.root-servers.net. IN A 3600000 192.203.230.10 +2 f.root-servers.net. IN A 3600000 192.5.5.241 +2 g.root-servers.net. IN A 3600000 192.112.36.4 +2 h.root-servers.net. IN A 3600000 128.63.2.53 +2 i.root-servers.net. IN A 3600000 192.36.148.17 +2 j.root-servers.net. IN A 3600000 192.58.128.30 +2 k.root-servers.net. IN A 3600000 193.0.14.129 +2 l.root-servers.net. IN A 3600000 198.32.64.12 +2 m.root-servers.net. IN A 3600000 202.12.27.33 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 0, opcode: 0 +Reply to question for qname='ns1.addzone.com.', qtype=A +0 ns1.test.com. IN A 3600 1.1.1.1 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='ns1.test.com.', qtype=A +Loaded zone addzone.com from addzone.com +1 +Already loaded +Rcode: 2, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='ns1.addzone.com.', qtype=A +0 ns1.addzone.com. IN A 3600 1.1.1.5 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='ns1.addzone.com.', qtype=A +0 ns1.test.com. IN A 3600 1.1.1.1 +Rcode: 0, RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='ns1.test.com.', qtype=A diff --git a/regression-tests/addzone.com b/regression-tests/addzone.com new file mode 100644 index 000000000..710bd33db --- /dev/null +++ b/regression-tests/addzone.com @@ -0,0 +1,38 @@ +$TTL 3600 +$ORIGIN addzone.com. +@ IN SOA ns1.addzone.com. ahu.example.com. ( 2005092501 + 8H ; refresh + 2H ; retry + 1W ; expire + 1D ; default_ttl + ) + +@ IN NS ns1 +@ IN NS ns2 +@ IN MX 10 smtp-servers.example.com. +@ IN MX 15 smtp-servers +ns1 IN A 1.1.1.5 +ns2 IN A 2.2.2.2 +www IN CNAME server1 +server1 IN A 1.2.3.4 + IN RP ahu.ds9a.nl. counter +*.test IN CNAME server1 +www.test IN A 4.3.2.1 +sub.test IN NS ns-test.example.net +enum IN NAPTR 100 50 "u" "e2u+sip" "" testuser.domain.com. +counter IN A 1.1.1.5 +_ldap._tcp.dc IN SRV 0 100 389 server2.example.net. +_double._tcp.dc IN SRV 0 100 389 server1 +_double._tcp.dc IN SRV 1 100 389 server1 +_root._tcp.dc IN SRV 0 0 0 . +blah IN NS blah +blah IN A 192.168.6.1 +;images IN URL "http://www.ds9a.nl" +;bert@auto.test.com. IN MBOXFW "bert@ds9a.nl" +very-long-txt IN TXT "A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long!" +within-server IN CNAME outpost.example.com. +_underscore IN TXT "underscores are terrible" +b.c IN A 5.6.7.8 +*.a.b.c IN A 8.7.6.5 +aland IN TXT "\195\133LAND ISLANDS" +hightxt IN TXT "v=spf1 mx ip4:78.46.192.210 –all" -- 2.40.0