#endif
#include "remotebackend.hh"
-
static const char *kBackendId = "[RemoteBackend]";
/**
* we need to do some treatment to the value before
* sending it downwards.
*/
-bool Connector::send(rapidjson::Document &value) {
- return send_message(value);
+bool Connector::send(Json& value) {
+ return send_message(value)>0;
}
-/**
+/**
* Helper for handling receiving of data.
- * Basically what happens here is that we check
+ * Basically what happens here is that we check
* that the receiving happened ok, and extract
- * result. Logging is performed here, too.
+ * result. Logging is performed here, too.
*/
-bool Connector::recv(rapidjson::Document &value) {
+bool Connector::recv(Json& value) {
if (recv_message(value)>0) {
bool rv = true;
// check for error
- if (!value.HasMember("result")) {
- return false;
- }
- if (!value["result"].IsObject() && getBool(value["result"]) == false) {
- rv = false;
- }
- if (value.HasMember("log")) {
- rapidjson::Value& messages = value["log"];
- if (messages.IsArray()) {
- // log em all
- for (rapidjson::Value::ValueIterator iter = messages.Begin(); iter != messages.End(); ++iter)
- L<<Logger::Info<<"[remotebackend]: "<< getString(*iter) <<std::endl;
- } else if (messages.IsNull() == false) { // could be just a value
- L<<Logger::Info<<"[remotebackend]: "<< getString(messages) <<std::endl;
- }
- }
- return rv;
+ if (value["result"] == Json())
+ return false;
+ if (value["result"].is_bool() && boolFromJson(value, "result", false) == false)
+ rv = false;
+ for(const auto& message: value["log"].array_items())
+ L<<Logger::Info<<"[remotebackend]: "<< message.string_value() <<std::endl;
+ return rv;
}
return false;
}
-/**
+/**
* Standard ctor and dtor
*/
RemoteBackend::RemoteBackend(const std::string &suffix)
setArgPrefix("remote"+suffix);
this->d_connstr = getArg("connection-string");
- this->d_result = NULL;
this->d_dnssec = mustDo("dnssec");
this->d_index = -1;
this->d_trxid = 0;
-
+
build();
}
RemoteBackend::~RemoteBackend() {
- if (connector != NULL) {
+ if (connector != NULL) {
delete connector;
}
}
-bool RemoteBackend::send(rapidjson::Document &value) {
+bool RemoteBackend::send(Json& value) {
try {
return connector->send(value);
} catch (PDNSException &ex) {
return false;
}
-bool RemoteBackend::recv(rapidjson::Document &value) {
+bool RemoteBackend::recv(Json& value) {
try {
return connector->recv(value);
} catch (PDNSException &ex) {
}
-/**
+/**
* Builds connector based on options
* Currently supports unix,pipe and http
*/
return -1;
}
-/**
+/**
* The functions here are just remote json stubs that send and receive the method call
- * data is mainly left alone, some defaults are assumed.
+ * data is mainly left alone, some defaults are assumed.
*/
void RemoteBackend::lookup(const QType &qtype, const DNSName& qdomain, DNSPacket *pkt_p, int zoneId) {
- rapidjson::Document query;
- rapidjson::Value parameters;
-
- if (d_index != -1)
+ if (d_index != -1)
throw PDNSException("Attempt to lookup while one running");
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "lookup", query.GetAllocator())
- parameters.SetObject();
- JSON_ADD_MEMBER(parameters, "qtype", qtype.getName().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(parameters, "qname", qdomain, query.GetAllocator());
-
string localIP="0.0.0.0";
string remoteIP="0.0.0.0";
string realRemote="0.0.0.0/0";
+
if (pkt_p) {
localIP=pkt_p->getLocal();
realRemote = pkt_p->getRealRemote().toString();
remoteIP = pkt_p->getRemote();
}
- JSON_ADD_MEMBER(parameters, "remote", remoteIP.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "local", localIP.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "real-remote", realRemote.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "zone-id", zoneId, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
-
- d_result = new rapidjson::Document();
+ Json query = Json::object{
+ { "method", "lookup" },
+ { "parameters", Json::object{
+ { "qtype", qtype.getName() },
+ { "qname", qdomain.toString() },
+ { "remote", remoteIP },
+ { "local", localIP },
+ { "real-remote", realRemote },
+ { "zone-id", zoneId }
+ }}
+ };
- if (this->send(query) == false || this->recv(*d_result) == false) {
- delete d_result;
+ if (this->send(query) == false || this->recv(d_result) == false) {
return;
}
// OK. we have result parameters in result. do not process empty result.
- if ((*d_result)["result"].IsArray() == false || (*d_result)["result"].Size() < 1) {
- delete d_result;
- return;
- }
+ if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1)
+ return;
d_index = 0;
}
bool RemoteBackend::list(const DNSName& target, int domain_id, bool include_disabled) {
- rapidjson::Document query;
- rapidjson::Value parameters;
-
if (d_index != -1)
throw PDNSException("Attempt to lookup while one running");
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "list", query.GetAllocator());
- query["method"] = "list";
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "zonename", target, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "domain-id", domain_id, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
-
- d_result = new rapidjson::Document();
+ Json query = Json::object{
+ { "method", "list" },
+ { "parameters", Json::object{
+ { "zonename", target.toString() },
+ { "domain-id", domain_id },
+ { "include-disabled", include_disabled }
+ }}
+ };
- if (this->send(query) == false || this->recv(*d_result) == false) {
- delete d_result;
+ if (this->send(query) == false || this->recv(d_result) == false)
+ return false;
+ if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1)
return false;
- }
- if ((*d_result)["result"].IsArray() == false || (*d_result)["result"].Size() < 1) {
- delete d_result;
- return false;
- }
d_index = 0;
return true;
bool RemoteBackend::get(DNSResourceRecord &rr) {
if (d_index == -1) return false;
- rapidjson::Value value;
-
- value = "";
- rr.qtype = getString(JSON_GET((*d_result)["result"][d_index], "qtype", value));
- rr.qname = DNSName(getString(JSON_GET((*d_result)["result"][d_index], "qname", value)));
+ rr.qtype = stringFromJson(d_result["result"][d_index], "qtype");
+ rr.qname = DNSName(stringFromJson(d_result["result"][d_index], "qname"));
rr.qclass = QClass::IN;
- rr.content = getString(JSON_GET((*d_result)["result"][d_index], "content",value));
- value = -1;
- rr.ttl = getInt(JSON_GET((*d_result)["result"][d_index], "ttl",value));
- rr.domain_id = getInt(JSON_GET((*d_result)["result"][d_index],"domain_id",value));
- value = 1;
- if (d_dnssec)
- rr.auth = getInt(JSON_GET((*d_result)["result"][d_index],"auth", value));
+ rr.content = stringFromJson(d_result["result"][d_index], "content");
+ rr.ttl = intFromJson(d_result["result"][d_index], "ttl", 0);
+ rr.domain_id = intFromJson(d_result["result"][d_index], "domain_id", -1);
+ if (d_dnssec)
+ rr.auth = intFromJson(d_result["result"][d_index], "auth", 1);
else
rr.auth = 1;
- value = 0;
- rr.scopeMask = getInt(JSON_GET((*d_result)["result"][d_index],"scopeMask", value));
-
+ rr.scopeMask = intFromJson(d_result["result"][d_index], "scopeMask", 0);
d_index++;
-
- // id index is out of bounds, we know the results end here.
- if (d_index == static_cast<int>((*d_result)["result"].Size())) {
- delete d_result;
- d_result = NULL;
+
+ // id index is out of bounds, we know the results end here.
+ if (d_index == static_cast<int>(d_result["result"].array_items().size())) {
+ d_result = Json();
d_index = -1;
}
return true;
}
bool RemoteBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, DNSName& unhashed, std::string& before, std::string& after) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getBeforeAndAfterNamesAbsolute", query.GetAllocator());
-
- parameters.SetObject();
- JSON_ADD_MEMBER(parameters, "id", id, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "qname", qname.c_str(), query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "getBeforeAndAfterNamesAbsolute" },
+ { "parameters", Json::object {
+ { "id", Json(static_cast<double>(id)) },
+ { "qname", qname }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- unhashed = DNSName(getString(answer["result"]["unhashed"]));
- before = getString(answer["result"]["before"]);
- after = getString(answer["result"]["after"]);
-
+ unhashed = DNSName(stringFromJson(answer["result"], "unhashed"));
+ before = "";
+ after = "";
+ if (answer["result"]["before"] != Json())
+ before = stringFromJson(answer["result"], "before");
+ if (answer["result"]["after"] != Json())
+ after = stringFromJson(answer["result"], "after");
+
return true;
}
bool RemoteBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getAllDomainMetadata", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "getAllDomainMetadata" },
+ { "parameters", Json::object {
+ { "name", name.toString() }
+ }}
+ };
if (this->send(query) == false)
return false;
meta.clear();
+ Json answer;
// not mandatory to implement
if (this->recv(answer) == false)
return true;
- if (answer["result"].IsObject()) {
- for (rapidjson::Value::MemberIterator kind = answer["result"].MemberBegin(); kind != answer["result"].MemberEnd(); kind++) {
- if (kind->value.IsArray()) {
- for(rapidjson::Value::ValueIterator content = kind->value.Begin(); content != kind->value.End(); content++)
- meta[kind->name.GetString()].push_back(getString(*content));
- } else {
- meta[kind->name.GetString()].push_back(getString(kind->value));
- }
+ for(const auto& pair: answer["result"].object_items()) {
+ if (pair.second.is_array()) {
+ for(const auto& val: pair.second.array_items())
+ meta[pair.first].push_back(asString(val));
+ } else {
+ meta[pair.first].push_back(asString(pair.second));
}
}
}
bool RemoteBackend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getDomainMetadata", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "kind", kind.c_str(), query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "getDomainMetadata" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "kind", kind }
+ }}
+ };
if (this->send(query) == false)
return false;
meta.clear();
+ Json answer;
// not mandatory to implement
if (this->recv(answer) == false)
return true;
- if (answer["result"].IsArray()) {
- for(rapidjson::Value::ValueIterator iter = answer["result"].Begin(); iter != answer["result"].End(); iter++) {
- meta.push_back(getString(*iter));
- }
- } else if (answer["result"].IsString()) {
- meta.push_back(answer["result"].GetString());
+ if (answer["result"].is_array()) {
+ for(const auto& row: answer["result"].array_items())
+ meta.push_back(row.string_value());
+ } else if (answer["result"].is_string()) {
+ meta.push_back(answer["result"].string_value());
}
return true;
}
bool RemoteBackend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters,val;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "setDomainMetadata", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "kind", kind.c_str(), query.GetAllocator());
- val.SetArray();
- for(const auto& value: meta) {
- val.PushBack(value.c_str(), query.GetAllocator());
- }
- parameters.AddMember("value", val, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "setDomainMetadata" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "kind", kind },
+ { "value", meta }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- return getBool(answer["result"]);
+ return boolFromJson(answer, "result", false);
}
bool RemoteBackend::getDomainKeys(const DNSName& name, unsigned int kind, std::vector<DNSBackend::KeyData>& keys) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getDomainKeys", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "kind", kind, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "getDomainKeys" },
+ { "parameters", Json::object{
+ { "name", name.toString() },
+ { "kind", static_cast<int>(kind) }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
keys.clear();
- for(rapidjson::Value::ValueIterator iter = answer["result"].Begin(); iter != answer["result"].End(); iter++) {
- DNSBackend::KeyData key;
- if (!(*iter).IsObject())
- throw PDNSException("Invalid reply to getDomainKeys, expected array of hashes, got something else");
-
- if (!(*iter).HasMember("id") ||
- !(*iter).HasMember("flags") ||
- !(*iter).HasMember("active") ||
- !(*iter).HasMember("content"))
- throw PDNSException("Invalid reply to getDomainKeys, missing keys in key hash");
-
- key.id = getUInt((*iter)["id"]);
- key.flags = getUInt((*iter)["flags"]);
- key.active = getBool((*iter)["active"]);
- key.content = getString((*iter)["content"]);
- keys.push_back(key);
+ for(const auto& jsonKey: answer["result"].array_items()) {
+ DNSBackend::KeyData key;
+ key.id = intFromJson(jsonKey, "id");
+ key.flags = intFromJson(jsonKey, "flags");
+ key.active = boolFromJson(jsonKey, "active");
+ key.content = stringFromJson(jsonKey, "content");
+ keys.push_back(key);
}
return true;
}
-bool RemoteBackend::removeDomainKey(const DNSName& name, unsigned int id) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
+bool RemoteBackend::removeDomainKey(const DNSName& name, unsigned int id) {
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "removeDomainKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "id", id, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "removeDomainKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "id", static_cast<int>(id) }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
}
int RemoteBackend::addDomainKey(const DNSName& name, const KeyData& key) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters,jkey;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "addDomainKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- jkey.SetObject();
- JSON_ADD_MEMBER(jkey, "flags", key.flags, query.GetAllocator());
- JSON_ADD_MEMBER(jkey, "active", key.active, query.GetAllocator());
- JSON_ADD_MEMBER(jkey, "content", key.content.c_str(), query.GetAllocator());
- parameters.AddMember("key", jkey, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "addDomainKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "key", Json::object {
+ { "flags", static_cast<int>(key.flags) },
+ { "active", key.active },
+ { "content", key.content }
+ }}
+ }}
+ };
+
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- return getInt(answer["result"]);
+ return intFromJson(answer,"result",0);
}
bool RemoteBackend::activateDomainKey(const DNSName& name, unsigned int id) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "activateDomainKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "id", id, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "activateDomainKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "id", static_cast<int>(id) }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
}
bool RemoteBackend::deactivateDomainKey(const DNSName& name, unsigned int id) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "deactivateDomainKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "id", id, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "deactivateDomainKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "id", static_cast<int>(id) }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
}
bool RemoteBackend::getTSIGKey(const DNSName& name, DNSName* algorithm, std::string* content) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getTSIGKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "getTSIGKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() }
+ }}
+ };
+
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- if (!answer["result"].IsObject() ||
- !answer["result"].HasMember("algorithm") ||
- !answer["result"].HasMember("content"))
- throw PDNSException("Invalid response to getTSIGKey, missing field(s)");
+ (*algorithm) = DNSName(stringFromJson(answer["result"], "algorithm"));
+ (*content) = stringFromJson(answer["result"], "content");
- (*algorithm) = DNSName(getString(answer["result"]["algorithm"]));
- content->assign(getString(answer["result"]["content"]));
-
return true;
}
bool RemoteBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const std::string& content) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "setTSIGKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(parameters, "algorithm", algorithm, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "content", content.c_str(), query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+
+ Json query = Json::object{
+ { "method", "setTSIGKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "algorithm", algorithm.toString() },
+ { "content", content }
+ }}
+ };
+
+ Json answer;
if (connector->send(query) == false || connector->recv(answer) == false)
return false;
}
bool RemoteBackend::deleteTSIGKey(const DNSName& name) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "deleteTSIGKey", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "deleteTSIGKey" },
+ { "parameters", Json::object {
+ { "name", name.toString() }
+ }}
+ };
+
+ Json answer;
if (connector->send(query) == false || connector->recv(answer) == false)
return false;
}
bool RemoteBackend::getTSIGKeys(std::vector<struct TSIGKey>& keys) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
// no point doing dnssec if it's not supported
if (d_dnssec == false) return false;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getTSIGKeys", query.GetAllocator());
- parameters.SetObject();
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "getTSIGKeys" },
+ { "parameters", Json::object {
+ }}
+ };
+ Json answer;
if (connector->send(query) == false || connector->recv(answer) == false)
return false;
- // expect array
- if (answer["result"].IsArray()) {
- for(rapidjson::Value::ValueIterator iter = answer["result"].Begin(); iter != answer["result"].End(); iter++) {
- struct TSIGKey key;
- rapidjson::Value value;
- value = "";
- key.name = DNSName(getString(JSON_GET((*iter), "name", value)));
- key.algorithm = DNSName(getString(JSON_GET((*iter), "algorithm", value)));
- key.key = getString(JSON_GET((*iter), "content", value));
-
- if (key.name.empty() ||
- key.algorithm.empty() ||
- key.key.empty())
- throw PDNSException("Invalid reply for getTSIGKeys query");
-
- keys.push_back(key);
- }
+ for(const auto& jsonKey: answer["result"].array_items()) {
+ struct TSIGKey key;
+ key.name = DNSName(stringFromJson(jsonKey, "name"));
+ key.algorithm = DNSName(stringFromJson(jsonKey, "algorithm"));
+ key.key = stringFromJson(jsonKey, "content");
+ keys.push_back(key);
}
return true;
}
bool RemoteBackend::getDomainInfo(const DNSName& domain, DomainInfo &di) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
- rapidjson::Value value;
- std::string kind;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "getDomainInfo", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", domain, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ if (domain.empty()) return false;
+ Json query = Json::object{
+ { "method", "getDomainInfo" },
+ { "parameters", Json::object {
+ { "name", domain.toString() }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- // make sure we got zone & kind
- if (!answer["result"].IsObject() || !answer["result"].HasMember("zone")) {
- L<<Logger::Error<<kBackendId<<" Missing zone in getDomainInfo return value"<<endl;
- throw PDNSException();
- }
- value = -1;
- // parse return value. we need at least zone,serial,kind
- di.id = getInt(JSON_GET(answer["result"],"id",value));
- di.zone = DNSName(getString(answer["result"]["zone"]));
-
- if (answer["result"].HasMember("masters") && answer["result"]["masters"].IsArray()) {
- rapidjson::Value& value = answer["result"]["masters"];
- for(rapidjson::Value::ValueIterator i = value.Begin(); i != value.End(); i++) {
- di.masters.push_back(getString(*i));
- }
+ di.id = intFromJson(answer["result"], "id", -1);
+ di.zone = DNSName(stringFromJson(answer["result"], "zone"));
+ for(const auto& master: answer["result"]["masters"].array_items())
+ di.masters.push_back(master.string_value());
+
+ di.notified_serial = static_cast<unsigned int>(doubleFromJson(answer["result"], "notified_serial", -1));
+ di.serial = static_cast<unsigned int>(doubleFromJson(answer["result"], "serial", 0));
+ di.last_check = static_cast<time_t>(doubleFromJson(answer["result"], "last_check", 0));
+
+ string kind = "";
+ if (answer["result"]["kind"].is_string()) {
+ kind = stringFromJson(answer["result"], "kind");
}
- di.notified_serial = getInt(JSON_GET(answer["result"], "notified_serial", value));
- value = 0;
- di.serial = getInt(JSON_GET(answer["result"],"serial", value));
- di.last_check = getInt(JSON_GET(answer["result"],"last_check", value));
- value = "native";
- kind = getString(JSON_GET(answer["result"], "kind", value));
if (kind == "master") {
di.kind = DomainInfo::Master;
} else if (kind == "slave") {
}
void RemoteBackend::setNotified(uint32_t id, uint32_t serial) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "setNotified", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER(parameters, "id", id, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "serial", serial, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
-
+ Json query = Json::object{
+ { "method", "setNotified" },
+ { "parameters", Json::object {
+ { "id", static_cast<double>(id) },
+ { "serial", static_cast<double>(serial) }
+ }}
+ };
+
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false) {
L<<Logger::Error<<kBackendId<<" Failed to execute RPC for RemoteBackend::setNotified("<<id<<","<<serial<<")"<<endl;
}
bool RemoteBackend::isMaster(const DNSName& name, const string &ip)
{
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "isMaster", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER_DNSNAME(parameters, "name", name, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "ip", ip.c_str(), query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "isMaster" },
+ { "parameters", Json::object {
+ { "name", name.toString() },
+ { "ip", ip }
+ }}
+ };
+
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
bool RemoteBackend::superMasterBackend(const string &ip, const DNSName& domain, const vector<DNSResourceRecord>&nsset, string* nameserver, 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_DNSNAME(parameters, "domain", domain, query.GetAllocator());
- rrset.SetArray();
- rrset.Reserve(nsset.size(), query.GetAllocator());
- for(rapidjson::SizeType i = 0; i < nsset.size(); i++) {
- rapidjson::Value rr;
- rr.SetObject();
- JSON_ADD_MEMBER(rr, "qtype", nsset[i].qtype.getName().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(rr, "qname", nsset[i].qname, 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, "auth", nsset[i].auth, query.GetAllocator());
- rrset.PushBack(rr, query.GetAllocator());
+ Json::array rrset;
+
+ for(const auto& ns: nsset) {
+ rrset.push_back(Json::object{
+ { "qtype", ns.qtype.getName() },
+ { "qname", ns.qname.toString() },
+ { "qclass", QClass::IN },
+ { "content", ns.content },
+ { "ttl", static_cast<int>(ns.ttl) },
+ { "auth", ns.auth }
+ });
}
- parameters.AddMember("nsset", rrset, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+
+ Json query = Json::object{
+ { "method", "superMasterBackend" },
+ { "parameters", Json::object {
+ { "ip", ip },
+ { "domain", domain.toString() },
+ { "nsset", rrset }
+ }}
+ };
*ddb = 0;
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
*ddb = this;
// we allow simple true as well...
- if (answer["result"].IsObject()) {
- if (answer["result"].HasMember("account"))
- *account = getString(answer["result"]["account"]);
- if (answer["result"].HasMember("nameserver"))
- *nameserver = getString(answer["result"]["nameserver"]);
+ if (answer["result"].is_object()) {
+ *account = stringFromJson(answer["result"], "account");
+ *nameserver = stringFromJson(answer["result"], "nameserver");
}
+
return true;
}
bool RemoteBackend::createSlaveDomain(const string &ip, const DNSName& domain, const string& nameserver, 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_DNSNAME(parameters, "domain", domain, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "nameserver", nameserver.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "account", account.c_str(), query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "createSlaveDomain" },
+ { "parameters", Json::object {
+ { "ip", ip },
+ { "domain", domain.toString() },
+ { "nameserver", nameserver },
+ { "account", account },
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
return true;
}
bool RemoteBackend::replaceRRSet(uint32_t domain_id, const DNSName& 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_DNSNAME(parameters, "qname", qname, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "qtype", qtype.getName().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
-
- rj_rrset.SetArray();
- rj_rrset.Reserve(rrset.size(), query.GetAllocator());
-
- for(rapidjson::SizeType i = 0; i < rrset.size(); i++) {
- rapidjson::Value rr;
- rr.SetObject();
- JSON_ADD_MEMBER(rr, "qtype", rrset[i].qtype.getName().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(rr, "qname", rrset[i].qname, 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, "auth", rrset[i].auth, query.GetAllocator());
- rj_rrset.PushBack(rr, query.GetAllocator());
+ Json::array json_rrset;
+ for(const auto& rr: rrset) {
+ json_rrset.push_back(Json::object{
+ { "qtype", rr.qtype.getName() },
+ { "qname", rr.qname.toString() },
+ { "qclass", QClass::IN },
+ { "content", rr.content },
+ { "ttl", static_cast<int>(rr.ttl) },
+ { "auth", rr.auth }
+ });
}
- parameters.AddMember("rrset", rj_rrset, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "replaceRRSet" },
+ { "parameters", Json::object {
+ { "domain_id", static_cast<double>(domain_id) },
+ { "qname", qname.toString() },
+ { "qtype", qtype.getName() },
+ { "trxid", static_cast<double>(d_trxid) },
+ { "rrset", json_rrset }
+ }}
+ };
+
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
}
bool RemoteBackend::feedRecord(const DNSResourceRecord &rr, string *ordername) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters,rj_rr;
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "feedRecord", query.GetAllocator());
- parameters.SetObject();
- rj_rr.SetObject();
- JSON_ADD_MEMBER(rj_rr, "qtype", rr.qtype.getName().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(rj_rr, "qname", rr.qname, query.GetAllocator());
- JSON_ADD_MEMBER(rj_rr, "qclass", QClass::IN, query.GetAllocator());
- JSON_ADD_MEMBER(rj_rr, "content", rr.content.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(rj_rr, "ttl", rr.ttl, query.GetAllocator());
- JSON_ADD_MEMBER(rj_rr, "auth", rr.auth, query.GetAllocator());
- parameters.AddMember("rr", rj_rr, query.GetAllocator());
-
- JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
-
- if (ordername) {
- JSON_ADD_MEMBER(parameters, "ordername", ordername->c_str(), query.GetAllocator());
- }
-
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "feedRecord" },
+ { "parameters", Json::object{
+ { "rr", Json::object{
+ { "qtype", rr.qtype.getName() },
+ { "qname", rr.qname.toString() },
+ { "qclass", QClass::IN },
+ { "content", rr.content },
+ { "ttl", static_cast<int>(rr.ttl) },
+ { "auth", rr.auth },
+ { "ordername", (ordername==nullptr?Json():*ordername) }
+ }},
+ { "trxid", static_cast<double>(d_trxid) },
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
return true; // XXX FIXME this API should not return 'true' I think -ahu
}
bool RemoteBackend::feedEnts(int domain_id, map<DNSName,bool>& 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());
- JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
- nts.SetArray();
- for(const auto& t: nonterm) {
- rapidjson::Value value(t.first.toString().c_str(), query.GetAllocator());
- nts.PushBack(value, query.GetAllocator());
- }
- parameters.AddMember("nonterm", nts, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json::array nts;
+
+ for(const auto& t: nonterm)
+ nts.push_back(Json::object{
+ { "nonterm", t.first.toString() },
+ { "auth", t.second }
+ });
+
+ Json query = Json::object{
+ { "method", "feedEnts" },
+ { "parameters", Json::object{
+ { "domain_id", domain_id },
+ { "trxid", static_cast<double>(d_trxid) },
+ { "nonterm", nts }
+ }},
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- return true;
+ return true;
}
bool RemoteBackend::feedEnts3(int domain_id, const DNSName& domain, map<DNSName,bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, 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_DNSNAME(parameters, "domain", domain, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "times", ns3prc.d_iterations, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "salt", ns3prc.d_salt.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "narrow", narrow, query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "trxid", d_trxid, query.GetAllocator());
-
- nts.SetArray();
- for(const auto& t: nonterm) {
- rapidjson::Value value(t.first.toString().c_str(), query.GetAllocator());
- nts.PushBack(value, query.GetAllocator());
- }
- parameters.AddMember("nonterm", nts, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json::array nts;
+
+ for(const auto& t: nonterm)
+ nts.push_back(Json::object{
+ { "nonterm", t.first.toString() },
+ { "auth", t.second }
+ });
+
+ Json query = Json::object{
+ { "method", "feedEnts3" },
+ { "parameters", Json::object{
+ { "domain_id", domain_id },
+ { "domain", domain.toString() },
+ { "times", ns3prc.d_iterations },
+ { "salt", ns3prc.d_salt },
+ { "narrow", narrow },
+ { "trxid", static_cast<double>(d_trxid) },
+ { "nonterm", nts }
+ }},
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
return true;
}
bool RemoteBackend::startTransaction(const DNSName& 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_DNSNAME(parameters, "domain", domain, 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());
+ Json query = Json::object{
+ { "method", "startTransaction" },
+ { "parameters", Json::object{
+ { "domain", domain.toString() },
+ { "domain_id", domain_id },
+ { "trxid", static_cast<double>(d_trxid) }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false) {
d_trxid = -1;
return false;
return true;
}
-bool RemoteBackend::commitTransaction() {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
+bool RemoteBackend::commitTransaction() {
+ if (d_trxid == -1) return false;
- 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());
+ Json query = Json::object{
+ { "method", "commitTransaction" },
+ { "parameters", Json::object{
+ { "trxid", static_cast<double>(d_trxid) }
+ }}
+ };
d_trxid = -1;
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
return true;
}
-bool RemoteBackend::abortTransaction() {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
+bool RemoteBackend::abortTransaction() {
+ if (d_trxid == -1) return false;
- 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());
+ Json query = Json::object{
+ { "method", "abortTransaction" },
+ { "parameters", Json::object{
+ { "trxid", static_cast<double>(d_trxid) }
+ }}
+ };
d_trxid = -1;
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
return true;
}
bool RemoteBackend::calculateSOASerial(const DNSName& 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_DNSNAME(parameters, "domain", domain, query.GetAllocator());
- soadata.SetObject();
- JSON_ADD_MEMBER_DNSNAME(soadata, "qname", sd.qname, query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(soadata, "nameserver", sd.nameserver, query.GetAllocator());
- JSON_ADD_MEMBER_DNSNAME(soadata, "hostmaster", sd.hostmaster, 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());
+ Json query = Json::object{
+ { "method", "calculateSOASerial" },
+ { "parameters", Json::object{
+ { "domain", domain.toString() },
+ { "sd", Json::object{
+ { "qname", sd.qname.toString() },
+ { "nameserver", sd.nameserver.toString() },
+ { "hostmaster", sd.hostmaster.toString() },
+ { "ttl", static_cast<int>(sd.ttl) },
+ { "serial", static_cast<double>(sd.serial) },
+ { "refresh", static_cast<int>(sd.refresh) },
+ { "retry", static_cast<int>(sd.retry) },
+ { "expire", static_cast<int>(sd.expire) },
+ { "default_ttl", static_cast<int>(sd.default_ttl) },
+ { "domain_id", static_cast<int>(sd.domain_id) },
+ { "scopeMask", sd.scopeMask }
+ }}
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return false;
- serial = getInt64(answer["result"]);
+ serial = static_cast<unsigned int>(doubleFromJson(answer,"result"));
return true;
}
string RemoteBackend::directBackendCmd(const string& querystr) {
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "directBackendCmd", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER(parameters, "query", querystr.c_str(), query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
+ Json query = Json::object{
+ { "method", "directBackendCmd" },
+ { "parameters", Json::object{
+ { "query", querystr }
+ }}
+ };
+ Json answer;
if (this->send(query) == false || this->recv(answer) == false)
return "backend command failed";
- return getString(answer["result"]);
+ return asString(answer["result"]);
}
bool RemoteBackend::searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result)
{
- rapidjson::Document query,answer;
- rapidjson::Value parameters;
-
- query.SetObject();
- JSON_ADD_MEMBER(query, "method", "searchRecords", query.GetAllocator());
- parameters.SetObject();
- JSON_ADD_MEMBER(parameters, "pattern", pattern.c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "maxResults", maxResults, query.GetAllocator());
- query.AddMember("parameters", parameters, query.GetAllocator());
-
- if (this->send(query) == false || this->recv(answer) == false)
- return false;
+ Json query = Json::object{
+ { "method", "searchRecords" },
+ { "parameters", Json::object{
+ { "pattern", pattern },
+ { "maxResults", maxResults }
+ }}
+ };
+
+ Json answer;
+ if (this->send(query) == false || this->recv(answer) == false)
+ return false;
- if (answer["result"].IsArray() == false)
- return false;
+ if (answer["result"].is_array() == false)
+ return false;
- for(rapidjson::SizeType i = 0; i < answer["result"].Size(); i++) {
- DNSResourceRecord rr;
- rapidjson::Value value;
- value = "";
- rr.qtype = getString(JSON_GET((*d_result)["result"][d_index], "qtype", value));
- rr.qname = DNSName(getString(JSON_GET((*d_result)["result"][d_index], "qname", value)));
- rr.qclass = QClass::IN;
- rr.content = getString(JSON_GET((*d_result)["result"][d_index], "content",value));
- value = -1;
- rr.ttl = getInt(JSON_GET((*d_result)["result"][d_index], "ttl",value));
- rr.domain_id = getInt(JSON_GET((*d_result)["result"][d_index],"domain_id",value));
- value = 1;
- if (d_dnssec)
- rr.auth = getInt(JSON_GET((*d_result)["result"][d_index],"auth", value));
- else
- rr.auth = 1;
- value = 0;
- rr.scopeMask = getInt(JSON_GET((*d_result)["result"][d_index],"scopeMask", value));
- result.push_back(rr);
+ for(const auto& row: answer["result"].array_items()) {
+ DNSResourceRecord rr;
+ rr.qtype = stringFromJson(row, "qtype");
+ rr.qname = DNSName(stringFromJson(row, "qname"));
+ rr.qclass = QClass::IN;
+ rr.content = stringFromJson(row, "content");
+ rr.ttl = intFromJson(row, "ttl", 0);
+ rr.domain_id = intFromJson(row, "domain_id", -1);
+ if (d_dnssec)
+ rr.auth = intFromJson(row, "auth", 1);
+ else
+ rr.auth = 1;
+ rr.scopeMask = intFromJson(row, "scopeMask", 0);
+ result.push_back(rr);
}
return true;
return false;
}
-
-// some rapidjson helpers
-bool RemoteBackend::getBool(rapidjson::Value &value) {
- if (value.IsNull()) return false;
- if (value.IsBool()) return value.GetBool();
- if (value.IsInt()) return value.GetInt() != 0; // 0 = false, non-zero true
- if (value.IsDouble()) return value.GetDouble() != 0; // 0 = false, non-zero true
- if (value.IsString()) { // accepts 0, 1, false, true
- std::string tmp = value.GetString();
- if (boost::iequals(tmp, "1") || boost::iequals(tmp, "true")) return true;
- if (boost::iequals(tmp, "0") || boost::iequals(tmp, "false")) return false;
- }
- std::cerr << value.GetType() << endl;
- throw PDNSException("Cannot convert rapidjson value into boolean");
-}
-
-bool Connector::getBool(rapidjson::Value &value) {
- if (value.IsNull()) return false;
- if (value.IsBool()) return value.GetBool();
- if (value.IsInt()) return value.GetInt() != 0; // 0 = false, non-zero true
- if (value.IsDouble()) return value.GetDouble() != 0; // 0 = false, non-zero true
- if (value.IsString()) { // accepts 0, 1, false, true
- std::string tmp = value.GetString();
- if (boost::iequals(tmp, "1") || boost::iequals(tmp, "true")) return true;
- if (boost::iequals(tmp, "0") || boost::iequals(tmp, "false")) return false;
- }
-
- // this is specific for Connector!
- return true;
-}
-
-std::string Connector::getString(rapidjson::Value &value) {
- if (value.IsString()) return value.GetString();
- if (value.IsBool()) return (value.GetBool() ? "true" : "false");
- if (value.IsInt64()) return std::to_string(value.GetInt64());
- if (value.IsInt()) return std::to_string(value.GetInt());
- if (value.IsDouble()) return std::to_string(value.GetDouble());
- return "(unpresentable value)"; // cannot convert into presentation format
-}
-
-int RemoteBackend::getInt(rapidjson::Value &value) {
- if (value.IsInt()) return value.GetInt();
- if (value.IsBool()) return (value.GetBool() ? 1 : 0);
- if (value.IsUint()) return static_cast<int>(value.GetUint());
- if (value.IsDouble()) return static_cast<int>(value.GetDouble());
- if (value.IsString()) { // accepts 0, 1, false, true
- std::string tmp = value.GetString();
- return std::stoi(tmp);
- }
- throw PDNSException("Cannot convert rapidjson value into integer");
-}
-
-unsigned int RemoteBackend::getUInt(rapidjson::Value &value) {
- if (value.IsUint()) return value.GetUint();
- if (value.IsBool()) return (value.GetBool() ? 1 : 0);
- if (value.IsInt()) return static_cast<unsigned int>(value.GetInt());
- if (value.IsDouble()) return static_cast<unsigned int>(value.GetDouble());
- if (value.IsString()) { // accepts 0, 1, false, true
- std::string tmp = value.GetString();
- return pdns_stou(tmp);
- }
- throw PDNSException("Cannot convert rapidjson value into integer");
-}
-
-int64_t RemoteBackend::getInt64(rapidjson::Value &value) {
- if (value.IsInt64()) return value.GetInt64();
- if (value.IsBool()) return (value.GetBool() ? 1 : 0);
- if (value.IsInt()) return value.GetInt();
- if (value.IsDouble()) return static_cast<int64_t>(value.GetDouble());
- if (value.IsString()) { // accepts 0, 1, false, true
- std::string tmp = value.GetString();
- return std::stoll(tmp);
- }
- throw PDNSException("Cannot convert rapidjson value into integer");
-}
-
-std::string RemoteBackend::getString(rapidjson::Value &value) {
- if (value.IsNull()) return "";
- if (value.IsString()) return value.GetString();
- if (value.IsBool()) return (value.GetBool() ? "true" : "false");
- if (value.IsInt64()) return std::to_string(value.GetInt64());
- if (value.IsInt()) return std::to_string(value.GetInt());
- if (value.IsDouble()) return std::to_string(value.GetDouble());
- throw PDNSException("Cannot convert rapidjson value into std::string");
-}
-
-double RemoteBackend::getDouble(rapidjson::Value &value) {
- if (value.IsDouble()) return value.GetDouble();
- if (value.IsBool()) return (value.GetBool() ? 1.0L : 0.0L);
- if (value.IsInt64()) return static_cast<double>(value.GetInt64());
- if (value.IsInt()) return static_cast<double>(value.GetInt());
- if (value.IsString()) { // accepts 0, 1, false, true
- std::string tmp = value.GetString();
- return std::stod(tmp);
- }
- throw PDNSException("Cannot convert rapidjson value into double");
-}
-
DNSBackend *RemoteBackend::maker()
{
try {