From 83c58cf42e36b52b08200f4193779457dd9de616 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Wed, 11 Sep 2019 12:11:01 -0700 Subject: [PATCH] ircd::net::dns: Deduplicate requests at resolve() entry. --- modules/net_dns.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/modules/net_dns.cc b/modules/net_dns.cc index 3ce0a23a0..6aca00503 100644 --- a/modules/net_dns.cc +++ b/modules/net_dns.cc @@ -108,21 +108,36 @@ ircd::net::dns::resolve(const hostport &hp, const opts &opts, callback cb) { - assert(ctx::current); if(unlikely(!opts.qtype)) throw error { "A query type is required; not specified; cannot be deduced here." }; - if(opts.cache_check) + // Try to satisfy from the cache first. This requires a ctx. + if(likely(ctx::current && opts.cache_check)) if(cache::get(hp, opts, cb)) return; + // Remote query will be made; register this callback as waiting for reply if(cb) cache::waiting.emplace_back(hp, opts, std::move(cb)); - resolver_call(hp, opts); + // Check if there is already someone else waiting on the same query + const auto count + { + !cb? 1: std::count_if(begin(cache::waiting), end(cache::waiting), [] + (const auto &a) + { + const auto &b(cache::waiting.back()); + return a.opts.qtype == b.opts.qtype && a.key != b.key; + }) + }; + + // When nobody else is already waiting on this query we have to submit it. + assert(count >= 1); + if(count == 1) + resolver_call(hp, opts); } void