From 477fe01e400b04a4c57dac6d04d3c2eeb8bad1f0 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 8 May 2018 15:03:24 -0700 Subject: [PATCH] ircd::net::dns: Write question into tag buffer; add send_burst conf item. --- include/ircd/net/resolver.h | 16 +++++----- ircd/net.cc | 62 ++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/include/ircd/net/resolver.h b/include/ircd/net/resolver.h index 4debe0d8c..70e6ccc7a 100644 --- a/include/ircd/net/resolver.h +++ b/include/ircd/net/resolver.h @@ -25,6 +25,7 @@ struct ircd::net::dns::resolver static constexpr const size_t &MAX_COUNT{64}; static conf::item timeout; static conf::item send_rate; + static conf::item send_burst; std::vector server; // The list of active servers size_t server_next{0}; // Round-robin state to hit servers @@ -33,8 +34,7 @@ struct ircd::net::dns::resolver ctx::dock dock; std::map tags; // The active requests steady_point send_last; // Time of last send - using queued = std::pair; - std::deque sendq; // Queue of frames for rate-limiting + std::deque sendq; // Queue of frames for rate-limiting ip::udp::socket ns; // A pollable activity object ip::udp::endpoint reply_from; // Remote addr of recv @@ -47,10 +47,10 @@ struct ircd::net::dns::resolver void handle(const error_code &ec, const size_t &) noexcept; void set_handle(); - void queue_query(const const_buffer &, tag &); - void send_query(const ip::udp::endpoint &, const const_buffer &, tag &); - void send_query(const const_buffer &, tag &); - void submit(const const_buffer &, tag &); + void send_query(const ip::udp::endpoint &, tag &); + void queue_query(tag &); + void send_query(tag &); + void submit(tag &); template tag &set_tag(A&&...); const_buffer make_query(const mutable_buffer &buf, const tag &) const; @@ -61,7 +61,7 @@ struct ircd::net::dns::resolver void timeout_worker(); ctx::context timeout_context; - void flush(const queued &); + void flush(const uint16_t &); void sendq_worker(); ctx::context sendq_context; @@ -74,10 +74,12 @@ struct ircd::net::dns::resolver::tag uint16_t id {0}; hostport hp; dns::opts opts; // note: invalid after query sent + const_buffer question; callback cb; steady_point last; uint8_t tries {0}; char hostbuf[256]; + char qbuf[384]; tag(const hostport &, const dns::opts &, callback &&); }; diff --git a/ircd/net.cc b/ircd/net.cc index 209a5e1a9..b03064469 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -2817,6 +2817,13 @@ ircd::net::dns::resolver::send_rate { "default", 60L }, }; +decltype(ircd::net::dns::resolver::send_burst) +ircd::net::dns::resolver::send_burst +{ + { "name", "ircd.net.dns.resolver.send_burst" }, + { "default", 8L }, +}; + ircd::net::dns::resolver::resolver() :ns{*ircd::ios} ,reply @@ -2871,26 +2878,21 @@ ircd::net::dns::resolver::sendq_worker() } void -ircd::net::dns::resolver::flush(const queued &next) +ircd::net::dns::resolver::flush(const uint16_t &next) try { auto &tag { - tags.at(next.first) + tags.at(next) }; - const const_buffer buf - { - data(next.second), size(next.second) - }; - - send_query(buf, tag); + send_query(tag); } catch(const std::out_of_range &e) { log::error { - "Queued tag id[%u] is no longer mapped", next.first + "Queued tag id[%u] is no longer mapped", next }; } @@ -2978,8 +2980,8 @@ ircd::net::dns::resolver::operator()(const hostport &hp, tags.erase(tag.id); }}; - thread_local char buf[64_KiB]; - submit(make_query(buf, tag), tag); + tag.question = make_query(tag.qbuf, tag); + submit(tag); } ircd::const_buffer @@ -3031,28 +3033,25 @@ ircd::net::dns::resolver::set_tag(A&&... args) } void -ircd::net::dns::resolver::submit(const const_buffer &buf, - tag &tag) +ircd::net::dns::resolver::queue_query(tag &tag) { - const auto rate(milliseconds(send_rate) / server.size()); - const auto elapsed(now() - send_last); - if(elapsed >= rate) - send_query(buf, tag); - else - queue_query(buf, tag); -} - -void -ircd::net::dns::resolver::queue_query(const const_buffer &buf, - tag &tag) -{ - sendq.emplace_back(tag.id, std::string(data(buf), size(buf))); + sendq.emplace_back(tag.id); dock.notify_one(); } void -ircd::net::dns::resolver::send_query(const const_buffer &buf, - tag &tag) +ircd::net::dns::resolver::submit(tag &tag) +{ + const auto rate(milliseconds(send_rate) / server.size()); + const auto elapsed(now() - send_last); + if(elapsed >= rate || tags.size() < size_t(send_burst)) + send_query(tag); + else + queue_query(tag); +} + +void +ircd::net::dns::resolver::send_query(tag &tag) try { assert(!server.empty()); @@ -3062,7 +3061,7 @@ try server.at(server_next) }; - send_query(ep, buf, tag); + send_query(ep, tag); } catch(const std::out_of_range &) { @@ -3074,14 +3073,15 @@ catch(const std::out_of_range &) void ircd::net::dns::resolver::send_query(const ip::udp::endpoint &ep, - const const_buffer &buf, tag &tag) { - assert(!empty(buf)); assert(ns.non_blocking()); + assert(!empty(tag.question)); + const const_buffer &buf{tag.question}; ns.send_to(asio::const_buffers_1(buf), ep); send_last = now(); tag.last = send_last; + tag.tries++; } void