From: Otto Moerbeek Date: Thu, 3 Jul 2025 10:03:41 +0000 (+0200) Subject: Add size limit X-Git-Tag: rec-5.4.0-alpha0~41^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92074de6da9f7535d27c9bc811440073aef440c7;p=thirdparty%2Fpdns.git Add size limit Signed-off-by: Otto Moerbeek --- diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index a91ca83fd0..8a278bb524 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -523,9 +523,9 @@ void RecursorLua4::postPrepareContext() // NOLINT(readability-function-cognitive return {dir, name}; }); - d_lw->writeFunction("getNSSpeedTable", []() { + d_lw->writeFunction("getNSSpeedTable", [](size_t maxSize) { std::string ret; - auto number = SyncRes::getNSSpeedTable(ret); + auto number = SyncRes::getNSSpeedTable(maxSize, ret); return std::tuple{ret, number}; }); diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 9b09876602..a2d7350969 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -290,8 +290,14 @@ public: } } - size_t getPB(std::string& ret) const + 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 full(ret); full.add_string(PBNSSpeedDump::required_string_version, getPDNSVersion()); full.add_string(PBNSSpeedDump::required_string_identity, SyncRes::s_serverID); @@ -300,11 +306,19 @@ public: full.add_string(PBNSSpeedDump::required_string_type, "PBNSSpeedDump"); size_t count = 0; + ret.reserve(estimate); + for (const auto& entry : *this) { protozero::pbf_builder 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; } @@ -426,10 +440,10 @@ public: static LockGuarded s_nsSpeeds; -size_t SyncRes::getNSSpeedTable(std::string& ret) +size_t SyncRes::getNSSpeedTable(size_t maxSize, std::string& ret) { const auto copy = *s_nsSpeeds.lock(); - return copy.getPB(ret); + return copy.getPB(maxSize, ret); } size_t SyncRes::putIntoNSSpeedTable(const std::string& ret) diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 0a661a71f5..91e8006271 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -170,7 +170,7 @@ public: static uint64_t doDumpSavedParentNSSets(int fileDesc); static uint64_t doDumpDoTProbeMap(int fileDesc); - static size_t getNSSpeedTable(std::string& ret); + static size_t getNSSpeedTable(size_t maxSize, std::string& ret); static size_t putIntoNSSpeedTable(const std::string& ret); static int getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigned int depth, Logr::log_t);