From 736000d37c335d00a1c5d97a777a7b5516e505a2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 14 May 2024 15:37:44 +0200 Subject: [PATCH] dnsdist: Prevent a race when calling `registerWebHandler` at runtime --- pdns/dnsdist-web.cc | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 066b5c177f..265206a725 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -1720,18 +1720,20 @@ static void handleRings(const YaHTTP::Request& req, YaHTTP::Response& resp) resp.headers["Content-Type"] = "application/json"; } -static std::unordered_map> s_webHandlers; +using WebHandler = std::function; +static SharedLockGuarded> s_webHandlers; -void registerWebHandler(const std::string& endpoint, std::function handler); +void registerWebHandler(const std::string& endpoint, WebHandler handler); -void registerWebHandler(const std::string& endpoint, std::function handler) +void registerWebHandler(const std::string& endpoint, WebHandler handler) { - s_webHandlers[endpoint] = std::move(handler); + auto handlers = s_webHandlers.write_lock(); + (*handlers)[endpoint] = std::move(handler); } void clearWebHandlers() { - s_webHandlers.clear(); + s_webHandlers.write_lock()->clear(); } #ifndef DISABLE_BUILTIN_HTML @@ -1862,9 +1864,17 @@ static void connectionThread(WebClientConnection&& conn) resp.status = 405; } else { - const auto it = s_webHandlers.find(req.url.path); - if (it != s_webHandlers.end()) { - it->second(req, resp); + WebHandler handler; + { + auto handlers = s_webHandlers.read_lock(); + const auto webHandlersIt = handlers->find(req.url.path); + if (webHandlersIt != handlers->end()) { + handler = webHandlersIt->second; + } + } + + if (handler) { + handler(req, resp); } else { resp.status = 404; -- 2.47.2