From f1e3a9c53bfaf7a3d56d8bb50a7f5f3b9d56786e Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 22 Jul 2019 19:49:21 -0700 Subject: [PATCH] ircd::m::keys: Add mass fetcher to interface. --- include/ircd/m/keys.h | 1 + modules/m_keys.cc | 83 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/include/ircd/m/keys.h b/include/ircd/m/keys.h index 92f47859a..ceb4c6617 100644 --- a/include/ircd/m/keys.h +++ b/include/ircd/m/keys.h @@ -60,6 +60,7 @@ struct ircd::m::keys using closure = std::function; using closure_bool = std::function; + static bool get(const queries &, const closure_bool &); static void get(const string_view &server_name, const closure &); static void get(const string_view &server_name, const string_view &key_id, const closure &); static void query(const string_view &query_server, const queries &, const closure_bool &); diff --git a/modules/m_keys.cc b/modules/m_keys.cc index 70b25a933..063c02043 100644 --- a/modules/m_keys.cc +++ b/modules/m_keys.cc @@ -374,6 +374,89 @@ catch(const ctx::timeout &e) }; } +bool +IRCD_MODULE_EXPORT +ircd::m::keys::get(const queries &queries, + const closure_bool &closure) +{ + bool ret{true}; + std::vector opts; + opts.reserve(queries.size()); + for(const auto &[server_name, key_id] : queries) + { + const bool cached + { + cache::get(server_name, key_id, [&ret, &closure] + (const auto &object) + { + ret = closure(object); + }) + }; + + if(!ret) + return ret; + + if(cached) + continue; + + if(server_name == my_host()) + { + log::derror + { + m::log, "key '%s' for '%s' (that's myself) not found.", + key_id, + server_name, + }; + + continue; + } + + log::debug + { + m::log, "Key '%s' for %s not cached; querying network...", + key_id, + server_name, + }; + + opts.emplace_back(); + opts.back().op = feds::op::keys; + opts.back().arg[0] = server_name; + opts.back().arg[1] = key_id; + } + + assert(opts.size() <= queries.size()); + m::feds::acquire(opts, [&ret, &closure] + (const auto &result) + { + if(empty(result.object)) + return true; + + const m::keys keys + { + result.object + }; + + if(!verify(keys, std::nothrow)) + { + log::derror + { + m::log, "Failed to verify key '%s' for '%s' from '%s'", + result.request->arg[0], + result.request->arg[1], + result.origin, + }; + + return true; + } + + cache::set(result.object); + ret = closure(result.object); + return ret; + }); + + return ret; +} + // // m::keys::cache //