summaryrefslogtreecommitdiff
path: root/louloulibs/network/dns_handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'louloulibs/network/dns_handler.cpp')
-rw-r--r--louloulibs/network/dns_handler.cpp125
1 files changed, 21 insertions, 104 deletions
diff --git a/louloulibs/network/dns_handler.cpp b/louloulibs/network/dns_handler.cpp
index b1807b5..ad0ad38 100644
--- a/louloulibs/network/dns_handler.cpp
+++ b/louloulibs/network/dns_handler.cpp
@@ -1,5 +1,5 @@
#include <louloulibs.h>
-#ifdef CARES_FOUND
+#ifdef UDNS_FOUND
#include <network/dns_socket_handler.hpp>
#include <network/dns_handler.hpp>
@@ -7,123 +7,40 @@
#include <utils/timed_events.hpp>
-#include <algorithm>
+#include <udns.h>
-DNSHandler DNSHandler::instance;
+#include <cstring>
+
+class Resolver;
using namespace std::string_literals;
-DNSHandler::DNSHandler():
- socket_handlers{},
- channel{nullptr}
-{
- 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));
- 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));
-}
-ares_channel& DNSHandler::get_channel()
-{
- return this->channel;
-}
+std::unique_ptr<DNSSocketHandler> DNSHandler::socket_handler{};
-void DNSHandler::destroy()
+DNSHandler::DNSHandler(std::shared_ptr<Poller> poller)
{
- this->remove_all_sockets_from_poller();
- this->socket_handlers.clear();
- ::ares_destroy(this->channel);
- ::ares_library_cleanup();
+ dns_init(nullptr, 0);
+ const auto socket = dns_open(nullptr);
+ if (socket == -1)
+ throw std::runtime_error("Failed to initialize udns socket: "s + strerror(errno));
+
+ DNSHandler::socket_handler = std::make_unique<DNSSocketHandler>(poller, socket);
}
-void DNSHandler::gethostbyname(const std::string& name, ares_host_callback callback,
- void* data, int family)
+void DNSHandler::destroy()
{
- ::ares_gethostbyname(this->channel, name.data(), family,
- callback, data);
+ DNSHandler::socket_handler.reset(nullptr);
+ dns_close(nullptr);
}
-void DNSHandler::watch_dns_sockets(std::shared_ptr<Poller>& poller)
+void DNSHandler::watch()
{
- fd_set readers;
- fd_set writers;
-
- FD_ZERO(&readers);
- FD_ZERO(&writers);
-
- int ndfs = ::ares_fds(this->channel, &readers, &writers);
- // For each existing DNS socket, see if we are still supposed to watch it,
- // if not then erase it
- this->socket_handlers.erase(
- std::remove_if(this->socket_handlers.begin(), this->socket_handlers.end(),
- [&readers](const auto& dns_socket)
- {
- return !FD_ISSET(dns_socket->get_socket(), &readers);
- }),
- this->socket_handlers.end());
-
- for (auto i = 0; i < ndfs; ++i)
- {
- bool read = FD_ISSET(i, &readers);
- bool write = FD_ISSET(i, &writers);
- // Look for the DNSSocketHandler with this fd
- auto it = std::find_if(this->socket_handlers.begin(),
- this->socket_handlers.end(),
- [i](const auto& socket_handler)
- {
- return i == socket_handler->get_socket();
- });
- if (!read && !write) // No need to read or write to it
- { // If found, erase it and stop watching it because it is not
- // needed anymore
- if (it != this->socket_handlers.end())
- // The socket destructor removes it from the poller
- this->socket_handlers.erase(it);
- }
- else // We need to write and/or read to it
- { // If not found, create it because we need to watch it
- if (it == this->socket_handlers.end())
- {
- this->socket_handlers.emplace(this->socket_handlers.begin(),
- std::make_unique<DNSSocketHandler>(poller, *this, i));
- it = this->socket_handlers.begin();
- }
- poller->add_socket_handler(it->get());
- if (write)
- 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"));
- }
+ DNSHandler::socket_handler->watch();
}
-void DNSHandler::remove_all_sockets_from_poller()
+void DNSHandler::unwatch()
{
- for (const auto& socket_handler: this->socket_handlers)
- {
- socket_handler->remove_from_poller();
- }
+ DNSHandler::socket_handler->unwatch();
}
-#endif /* CARES_FOUND */
+#endif /* UDNS_FOUND */