From: Remi Gacogne Date: Tue, 14 May 2024 13:37:44 +0000 (+0200) Subject: dnsdist: Prevent a race when calling `registerWebHandler` at runtime X-Git-Tag: dnsdist-1.9.5~15^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F14170%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Prevent a race when calling `registerWebHandler` at runtime --- 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;