From d99179c73546539d27a2e7754203a8b84d8f1c97 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 26 Apr 2022 09:59:46 +0200 Subject: [PATCH] dnsdist-1.7: Scan the UDP buckets only when we have outstanding queries --- pdns/dnsdist.cc | 68 +++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index ea09c45487..236dcf92ce 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1849,7 +1849,7 @@ static void healthChecksThread() auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); auto states = g_dstates.getLocal(); // this points to the actual shared_ptrs! - for(auto& dss : *states) { + for (auto& dss : *states) { auto delta = dss->sw.udiffAndSet()/1000000.0; dss->queryLoad.store(1.0*(dss->queries.load() - dss->prev.queries.load())/delta); @@ -1857,39 +1857,41 @@ static void healthChecksThread() dss->prev.queries.store(dss->queries.load()); dss->prev.reuseds.store(dss->reuseds.load()); - for (IDState& ids : dss->idStates) { // timeouts - int64_t usageIndicator = ids.usageIndicator; - if(IDState::isInUse(usageIndicator) && ids.age++ > g_udpTimeout) { - /* We mark the state as unused as soon as possible - to limit the risk of racing with the - responder thread. - */ - auto oldDU = ids.du; - - if (!ids.tryMarkUnused(usageIndicator)) { - /* this state has been altered in the meantime, - don't go anywhere near it */ - continue; + if (dss->outstanding.load() > 0) { + for (IDState& ids : dss->idStates) { // timeouts + int64_t usageIndicator = ids.usageIndicator; + if(IDState::isInUse(usageIndicator) && ids.age++ > g_udpTimeout) { + /* We mark the state as unused as soon as possible + to limit the risk of racing with the + responder thread. + */ + auto oldDU = ids.du; + + if (!ids.tryMarkUnused(usageIndicator)) { + /* this state has been altered in the meantime, + don't go anywhere near it */ + continue; + } + ids.du = nullptr; + handleDOHTimeout(DOHUnitUniquePtr(oldDU, DOHUnit::release)); + oldDU = nullptr; + ids.age = 0; + dss->reuseds++; + --dss->outstanding; + ++g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout + vinfolog("Had a downstream timeout from %s (%s) for query for %s|%s from %s", + dss->remote.toStringWithPort(), dss->getName(), + ids.qname.toLogString(), QType(ids.qtype).toString(), ids.origRemote.toStringWithPort()); + + struct timespec ts; + gettime(&ts); + + struct dnsheader fake; + memset(&fake, 0, sizeof(fake)); + fake.id = ids.origID; + + g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits::max(), 0, fake, dss->remote, dss->getProtocol()); } - ids.du = nullptr; - handleDOHTimeout(DOHUnitUniquePtr(oldDU, DOHUnit::release)); - oldDU = nullptr; - ids.age = 0; - dss->reuseds++; - --dss->outstanding; - ++g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout - vinfolog("Had a downstream timeout from %s (%s) for query for %s|%s from %s", - dss->remote.toStringWithPort(), dss->getName(), - ids.qname.toLogString(), QType(ids.qtype).toString(), ids.origRemote.toStringWithPort()); - - struct timespec ts; - gettime(&ts); - - struct dnsheader fake; - memset(&fake, 0, sizeof(fake)); - fake.id = ids.origID; - - g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits::max(), 0, fake, dss->remote, dss->getProtocol()); } } -- 2.47.2