pdns_recursor.cc \
pdnsexception.hh \
pollmplexer.cc \
+ protozero-helpers.hh \
protozero-trace.cc protozero-trace.hh \
protozero.cc protozero.hh \
proxy-protocol.cc proxy-protocol.hh \
rec-eventtrace.cc rec-eventtrace.hh \
rec-lua-conf.hh rec-lua-conf.cc \
rec-main.hh rec-main.cc \
+ rec-nsspeeds.cc rec-nsspeeds.hh \
rec-protozero.cc rec-protozero.hh \
rec-responsestats.hh rec-responsestats.cc \
rec-rust-lib/cxxsupport.cc \
src_dir / 'rec-carbon.cc',
src_dir / 'rec-eventtrace.cc',
src_dir / 'rec-lua-conf.cc',
+ src_dir / 'rec-nsspeeds.cc',
src_dir / 'rec-protozero.cc',
src_dir / 'rec-responsestats.cc',
src_dir / 'rec-system-resolve.cc',
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <protozero/pbf_builder.hpp>
+#include <protozero/pbf_message.hpp>
+#include "protozero-helpers.hh"
+
+#include "logging.hh"
+#include "version.hh"
+
+#include "rec-nsspeeds.hh"
+
+enum class PBNSSpeedDump : protozero::pbf_tag_type
+{
+ required_string_version = 1,
+ required_string_identity = 2,
+ required_uint64_protocolVersion = 3,
+ required_int64_time = 4,
+ required_string_type = 5,
+ repeated_message_nsspeedEntry = 6,
+};
+
+enum class PBNSSpeedEntry : protozero::pbf_tag_type
+{
+ required_bytes_name = 1,
+ required_int64_lastgets = 2,
+ required_int64_lastgetus = 3,
+ repeated_message_map = 4,
+};
+
+enum class PBNSSpeedMap : protozero::pbf_tag_type
+{
+ required_bytes_address = 1,
+ required_float_val = 2,
+ required_int32_last = 3,
+};
+
+template <typename T, typename U>
+void nsspeeds_t::getPBEntry(T& message, U& entry)
+{
+ message.add_bytes(PBNSSpeedEntry::required_bytes_name, entry.d_name.toString());
+ message.add_int64(PBNSSpeedEntry::required_int64_lastgets, entry.d_lastget.tv_sec);
+ message.add_int64(PBNSSpeedEntry::required_int64_lastgetus, entry.d_lastget.tv_usec);
+ for (const auto& [address, collection] : entry.d_collection) {
+ protozero::pbf_builder<PBNSSpeedMap> map(message, PBNSSpeedEntry::repeated_message_map);
+ encodeComboAddress(map, PBNSSpeedMap::required_bytes_address, address);
+ map.add_float(PBNSSpeedMap::required_float_val, collection.d_val);
+ map.add_int32(PBNSSpeedMap::required_int32_last, collection.d_last);
+ }
+}
+
+size_t nsspeeds_t::getPB(const string& serverID, size_t maxSize, std::string& ret) const
+{
+ auto log = g_slog->withName("syncres")->withValues("maxSize", Logging::Loggable(maxSize));
+ log->info(Logr::Info, "Producing nsspeed dump");
+
+ // A observed average record size is 60;
+ size_t estimate = maxSize == 0 ? size() * 60 : maxSize + 4096; // We may overshoot (will be rolled back)
+
+ protozero::pbf_builder<PBNSSpeedDump> full(ret);
+ full.add_string(PBNSSpeedDump::required_string_version, getPDNSVersion());
+ full.add_string(PBNSSpeedDump::required_string_identity, serverID);
+ full.add_uint64(PBNSSpeedDump::required_uint64_protocolVersion, 1);
+ full.add_int64(PBNSSpeedDump::required_int64_time, time(nullptr));
+ full.add_string(PBNSSpeedDump::required_string_type, "PBNSSpeedDump");
+
+ size_t count = 0;
+ ret.reserve(estimate);
+
+ for (const auto& entry : *this) {
+ protozero::pbf_builder<PBNSSpeedEntry> message(full, PBNSSpeedDump::repeated_message_nsspeedEntry);
+ getPBEntry(message, entry);
+ if (ret.size() > maxSize) {
+ message.rollback();
+ log->info(Logr::Info, "Produced nsspeed dump (max size reached)", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count));
+ return count;
+ }
+ ++count;
+ }
+ log->info(Logr::Info, "Produced nsspeed dump", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count));
+ return count;
+}
+
+template <typename T>
+bool nsspeeds_t::putPBEntry(time_t cutoff, T& message)
+{
+ DecayingEwmaCollection entry{{}};
+ while (message.next()) {
+ switch (message.tag()) {
+ case PBNSSpeedEntry::required_bytes_name:
+ entry.d_name = DNSName(message.get_bytes());
+ break;
+ case PBNSSpeedEntry::required_int64_lastgets:
+ entry.d_lastget.tv_sec = message.get_int64();
+ break;
+ case PBNSSpeedEntry::required_int64_lastgetus:
+ entry.d_lastget.tv_usec = message.get_int64();
+ break;
+ case PBNSSpeedEntry::repeated_message_map: {
+ protozero::pbf_message<PBNSSpeedMap> map = message.get_message();
+ ComboAddress address;
+ float val{};
+ int last{};
+ while (map.next()) {
+ switch (map.tag()) {
+ case PBNSSpeedMap::required_bytes_address:
+ decodeComboAddress(map, address);
+ break;
+ case PBNSSpeedMap::required_float_val:
+ val = map.get_float();
+ break;
+ case PBNSSpeedMap::required_int32_last:
+ last = map.get_int32();
+ break;
+ }
+ }
+ entry.insert(address, val, last);
+ break;
+ }
+ }
+ }
+ if (!entry.stale(cutoff)) {
+ return insert(std::move(entry)).second;
+ }
+ return false;
+}
+
+size_t nsspeeds_t::putPB(time_t cutoff, const std::string& pbuf)
+{
+ auto log = g_slog->withName("syncres")->withValues("size", Logging::Loggable(pbuf.size()));
+ log->info(Logr::Debug, "Processing nsspeed dump");
+
+ protozero::pbf_message<PBNSSpeedDump> full(pbuf);
+ size_t count = 0;
+ size_t inserted = 0;
+ try {
+ bool protocolVersionSeen = false;
+ bool typeSeen = false;
+ while (full.next()) {
+ switch (full.tag()) {
+ case PBNSSpeedDump::required_string_version: {
+ auto version = full.get_string();
+ log = log->withValues("version", Logging::Loggable(version));
+ break;
+ }
+ case PBNSSpeedDump::required_string_identity: {
+ auto identity = full.get_string();
+ log = log->withValues("identity", Logging::Loggable(identity));
+ break;
+ }
+ case PBNSSpeedDump::required_uint64_protocolVersion: {
+ auto protocolVersion = full.get_uint64();
+ log = log->withValues("protocolVersion", Logging::Loggable(protocolVersion));
+ if (protocolVersion != 1) {
+ throw std::runtime_error("Protocol version mismatch");
+ }
+ protocolVersionSeen = true;
+ break;
+ }
+ case PBNSSpeedDump::required_int64_time: {
+ auto time = full.get_int64();
+ log = log->withValues("time", Logging::Loggable(time));
+ break;
+ }
+ case PBNSSpeedDump::required_string_type: {
+ auto type = full.get_string();
+ if (type != "PBNSSpeedDump") {
+ throw std::runtime_error("Data type mismatch");
+ }
+ typeSeen = true;
+ break;
+ }
+ case PBNSSpeedDump::repeated_message_nsspeedEntry: {
+ if (!protocolVersionSeen || !typeSeen) {
+ throw std::runtime_error("Required field missing");
+ }
+ protozero::pbf_message<PBNSSpeedEntry> message = full.get_message();
+ if (putPBEntry(cutoff, message)) {
+ ++inserted;
+ }
+ ++count;
+ break;
+ }
+ }
+ }
+ log->info(Logr::Info, "Processed nsspeed dump", "processed", Logging::Loggable(count), "inserted", Logging::Loggable(inserted));
+ return inserted;
+ }
+ catch (const std::runtime_error& e) {
+ log->error(Logr::Error, e.what(), "Runtime exception processing cache dump");
+ }
+ catch (const std::exception& e) {
+ log->error(Logr::Error, e.what(), "Exception processing cache dump");
+ }
+ catch (...) {
+ log->error(Logr::Error, "Other exception processing cache dump");
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+
+#include "iputils.hh"
+
+using namespace ::boost::multi_index;
+
+/** Class that implements a decaying EWMA.
+ This class keeps an exponentially weighted moving average which, additionally, decays over time.
+ The decaying is only done on get.
+*/
+
+//! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
+/** Modelled to work mostly like the underlying DecayingEwma */
+class DecayingEwmaCollection
+{
+private:
+ struct DecayingEwma
+ {
+ public:
+ void submit(int arg, const struct timeval& last, const struct timeval& now)
+ {
+ d_last = arg;
+ auto val = static_cast<float>(arg);
+ if (d_val == 0) {
+ d_val = val;
+ }
+ else {
+ auto diff = makeFloat(last - now);
+ auto factor = expf(diff) / 2.0F; // might be '0.5', or 0.0001
+ d_val = (1.0F - factor) * val + factor * d_val;
+ }
+ }
+
+ float get(float factor)
+ {
+ return d_val *= factor;
+ }
+
+ [[nodiscard]] float peek() const
+ {
+ return d_val;
+ }
+
+ [[nodiscard]] int last() const
+ {
+ return d_last;
+ }
+
+ float d_val{0};
+ int d_last{0};
+ };
+
+public:
+ DecayingEwmaCollection(DNSName name, const struct timeval val = {0, 0}) :
+ d_name(std::move(name)), d_lastget(val)
+ {
+ }
+
+ void submit(const ComboAddress& remote, int usecs, const struct timeval& now) const
+ {
+ d_collection[remote].submit(usecs, d_lastget, now);
+ }
+
+ float getFactor(const struct timeval& now) const
+ {
+ float diff = makeFloat(d_lastget - now);
+ return expf(diff / 60.0F); // is 1.0 or less
+ }
+
+ bool stale(time_t limit) const
+ {
+ return limit > d_lastget.tv_sec;
+ }
+
+ void purge(const std::map<ComboAddress, float>& keep) const
+ {
+ for (auto iter = d_collection.begin(); iter != d_collection.end();) {
+ if (keep.find(iter->first) != keep.end()) {
+ ++iter;
+ }
+ else {
+ iter = d_collection.erase(iter);
+ }
+ }
+ }
+
+ void insert(const ComboAddress& address, float val, int last)
+ {
+ d_collection.insert(std::make_pair(address, DecayingEwma{val, last}));
+ }
+
+ // d_collection is the modifyable part of the record, we index on DNSName and timeval, and DNSName never changes
+ mutable std::map<ComboAddress, DecayingEwma> d_collection;
+ DNSName d_name;
+ struct timeval d_lastget;
+};
+
+class nsspeeds_t : public multi_index_container<DecayingEwmaCollection,
+ indexed_by<
+ hashed_unique<tag<DNSName>, member<DecayingEwmaCollection, const DNSName, &DecayingEwmaCollection::d_name>>,
+ ordered_non_unique<tag<timeval>, member<DecayingEwmaCollection, timeval, &DecayingEwmaCollection::d_lastget>>>>
+{
+public:
+ const auto& find_or_enter(const DNSName& name, const struct timeval& now)
+ {
+ const auto iter = insert(DecayingEwmaCollection{name, now}).first;
+ return *iter;
+ }
+
+ const auto& find_or_enter(const DNSName& name)
+ {
+ const auto iter = insert(DecayingEwmaCollection{name}).first;
+ return *iter;
+ }
+
+ float fastest(const DNSName& name, const struct timeval& now)
+ {
+ auto& ind = get<DNSName>();
+ auto iter = insert(DecayingEwmaCollection{name, now}).first;
+ if (iter->d_collection.empty()) {
+ return 0;
+ }
+ // This could happen if find(DNSName) entered an entry; it's used only by test code
+ if (iter->d_lastget.tv_sec == 0 && iter->d_lastget.tv_usec == 0) {
+ ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; });
+ }
+
+ float ret = std::numeric_limits<float>::max();
+ const float factor = iter->getFactor(now);
+ for (auto& entry : iter->d_collection) {
+ ret = std::min(ret, entry.second.get(factor));
+ }
+ ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; });
+ return ret;
+ }
+
+ size_t getPB(const string& serverID, size_t maxSize, std::string& ret) const;
+ size_t putPB(time_t cutoff, const std::string& pbuf);
+
+private:
+ template <typename T, typename U>
+ static void getPBEntry(T& message, U& entry);
+ template <typename T>
+ bool putPBEntry(time_t cutoff, T& message);
+};
#include "validate-recursor.hh"
#include "rec-taskqueue.hh"
#include "shuffle.hh"
-
-#include "version.hh"
-#include <protozero/pbf_builder.hpp>
-#include <protozero/pbf_message.hpp>
-#include "protozero-helpers.hh"
+#include "rec-nsspeeds.hh"
rec::GlobalCounters g_Counters;
thread_local rec::TCounters t_Counters(g_Counters);
cont_t d_cont;
};
-/** Class that implements a decaying EWMA.
- This class keeps an exponentially weighted moving average which, additionally, decays over time.
- The decaying is only done on get.
-*/
-
-//! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
-/** Modelled to work mostly like the underlying DecayingEwma */
-class DecayingEwmaCollection
-{
-private:
- struct DecayingEwma
- {
- public:
- void submit(int arg, const struct timeval& last, const struct timeval& now)
- {
- d_last = arg;
- auto val = static_cast<float>(arg);
- if (d_val == 0) {
- d_val = val;
- }
- else {
- auto diff = makeFloat(last - now);
- auto factor = expf(diff) / 2.0F; // might be '0.5', or 0.0001
- d_val = (1.0F - factor) * val + factor * d_val;
- }
- }
-
- float get(float factor)
- {
- return d_val *= factor;
- }
-
- [[nodiscard]] float peek() const
- {
- return d_val;
- }
-
- [[nodiscard]] int last() const
- {
- return d_last;
- }
-
- float d_val{0};
- int d_last{0};
- };
-
-public:
- DecayingEwmaCollection(DNSName name, const struct timeval val = {0, 0}) :
- d_name(std::move(name)), d_lastget(val)
- {
- }
-
- void submit(const ComboAddress& remote, int usecs, const struct timeval& now) const
- {
- d_collection[remote].submit(usecs, d_lastget, now);
- }
-
- float getFactor(const struct timeval& now) const
- {
- float diff = makeFloat(d_lastget - now);
- return expf(diff / 60.0F); // is 1.0 or less
- }
-
- bool stale(time_t limit) const
- {
- return limit > d_lastget.tv_sec;
- }
-
- void purge(const std::map<ComboAddress, float>& keep) const
- {
- for (auto iter = d_collection.begin(); iter != d_collection.end();) {
- if (keep.find(iter->first) != keep.end()) {
- ++iter;
- }
- else {
- iter = d_collection.erase(iter);
- }
- }
- }
-
- void insert(const ComboAddress& address, float val, int last)
- {
- d_collection.insert(std::make_pair(address, DecayingEwma{val, last}));
- }
-
- // d_collection is the modifyable part of the record, we index on DNSName and timeval, and DNSName never changes
- mutable std::map<ComboAddress, DecayingEwma> d_collection;
- DNSName d_name;
- struct timeval d_lastget;
-};
-
-class nsspeeds_t : public multi_index_container<DecayingEwmaCollection,
- indexed_by<
- hashed_unique<tag<DNSName>, member<DecayingEwmaCollection, const DNSName, &DecayingEwmaCollection::d_name>>,
- ordered_non_unique<tag<timeval>, member<DecayingEwmaCollection, timeval, &DecayingEwmaCollection::d_lastget>>>>
-{
-public:
- const auto& find_or_enter(const DNSName& name, const struct timeval& now)
- {
- const auto iter = insert(DecayingEwmaCollection{name, now}).first;
- return *iter;
- }
-
- const auto& find_or_enter(const DNSName& name)
- {
- const auto iter = insert(DecayingEwmaCollection{name}).first;
- return *iter;
- }
-
- float fastest(const DNSName& name, const struct timeval& now)
- {
- auto& ind = get<DNSName>();
- auto iter = insert(DecayingEwmaCollection{name, now}).first;
- if (iter->d_collection.empty()) {
- return 0;
- }
- // This could happen if find(DNSName) entered an entry; it's used only by test code
- if (iter->d_lastget.tv_sec == 0 && iter->d_lastget.tv_usec == 0) {
- ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; });
- }
-
- float ret = std::numeric_limits<float>::max();
- const float factor = iter->getFactor(now);
- for (auto& entry : iter->d_collection) {
- ret = std::min(ret, entry.second.get(factor));
- }
- ind.modify(iter, [&](DecayingEwmaCollection& dec) { dec.d_lastget = now; });
- return ret;
- }
-
- enum class PBNSSpeedDump : protozero::pbf_tag_type
- {
- required_string_version = 1,
- required_string_identity = 2,
- required_uint64_protocolVersion = 3,
- required_int64_time = 4,
- required_string_type = 5,
- repeated_message_nsspeedEntry = 6,
- };
-
- enum class PBNSSpeedEntry : protozero::pbf_tag_type
- {
- required_bytes_name = 1,
- required_int64_lastgets = 2,
- required_int64_lastgetus = 3,
- repeated_message_map = 4,
- };
-
- enum class PBNSSpeedMap : protozero::pbf_tag_type
- {
- required_bytes_address = 1,
- required_float_val = 2,
- required_int32_last = 3,
- };
-
- template <typename T, typename U>
- void getEntry(T& message, U entry) const
- {
- message.add_bytes(PBNSSpeedEntry::required_bytes_name, entry->d_name.toString());
- message.add_int64(PBNSSpeedEntry::required_int64_lastgets, entry->d_lastget.tv_sec);
- message.add_int64(PBNSSpeedEntry::required_int64_lastgetus, entry->d_lastget.tv_usec);
- for (const auto& [address, collection] : entry->d_collection) {
- protozero::pbf_builder<PBNSSpeedMap> map(message, PBNSSpeedEntry::repeated_message_map);
- encodeComboAddress(map, PBNSSpeedMap::required_bytes_address, address);
- map.add_float(PBNSSpeedMap::required_float_val, collection.d_val);
- map.add_int32(PBNSSpeedMap::required_int32_last, collection.d_last);
- }
- }
-
- size_t getPB(size_t maxSize, std::string& ret) const
- {
- auto log = g_slog->withName("syncres")->withValues("maxSize", Logging::Loggable(maxSize));
- log->info(Logr::Info, "Producing nsspeed dump");
-
- // A observed average record size is 60;
- size_t estimate = maxSize == 0 ? size() * 60 : maxSize + 4096; // We may overshoot (will be rolled back)
-
- protozero::pbf_builder<PBNSSpeedDump> full(ret);
- full.add_string(PBNSSpeedDump::required_string_version, getPDNSVersion());
- full.add_string(PBNSSpeedDump::required_string_identity, SyncRes::s_serverID);
- full.add_uint64(PBNSSpeedDump::required_uint64_protocolVersion, 1);
- full.add_int64(PBNSSpeedDump::required_int64_time, time(nullptr));
- full.add_string(PBNSSpeedDump::required_string_type, "PBNSSpeedDump");
-
- size_t count = 0;
- ret.reserve(estimate);
-
- for (const auto& entry : *this) {
- protozero::pbf_builder<PBNSSpeedEntry> message(full, PBNSSpeedDump::repeated_message_nsspeedEntry);
- getEntry(message, &entry);
- if (ret.size() > maxSize) {
- message.rollback();
- log->info(Logr::Info, "Produced nsspeed dump (max size reached)", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count));
- return count;
- }
- ++count;
- }
- log->info(Logr::Info, "Produced nsspeed dump", "size", Logging::Loggable(ret.size()), "count", Logging::Loggable(count));
- return count;
- }
-
-
- template <typename T>
- bool putEntry(T& message)
- {
- DecayingEwmaCollection entry{{}};
- while (message.next()) {
- switch (message.tag()) {
- case PBNSSpeedEntry::required_bytes_name:
- entry.d_name = DNSName(message.get_bytes());
- break;
- case PBNSSpeedEntry::required_int64_lastgets:
- entry.d_lastget.tv_sec = message.get_int64();
- break;
- case PBNSSpeedEntry::required_int64_lastgetus:
- entry.d_lastget.tv_usec = message.get_int64();
- break;
- case PBNSSpeedEntry::repeated_message_map: {
- protozero::pbf_message<PBNSSpeedMap> map = message.get_message();
- ComboAddress address;
- float val{};
- int last{};
- while (map.next()) {
- switch (map.tag()) {
- case PBNSSpeedMap::required_bytes_address:
- decodeComboAddress(map, address);
- break;
- case PBNSSpeedMap::required_float_val:
- val = map.get_float();
- break;
- case PBNSSpeedMap::required_int32_last:
- last = map.get_int32();
- break;
- }
- }
- entry.insert(address, val, last);
- break;
- }
- }
- }
- return insert(std::move(entry)).second;
- }
-
- size_t putPB(const std::string& pbuf)
- {
- auto log = g_slog->withName("syncres")->withValues("size", Logging::Loggable(pbuf.size()));
- log->info(Logr::Debug, "Processing nsspeed dump");
-
- protozero::pbf_message<PBNSSpeedDump> full(pbuf);
- size_t count = 0;
- size_t inserted = 0;
- try {
- bool protocolVersionSeen = false;
- bool typeSeen = false;
- while (full.next()) {
- switch (full.tag()) {
- case PBNSSpeedDump::required_string_version: {
- auto version = full.get_string();
- log = log->withValues("version", Logging::Loggable(version));
- break;
- }
- case PBNSSpeedDump::required_string_identity: {
- auto identity = full.get_string();
- log = log->withValues("identity", Logging::Loggable(identity));
- break;
- }
- case PBNSSpeedDump::required_uint64_protocolVersion: {
- auto protocolVersion = full.get_uint64();
- log = log->withValues("protocolVersion", Logging::Loggable(protocolVersion));
- if (protocolVersion != 1) {
- throw std::runtime_error("Protocol version mismatch");
- }
- protocolVersionSeen = true;
- break;
- }
- case PBNSSpeedDump::required_int64_time: {
- auto time = full.get_int64();
- log = log->withValues("time", Logging::Loggable(time));
- break;
- }
- case PBNSSpeedDump::required_string_type: {
- auto type = full.get_string();
- if (type != "PBNSSpeedDump") {
- throw std::runtime_error("Data type mismatch");
- }
- typeSeen = true;
- break;
- }
- case PBNSSpeedDump::repeated_message_nsspeedEntry: {
- if (!protocolVersionSeen || !typeSeen) {
- throw std::runtime_error("Required field missing");
- }
- protozero::pbf_message<PBNSSpeedEntry> message = full.get_message();
- if (putEntry(message)) {
- ++inserted;
- }
- ++count;
- break;
- }
- }
- }
- log->info(Logr::Info, "Processed nsspeed dump", "processed", Logging::Loggable(count), "inserted", Logging::Loggable(inserted));
- return inserted;
- }
- catch (const std::runtime_error& e) {
- log->error(Logr::Error, e.what(), "Runtime exception processing cache dump");
- }
- catch (const std::exception& e) {
- log->error(Logr::Error, e.what(), "Exception processing cache dump");
- }
- catch (...) {
- log->error(Logr::Error, "Other exception processing cache dump");
- }
- return 0;
- }
-};
static LockGuarded<nsspeeds_t> s_nsSpeeds;
size_t SyncRes::getNSSpeedTable(size_t maxSize, std::string& ret)
{
const auto copy = *s_nsSpeeds.lock();
- return copy.getPB(maxSize, ret);
+ return copy.getPB(s_serverID, maxSize, ret);
}
size_t SyncRes::putIntoNSSpeedTable(const std::string& ret)
{
auto lock = s_nsSpeeds.lock();
- return lock->putPB(ret);
+ return lock->putPB(time(nullptr) - 300, ret);
}
class Throttle