} else {
this->d_url_suffix = "";
}
+ this->timeout = 2;
+ if (options.find("timeout") != options.end()) {
+ this->timeout = boost::lexical_cast<int>(options.find("timeout")->second)/1000;
+ }
}
HTTPConnector::~HTTPConnector() {
// finally add suffix
ss << d_url_suffix;
curl_easy_setopt(d_c, CURLOPT_URL, ss.str().c_str());
-
+
(*slist) = NULL;
// set the correct type of request based on method
if (method == "activateDomainKey" || method == "deactivateDomainKey") {
d_c = curl_easy_init();
d_data = "";
curl_easy_setopt(d_c, CURLOPT_NOSIGNAL, 1);
- curl_easy_setopt(d_c, CURLOPT_TIMEOUT, 2);
+ curl_easy_setopt(d_c, CURLOPT_TIMEOUT, this->timeout);
+
slist = NULL;
// build request
if (coproc != NULL) return;
rapidjson::Value val;
rapidjson::Document init,res;
- coproc = new CoProcess(this->command, 2000);
+ int timeout=2000;
+ if (options.find("timeout") != options.end()) {
+ timeout = boost::lexical_cast<int>(options.find("timeout")->second);
+ }
+ coproc = new CoProcess(this->command, timeout);
init.SetObject();
val = "initialize";
init.AddMember("method",val, init.GetAllocator());
-#!/usr/bin/ruby1.9.1
+#!/usr/bin/ruby
require 'json'
require 'sqlite3'
-#!/usr/bin/ruby1.9.1
+#!/usr/bin/ruby
require "rubygems"
#require "bundler/setup"
require "webrick"
require "../modules/remotebackend/regression-tests/backend"
server = WEBrick::HTTPServer.new(
- Port: 62434,
- BindAddress: "localhost",
+ :Port=>62434,
+ :BindAddress=>"localhost",
# Logger: WEBrick::Log.new("remotebackend-server.log"),
- AccessLog: [ [ File.open("remotebackend-access.log", "w"), WEBrick::AccessLog::COMBINED_LOG_FORMAT ] ]
+ :AccessLog=>[ [ File.open("remotebackend-access.log", "w"), WEBrick::AccessLog::COMBINED_LOG_FORMAT ] ]
)
be = Handler.new("../modules/remotebackend/regression-tests/remote.sqlite3")
-#!/usr/bin/ruby1.9.1
+#!/usr/bin/ruby
require 'json'
require '../modules/remotebackend/regression-tests/backend'
res, log = h.send(method)
end
puts ({:result => res, :log => log}).to_json
- f.puts ({:result => res, :log => log}).to_json
+ f.puts({:result => res, :log => log}).to_json
rescue JSON::ParserError
puts ({:result => false, :log => "Cannot parse input #{line}"}).to_json
next
JSON_ADD_MEMBER(parameters, "qtype", qtype.getName().c_str(), query.GetAllocator());
JSON_ADD_MEMBER(parameters, "qname", qdomain.c_str(), query.GetAllocator());
- if (pkt_p != NULL) {
- JSON_ADD_MEMBER(parameters, "remote", pkt_p->getRemote().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "local", pkt_p->getRemote().c_str(), query.GetAllocator());
- JSON_ADD_MEMBER(parameters, "real-remote", pkt_p->getRealRemote().toString().c_str(), 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());
if (connector->recv(answer) == false)
return true;
- for(rapidjson::Value::ValueIterator iter = answer.Begin(); iter != answer.End(); iter++) {
- meta.push_back(iter->GetString());
+ if (answer.IsArray()) {
+ for(rapidjson::Value::ValueIterator iter = answer.Begin(); iter != answer.End(); iter++) {
+ meta.push_back(iter->GetString());
+ }
+ } else if (answer.IsString()) {
+ meta.push_back(answer.GetString());
}
return true;
{
declare(suffix,"dnssec","Enable dnssec support","no");
declare(suffix,"connection-string","Connection string","");
- declare(suffix,"timeout","Timeout in milliseconds to wait for reply","2000");
}
DNSBackend *make(const std::string &suffix="")
int fd;
std::string path;
bool connected;
+ int timeout;
};
#ifdef REMOTEBACKEND_HTTP
std::string d_url_suffix;
CURL *d_c;
std::string d_data;
+ int timeout;
void json2string(const rapidjson::Value &input, std::string &output);
void requestbuilder(const std::string &method, const rapidjson::Value ¶meters, struct curl_slist **slist);
void addUrlComponent(const rapidjson::Value ¶meters, const char *element, std::stringstream& ss);
L<<Logger::Error<<"Cannot find 'path' option in connection string"<<endl;
throw new AhuException();
}
+ this->timeout = 2000;
+ if (options.find("timeout") != options.end()) {
+ this->timeout = boost::lexical_cast<int>(options.find("timeout")->second);
+ }
this->path = options.find("path")->second;
this->options = options;
this->connected = false;
std::string s_output;
rapidjson::GenericReader<rapidjson::UTF8<> , rapidjson::MemoryPoolAllocator<> > r;
- time_t t0;
+ struct timeval t0,t;
nread = 0;
- t0 = time(NULL);
+ gettimeofday(&t0, NULL);
+ memcpy(&t,&t0,sizeof(t0));
s_output = "";
-
- while(time(NULL) - t0 < 2) { // 2 second timeout
+
+ while((t.tv_sec - t0.tv_sec)*1000 + (t.tv_usec - t0.tv_usec)/1000 < this->timeout) {
std::string temp;
temp.clear();
if (output.HasParseError() == false)
return s_output.size();
}
+ gettimeofday(&t, NULL);
}
return -1;
</para>
<sect2 id="remotebackend-compiling"><title>Compiling</title>
<para>
- Install following libraries for dependencies: libjsoncpp, libcurl. To compile this backend, you need to configure --with-modules="remote pipe", for now.
+ Install following libraries for dependencies: libjsoncpp. To compile this backend, you need to configure --with-modules="remote pipe", for
+ now. If you want to use http connector, you need libcurl and use --enable-remotebackend-http.
</para>
</sect2>
<sect2 id="remotebackend-usage"><title>Usage</title>
<para>
You can pass as many parameters as you want. For unix and pipe backends, these
are passed along to the remote end as initialization. See <xref linkend="remotebackend-api" />.
+ Initialize is not called for http backend.
</para>
<sect3 id="remotebackend-unix"><title>Unix backend</title>
<para>
- parameters: path
+ parameters: path, timeout (default 2000ms)
</para>
<para>
<programlisting>
<sect3 id="remotebackend-pipe"><title>Pipe backend</title>
<para>
- parameters: command
+ parameters: command,timeout (default 2000ms)
</para>
<para>
<programlisting>
-remote-connection-string=unix:command=/path/to/executable
+remote-connection-string=unix:command=/path/to/executable,timeout=2000
</programlisting>
</para>
</sect3>
<sect3 id="remotebackend-HTTP"><title>HTTP backend</title>
<para>
- parameters: url, url-suffix
+ parameters: url, url-suffix, timeout (default 2000)
</para>
<para>
HTTP backend tries to do RESTful requests to your server. See examples.
<para>
URL should not end with /, and url-suffix is optional, but if you define it, it's
up to you to write the ".php" or ".json". Lack of dot causes lack of dot in
- URL.
+ URL. Timeout is divided by 1000 because libcurl only supports seconds, but this is
+ given in milliseconds for consistency with other backends.
</para>
</sect3>
- </sect2>
+ </sect2>
<sect2 id="remotebackend-api"><title>API</title>
<sect3 id="remotebackend-api-queries"><title>Queries</title>
</para>
</sect3>
<sect3 id="remotebackend-api-methods"><title>Methods</title>
+
+<sect4 id="remotebackend-api-methods-initialize"><title>Method: initialize</title>
+<variablelist>
+ <varlistentry>
+ <term>Mandatory:</term>
+ <listitem><para>Yes (except HTTP backend)</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Parameters:</term>
+ <listitem><para>all parameters in connection string</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Reply:</term>
+ <listitem><para>true on success / false on failure</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Description</term>
+ <listitem><para>Called to initialize the backend. This is not called for HTTP backend. You should
+do your initializations here.</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Example JSON/RPC:</term>
+<listitem>
+<para>
+Query:
+<programlisting>
+{"method":"initialize", "parameters":{"command":"/path/to/something", "timeout":"2000", "something":"else"}}
+</programlisting>
+</para>
+<para>
+Response:
+<programlisting>
+{"result":true}
+</programlisting>
+</para>
+</listitem>
+ </varlistentry>
+</variablelist>
+</sect4>
+
<sect4 id="remotebackend-api-methods-lookup"><title>Method: lookup</title>
<variablelist>
<varlistentry>
narrow=$(echo $context | cut -d- -f 4)
testsdir=../modules/remotebackend/regression-tests/
+ # cleanup unbound-host.conf to avoid failures
+ rm -f unbound-host.conf
+
case $remotetype in
http)
connstr="http:url=http://localhost:62434/dns"