summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorent Le Coz <louiz@louiz.org>2015-07-09 13:54:24 +0200
committerFlorent Le Coz <louiz@louiz.org>2015-07-09 14:35:29 +0200
commit4130f1679d909e90d691d47d07cd0e0d4fbe64e1 (patch)
treec9d4ab6413ef7b2bbde1f117c92bf6ac09d32613
parenta42af9e700bcf54777b53b5d0ca999b3b0c107e9 (diff)
downloadbiboumi-4130f1679d909e90d691d47d07cd0e0d4fbe64e1.tar.gz
biboumi-4130f1679d909e90d691d47d07cd0e0d4fbe64e1.tar.bz2
biboumi-4130f1679d909e90d691d47d07cd0e0d4fbe64e1.tar.xz
biboumi-4130f1679d909e90d691d47d07cd0e0d4fbe64e1.zip
Check for timeouts on the DNS resolution using c-ares
ref #3083
-rw-r--r--louloulibs/network/dns_handler.cpp30
-rw-r--r--louloulibs/network/dns_handler.hpp4
2 files changed, 30 insertions, 4 deletions
diff --git a/louloulibs/network/dns_handler.cpp b/louloulibs/network/dns_handler.cpp
index ec53683..324784b 100644
--- a/louloulibs/network/dns_handler.cpp
+++ b/louloulibs/network/dns_handler.cpp
@@ -6,6 +6,8 @@
#include <network/dns_handler.hpp>
#include <network/poller.hpp>
+#include <utils/timed_events.hpp>
+
#include <algorithm>
#include <stdexcept>
@@ -30,7 +32,13 @@ DNSHandler::DNSHandler()
int ares_error;
if ((ares_error = ::ares_library_init(ARES_LIB_INIT_ALL)) != 0)
throw std::runtime_error("Failed to initialize c-ares lib: "s + ares_strerror(ares_error));
- if ((ares_error = ::ares_init(&this->channel)) != ARES_SUCCESS)
+ struct ares_options options = {};
+ // The default timeout values are way too high
+ options.timeout = 1000;
+ options.tries = 3;
+ if ((ares_error = ::ares_init_options(&this->channel,
+ &options,
+ ARES_OPT_TIMEOUTMS|ARES_OPT_TRIES)) != ARES_SUCCESS)
throw std::runtime_error("Failed to initialize c-ares channel: "s + ares_strerror(ares_error));
}
@@ -99,7 +107,8 @@ void DNSHandler::watch_dns_sockets(std::shared_ptr<Poller>& poller)
{ // If not found, create it because we need to watch it
if (it == this->socket_handlers.end())
{
- this->socket_handlers.emplace_front(std::make_unique<DNSSocketHandler>(poller, i));
+ this->socket_handlers.emplace(this->socket_handlers.begin(),
+ std::make_unique<DNSSocketHandler>(poller, i));
it = this->socket_handlers.begin();
}
poller->add_socket_handler(it->get());
@@ -107,6 +116,23 @@ void DNSHandler::watch_dns_sockets(std::shared_ptr<Poller>& poller)
poller->watch_send_events(it->get());
}
}
+ // Cancel previous timer, if any.
+ TimedEventsManager::instance().cancel("DNS timeout");
+ struct timeval tv;
+ struct timeval* tvp;
+ tvp = ::ares_timeout(this->channel, NULL, &tv);
+ if (tvp)
+ {
+ auto future_time = std::chrono::steady_clock::now() + std::chrono::seconds(tvp->tv_sec) + \
+ std::chrono::microseconds(tvp->tv_usec);
+ TimedEventsManager::instance().add_event(TimedEvent(std::move(future_time),
+ [this]()
+ {
+ for (auto& dns_socket_handler: this->socket_handlers)
+ dns_socket_handler->on_recv();
+ },
+ "DNS timeout"));
+ }
}
#endif /* CARES_FOUND */
diff --git a/louloulibs/network/dns_handler.hpp b/louloulibs/network/dns_handler.hpp
index a515f52..ec35374 100644
--- a/louloulibs/network/dns_handler.hpp
+++ b/louloulibs/network/dns_handler.hpp
@@ -11,7 +11,7 @@ class DNSSocketHandler;
# include <ares.h>
# include <memory>
# include <string>
-# include <list>
+# include <vector>
void on_hostname4_resolved(void* arg, int status, int, struct hostent* hostent);
void on_hostname6_resolved(void* arg, int status, int, struct hostent* hostent);
@@ -49,7 +49,7 @@ private:
* call to ares_fds. DNSSocketHandlers are added to it or removed from it
* in the watch_dns_sockets() method
*/
- std::list<std::unique_ptr<DNSSocketHandler>> socket_handlers;
+ std::vector<std::unique_ptr<DNSSocketHandler>> socket_handlers;
ares_channel channel;
DNSHandler(const DNSHandler&) = delete;