From: Remi Gacogne Date: Mon, 18 May 2026 10:34:21 +0000 (+0200) Subject: dnsdist: Handle exceptions when dealing with asynchronous objects X-Git-Tag: auth-5.1.0~41^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7dfd36ce539de4b22427d2b7c3e2bf00146861cd;p=thirdparty%2Fpdns.git dnsdist: Handle exceptions when dealing with asynchronous objects Signed-off-by: Remi Gacogne --- diff --git a/pdns/dnsdistdist/dnsdist-async.cc b/pdns/dnsdistdist/dnsdist-async.cc index 8bd0caa46e..0d0ba896e4 100644 --- a/pdns/dnsdistdist/dnsdist-async.cc +++ b/pdns/dnsdistdist/dnsdist-async.cc @@ -94,60 +94,70 @@ void AsynchronousHolder::mainThread(std::shared_ptr data) std::vector readyFDs; while (true) { - bool shouldWait = true; - int timeout = -1; - dnsdist::configuration::refreshLocalRuntimeConfiguration(); - - { - auto content = data->d_content.lock(); - if (data->d_done) { - return; - } + try { + bool shouldWait = true; + int timeout = -1; + dnsdist::configuration::refreshLocalRuntimeConfiguration(); - if (!content->empty()) { - gettimeofday(&now, nullptr); - struct timeval next = getNextTTD(*content); - if (next <= now) { - pickupExpired(*content, now, expiredEvents); - shouldWait = false; + { + auto content = data->d_content.lock(); + if (data->d_done) { + return; } - else { - auto remainingUsec = uSec(next - now); - timeout = static_cast(std::round(static_cast(remainingUsec) / 1000.0)); - if (timeout == 0 && remainingUsec > 0) { - /* if we have less than 1 ms, let's wait at least 1 ms */ - timeout = 1; + + if (!content->empty()) { + gettimeofday(&now, nullptr); + struct timeval next = getNextTTD(*content); + if (next <= now) { + pickupExpired(*content, now, expiredEvents); + shouldWait = false; + } + else { + auto remainingUsec = uSec(next - now); + timeout = static_cast(std::round(static_cast(remainingUsec) / 1000.0)); + if (timeout == 0 && remainingUsec > 0) { + /* if we have less than 1 ms, let's wait at least 1 ms */ + timeout = 1; + } } } } - } - if (shouldWait) { - auto timedOut = wait(*data, *mplexer, readyFDs, timeout); - if (timedOut) { - auto content = data->d_content.lock(); - gettimeofday(&now, nullptr); - pickupExpired(*content, now, expiredEvents); + if (shouldWait) { + auto timedOut = wait(*data, *mplexer, readyFDs, timeout); + if (timedOut) { + auto content = data->d_content.lock(); + gettimeofday(&now, nullptr); + pickupExpired(*content, now, expiredEvents); + } } - } - while (!expiredEvents.empty()) { - auto [queryID, query] = std::move(expiredEvents.front()); - expiredEvents.pop_front(); - if (!data->d_failOpen) { - VERBOSESLOG(infolog("Asynchronous query %d has expired at %d.%d, notifying the sender", queryID, now.tv_sec, now.tv_usec), - dnsdist::logging::getTopLogger("async-thread")->info(Logr::Info, "Asynchronous query has expired, notifying the sender", "dns.question.id", Logging::Loggable(queryID))); - auto sender = query->getTCPQuerySender(); - if (sender) { - TCPResponse tresponse(std::move(query->query)); - sender->notifyIOError(now, std::move(tresponse)); + while (!expiredEvents.empty()) { + auto [queryID, query] = std::move(expiredEvents.front()); + expiredEvents.pop_front(); + if (!data->d_failOpen) { + VERBOSESLOG(infolog("Asynchronous query %d has expired at %d.%d, notifying the sender", queryID, now.tv_sec, now.tv_usec), + dnsdist::logging::getTopLogger("async-thread")->info(Logr::Info, "Asynchronous query has expired, notifying the sender", "dns.question.id", Logging::Loggable(queryID))); + auto sender = query->getTCPQuerySender(); + if (sender) { + TCPResponse tresponse(std::move(query->query)); + sender->notifyIOError(now, std::move(tresponse)); + } + } + else { + VERBOSESLOG(infolog("Asynchronous query %d has expired at %d.%d, resuming", queryID, now.tv_sec, now.tv_usec), + dnsdist::logging::getTopLogger("async-thread")->info(Logr::Info, "Asynchronous query has expired, resuming", "dns.question.id", Logging::Loggable(queryID))); + resumeQuery(std::move(query)); } } - else { - VERBOSESLOG(infolog("Asynchronous query %d has expired at %d.%d, resuming", queryID, now.tv_sec, now.tv_usec), - dnsdist::logging::getTopLogger("async-thread")->info(Logr::Info, "Asynchronous query has expired, resuming", "dns.question.id", Logging::Loggable(queryID))); - resumeQuery(std::move(query)); - } + } + catch (const std::exception& exp) { + VERBOSESLOG(infolog("Got exception in the main asynchronous handler thread: %s", exp.what()), + dnsdist::logging::getTopLogger("async-thread")->error(Logr::Info, exp.what(), "Got exception in the main asynchronous handler thread")); + } + catch (...) { + VERBOSESLOG(infolog("Got exception in the main asynchronous handler thread"), + dnsdist::logging::getTopLogger("async-thread")->info(Logr::Info, "Got exception in the main asynchronous handler thread")); } } }