diff --git a/include/ircd/net/dns.h b/include/ircd/net/dns.h index 61110b9b4..151203ae2 100644 --- a/include/ircd/net/dns.h +++ b/include/ircd/net/dns.h @@ -84,9 +84,11 @@ namespace ircd::net::dns::cache using closure = std::function; bool is_error(const json::object &rr); + bool is_error(const json::array &rr); time_t get_ttl(const json::object &rr); bool expired(const json::object &rr, const time_t &rr_ts, const time_t &min_ttl); bool expired(const json::object &rr, const time_t &rr_ts); + json::object random_choice(const json::array &); string_view make_type(const mutable_buffer &out, const string_view &); string_view make_type(const mutable_buffer &out, const uint16_t &); diff --git a/ircd/net.cc b/ircd/net.cc index 5a9f17d87..77296492f 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -3507,6 +3507,31 @@ ircd::net::dns::cache::make_type(const mutable_buffer &out, }; } +ircd::json::object +ircd::net::dns::cache::random_choice(const json::array &rrs) +{ + const size_t &count + { + rrs.size() + }; + + if(!count) + return json::object{}; + + const auto choice + { + rand::integer(0, count - 1) + }; + + assert(choice < count); + const json::object &rr + { + rrs[choice] + }; + + return rr; +} + bool ircd::net::dns::cache::expired(const json::object &rr, const time_t &rr_ts) @@ -3558,6 +3583,16 @@ ircd::net::dns::cache::get_ttl(const json::object &rr) return rr.get("ttl", 0L); } +bool +ircd::net::dns::cache::is_error(const json::array &rrs) +{ + return !std::none_of(begin(rrs), end(rrs), [] + (const json::object &rr) + { + return is_error(rr); + }); +} + bool ircd::net::dns::cache::is_error(const json::object &rr) { diff --git a/modules/s_dns.cc b/modules/s_dns.cc index e9e85d9de..a071eac4f 100644 --- a/modules/s_dns.cc +++ b/modules/s_dns.cc @@ -110,15 +110,9 @@ ircd::net::dns::handle_resolve_one(const hostport &hp, const json::array &rrs, callback_one callback) { - const size_t &count{rrs.size()}; - const auto choice - { - count? rand::integer(0, count - 1) : 0UL - }; - const json::object &rr { - rrs[choice] + cache::random_choice(rrs) }; callback(hp, rr);