]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Fixed bug where setNotified did not add parameters to query
authorAki Tuomi <cmouse@desteem.org>
Sat, 1 Jun 2013 18:28:47 +0000 (21:28 +0300)
committerAki Tuomi <cmouse@desteem.org>
Wed, 5 Jun 2013 05:03:27 +0000 (08:03 +0300)
Support for superMaster, slaving and soa calculations

superMasterBackend implementation

createSlaveDomain implementation

Removed references to GSQLBackend

replaceRRSet implementation

feedEnts, feedEnts3 implementation and few AddMember additions where forgotten

Rest of the methods

Final touches to remotebackend

Partial support for new slave methods

Added transaction ID for start/abort/commiTransaction

modules/remotebackend/httpconnector.cc
modules/remotebackend/remotebackend.cc
modules/remotebackend/remotebackend.hh

index af49cd4c67baf42c8a30131f591c2eb4d39ec644..8706d2a8fc7530b8fc2e910757bc23ed0879e984 100644 (file)
@@ -66,6 +66,8 @@ void HTTPConnector::requestbuilder(const std::string &method, const rapidjson::V
     std::stringstream ss;
     std::string sparam;
     char *tmpstr;
+    size_t k=0;
+    k=k;
 
     // special names are qname, name, zonename, kind, others go to headers
 
@@ -106,6 +108,76 @@ void HTTPConnector::requestbuilder(const std::string &method, const rapidjson::V
         curl_easy_setopt(d_c, CURLOPT_COPYPOSTFIELDS, postfields);
         curl_free(tmpstr);
         delete postfields;
+    } else if (method == "superMasterBackend") {
+        std::stringstream ss2;
+        addUrlComponent(parameters, "ip", ss);
+        addUrlComponent(parameters, "domain", ss);
+        // then we need to serialize rrset payload into POST
+        for(rapidjson::Value::ConstValueIterator itr = parameters["nsset"].Begin(), k=0; itr != parameters["nsset"].End(); itr++, k++) {
+           for (rapidjson::Value::ConstMemberIterator itr2 = itr->MemberBegin(); itr2 != itr->MemberEnd(); itr2++) {
+              ss2 << "nsset[" << k << "][" << itr2->name.GetString() << "]=";
+              if (itr2->value.IsUint()) {
+                 ss2 << itr2->value.GetUint();
+              } else if (itr2->value.IsInt()) {
+                 ss2 << itr2->value.GetInt();
+              } else if (itr2->value.IsBool()) {
+                 ss2 << (itr2->value.GetBool() ? 1 : 0);
+              } else if (itr2->value.IsString()) {
+                 tmpstr = curl_easy_escape(d_c, itr2->value.GetString(), 0);
+                 ss2 << tmpstr;
+                 curl_free(tmpstr);
+              }
+           }
+        }
+        // then give it to curl
+        std::string out = ss2.str();
+        curl_easy_setopt(d_c, CURLOPT_POSTFIELDSIZE, out.size());
+        curl_easy_setopt(d_c, CURLOPT_COPYPOSTFIELDS, out.c_str());
+    } else if (method == "createSlaveDomain") {
+        addUrlComponent(parameters, "ip", ss);
+        addUrlComponent(parameters, "domain", ss);
+        addUrlComponent(parameters, "account", ss);
+    } else if (method == "replaceRRSet") {
+        std::stringstream ss2;
+        for(rapidjson::Value::ConstValueIterator itr = parameters["nsset"].Begin(), k=0; itr != parameters["nsset"].End(); itr++, k++) {
+           for (rapidjson::Value::ConstMemberIterator itr2 = itr->MemberBegin(); itr2 != itr->MemberEnd(); itr2++) {
+              ss2 << "rrset[" << k << "][" << itr2->name.GetString() << "]=";
+              if (itr2->value.IsUint()) {
+                 ss2 << itr2->value.GetUint();
+              } else if (itr2->value.IsInt()) {
+                 ss2 << itr2->value.GetInt();
+              } else if (itr2->value.IsBool()) {
+                 ss2 << (itr2->value.GetBool() ? 1 : 0);
+              } else if (itr2->value.IsString()) {
+                 tmpstr = curl_easy_escape(d_c, itr2->value.GetString(), 0);
+                 ss2 << tmpstr;
+                 curl_free(tmpstr);
+              }
+           }
+        }
+        // then give it to curl
+        std::string out = ss2.str();
+        curl_easy_setopt(d_c, CURLOPT_POSTFIELDSIZE, out.size());
+        curl_easy_setopt(d_c, CURLOPT_COPYPOSTFIELDS, out.c_str());
+    } else if (method == "feedRecord") {
+        std::stringstream ss2;
+        for (rapidjson::Value::ConstMemberIterator itr2 = parameters["rr"].MemberBegin(); itr2 != parameters["rr"].MemberEnd(); itr2++) {
+           ss2 << "rr[" << itr2->name.GetString() << "]=";
+           if (itr2->value.IsUint()) {
+              ss2 << itr2->value.GetUint();
+           } else if (itr2->value.IsInt()) {
+              ss2 << itr2->value.GetInt();
+           } else if (itr2->value.IsBool()) {
+              ss2 << (itr2->value.GetBool() ? 1 : 0);
+           } else if (itr2->value.IsString()) {
+              tmpstr = curl_easy_escape(d_c, itr2->value.GetString(), 0);
+              ss2 << tmpstr;
+              curl_free(tmpstr);
+           }
+        }
+        std::string out = ss2.str();
+        curl_easy_setopt(d_c, CURLOPT_POSTFIELDSIZE, out.size());
+        curl_easy_setopt(d_c, CURLOPT_COPYPOSTFIELDS, out.c_str());
     } else if (method == "setDomainMetadata") {
         int n=0;
         // copy all metadata values into post
index 0e9d132dce80dcf85d2a2a06019d5c8b06ea32be..c6b58bc1ce5efff5c990702e42f3c15540b7ff9f 100644 (file)
@@ -43,12 +43,16 @@ bool Connector::recv(rapidjson::Document &value) {
     return false;
 }
 
+/** 
+ * Standard ctor and dtor
+ */
 RemoteBackend::RemoteBackend(const std::string &suffix)
 {
       setArgPrefix("remote"+suffix);
       build(getArg("connection-string"));
       this->d_dnssec = mustDo("dnssec");
       this->d_index = -1;
+      this->d_trxid = 0;
 }
 
 RemoteBackend::~RemoteBackend() {
@@ -351,7 +355,7 @@ bool RemoteBackend::removeDomainKey(const string& name, unsigned int id) {
    if (connector->send(query) == false || connector->recv(answer) == false)
      return false;
 
-   return answer["result"].GetBool();
+   return true;
 }
 
 int RemoteBackend::addDomainKey(const string& name, const KeyData& key) {
@@ -394,7 +398,7 @@ bool RemoteBackend::activateDomainKey(const string& name, unsigned int id) {
    if (connector->send(query) == false || connector->recv(answer) == false)
      return false;
 
-   return answer["result"].GetBool();
+   return true;
 }
 
 bool RemoteBackend::deactivateDomainKey(const string& name, unsigned int id) {
@@ -414,7 +418,7 @@ bool RemoteBackend::deactivateDomainKey(const string& name, unsigned int id) {
    if (connector->send(query) == false || connector->recv(answer) == false)
      return false;
 
-   return answer["result"].GetBool();
+   return true;
 }
 
 bool RemoteBackend::doesDNSSEC() {
@@ -500,12 +504,257 @@ void RemoteBackend::setNotified(uint32_t id, uint32_t serial) {
    parameters.SetObject();
    JSON_ADD_MEMBER(parameters, "id", id, query.GetAllocator());
    JSON_ADD_MEMBER(parameters, "serial", id, query.GetAllocator());
-
+   query.AddMember("parameters", parameters, query.GetAllocator());
    if (connector->send(query) == false || connector->recv(answer) == false) {
       L<<Logger::Error<<kBackendId<<"Failed to execute RPC for RemoteBackend::setNotified("<<id<<","<<serial<<")"<<endl;
    }
 }
 
+bool RemoteBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **ddb) 
+{
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   rapidjson::Value rrset;
+
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "superMasterBackend", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "ip", ip.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "domain", domain.c_str(), query.GetAllocator());
+   rrset.SetArray();
+   rrset.Reserve(nsset.size(), query.GetAllocator());
+   for(rapidjson::SizeType i = 0; i < nsset.size(); i++) {
+      rapidjson::Value &rr = rrset[i]; 
+      rr.SetObject();
+      JSON_ADD_MEMBER(rr, "qtype", nsset[i].qtype.getName().c_str(), query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "qname", nsset[i].qname.c_str(), query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "qclass", QClass::IN, query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "content", nsset[i].content.c_str(), query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "ttl", nsset[i].ttl, query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "priority", nsset[i].priority, query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "auth", nsset[i].auth, query.GetAllocator());
+   }
+   parameters.AddMember("nsset", rrset, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+
+   // we are the backend
+   *ddb = this;
+   
+   // we allow simple true as well...
+   if (answer["result"].IsObject() && answer["result"].HasMember("account")) 
+     *account = answer["result"]["account"].GetString();
+
+   return true;
+}
+
+bool RemoteBackend::createSlaveDomain(const string &ip, const string &domain, const string &account) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "createSlaveDomain", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "ip", ip.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "domain", domain.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "account", account.c_str(), query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+   return true;
+}
+
+bool RemoteBackend::replaceRRSet(uint32_t domain_id, const string& qname, const QType& qtype, const vector<DNSResourceRecord>& rrset) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   rapidjson::Value rj_rrset;
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "replaceRRSet", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "domain_id", domain_id, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "qname", qname.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "qtype", qtype.getName().c_str(), query.GetAllocator());
+   rj_rrset.SetArray();
+   rj_rrset.Reserve(rrset.size(), query.GetAllocator());
+
+   for(rapidjson::SizeType i = 0; i < rrset.size(); i++) {
+      rapidjson::Value &rr = rj_rrset[i];
+      rr.SetObject();
+      JSON_ADD_MEMBER(rr, "qtype", rrset[i].qtype.getName().c_str(), query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "qname", rrset[i].qname.c_str(), query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "qclass", QClass::IN, query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "content", rrset[i].content.c_str(), query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "ttl", rrset[i].ttl, query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "priority", rrset[i].priority, query.GetAllocator());
+      JSON_ADD_MEMBER(rr, "auth", rrset[i].auth, query.GetAllocator());
+   }
+   parameters.AddMember("rrset", rj_rrset, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+
+   return true;
+}
+
+bool RemoteBackend::feedRecord(const DNSResourceRecord &rr, string *ordername) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "feedRecord", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "qtype", rr.qtype.getName().c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "qname", rr.qname.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "qclass", QClass::IN, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "content", rr.content.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "ttl", rr.ttl, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "priority", rr.priority, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "auth", rr.auth, query.GetAllocator());
+   if (ordername) {
+     JSON_ADD_MEMBER(parameters, "ordername", ordername->c_str(), query.GetAllocator());
+   }
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+   return true; // XXX FIXME this API should not return 'true' I think -ahu
+}
+
+bool RemoteBackend::feedEnts(int domain_id, set<string>& nonterm) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   rapidjson::Value nts;
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "feedEnts", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "domain_id", domain_id, query.GetAllocator());
+   nts.SetArray();
+   BOOST_FOREACH(const string &t, nonterm) {
+      nts.PushBack(t.c_str(), query.GetAllocator());
+   }
+   parameters.AddMember("nonterm", nts, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+   return true; 
+}
+
+bool RemoteBackend::feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   rapidjson::Value nts;
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "feedEnts3", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "domain_id", domain_id, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "domain", domain.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "times", times, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "salt", salt.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "narrow", narrow, query.GetAllocator());
+
+   nts.SetArray();
+   BOOST_FOREACH(const string &t, nonterm) {
+      nts.PushBack(t.c_str(), query.GetAllocator());
+   }
+   parameters.AddMember("nonterm", nts, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+   return true;
+}
+
+bool RemoteBackend::startTransaction(const string &domain, int domain_id) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   this->d_trxid = time((time_t*)NULL);
+
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "startTransaction", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "domain", domain.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "domain_id", domain_id, query.GetAllocator());
+   JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
+
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false) {
+     d_trxid = -1;
+     return false;
+   }
+   return true;
+
+}
+bool RemoteBackend::commitTransaction() { 
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "abortTransaction", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   d_trxid = -1;
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+   return true;
+}
+
+bool RemoteBackend::abortTransaction() { 
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "commitTransaction", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   d_trxid = -1;
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+   return true;
+}
+
+bool RemoteBackend::calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial) {
+   rapidjson::Document query,answer;
+   rapidjson::Value parameters;
+   rapidjson::Value soadata;
+
+   query.SetObject();
+   JSON_ADD_MEMBER(query, "method", "calculateSOASerial", query.GetAllocator());
+   parameters.SetObject();
+   JSON_ADD_MEMBER(parameters, "domain", domain.c_str(), query.GetAllocator());
+   soadata.SetObject();
+   JSON_ADD_MEMBER(soadata, "qname", sd.qname.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "nameserver", sd.nameserver.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "hostmaster", sd.hostmaster.c_str(), query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "ttl", sd.ttl, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "serial", sd.serial, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "refresh", sd.refresh, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "retry", sd.retry, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "expire", sd.expire, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "default_ttl", sd.default_ttl, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "domain_id", sd.domain_id, query.GetAllocator());
+   JSON_ADD_MEMBER(soadata, "scopeMask", sd.scopeMask, query.GetAllocator());
+   parameters.AddMember("sd", soadata, query.GetAllocator());
+   query.AddMember("parameters", parameters, query.GetAllocator());
+
+   if (connector->send(query) == false || connector->recv(answer) == false)
+     return false;
+
+   if (answer["result"].IsInt64() == false)
+     return false;
+
+   serial = answer["result"].GetInt64();
+   return true;
+}
+
 DNSBackend *RemoteBackend::maker()
 {
    try {
index 7bc02b71e398bad1636aa0027b6a89da4ce70169..8984aa089f982421c1d5520bdc65d6b752eb1c23 100644 (file)
@@ -111,6 +111,16 @@ class RemoteBackend : public DNSBackend
   virtual bool getDomainInfo(const string&, DomainInfo&);
   virtual void setNotified(uint32_t id, uint32_t serial);
   virtual bool doesDNSSEC();
+  virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **ddb);
+  virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account);
+  virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset);
+  virtual bool feedRecord(const DNSResourceRecord &r, string *ordername);
+  virtual bool feedEnts(int domain_id, set<string>& nonterm);
+  virtual bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow);
+  virtual bool startTransaction(const string &domain, int domain_id);
+  virtual bool commitTransaction();
+  virtual bool abortTransaction();
+  virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
 
   static DNSBackend *maker();
 
@@ -119,6 +129,7 @@ class RemoteBackend : public DNSBackend
     Connector *connector;
     bool d_dnssec;
     rapidjson::Document *d_result;
-    int d_index; 
+    int d_index;
+    time_t d_trxid;
 };
 #endif