net-dns/dnsdist: add 2.0.2

- migrated build to meson
- upstream contributions
- backported performance fixes

Signed-off-by: Holger Hoffstätte <holger@applied-asynchrony.com>
Part-of: https://github.com/gentoo/gentoo/pull/44863
Signed-off-by: Sam James <sam@gentoo.org>
This commit is contained in:
Holger Hoffstätte
2025-12-02 14:18:21 +01:00
committed by Sam James
parent 7e9df3b1da
commit 93effd99eb
4 changed files with 553 additions and 0 deletions

View File

@@ -1,5 +1,8 @@
DIST dnsdist-1.9.10.tar.bz2 1598472 BLAKE2B ea66ca17ef66ecc64fd3a7379b22c2b0448c2a41f325e574a4edb20dfe408315be84a407b78f30a441479fbbcba31a28da2e310c275877739918ad3f9870acd1 SHA512 d7249861bb5454dce3d179701e1c686c5c5ed177ca39b07ca6b1f27d2ab7a014d0d255ee6b70153962dc5d9a84545ae4a4a55c53c8e75f308cda5406eed57e9b
DIST dnsdist-1.9.11.tar.bz2 1598511 BLAKE2B 54b197e625e10aa84238264e33b8df398d151645883586c778669741f96f21aee8b2242cec593e9ed2db19a134600cceb5eb69c193a1e527b6da4025b9658c73 SHA512 d1460051e4cc30c4df48f640dc18846ea68102227df3ef016cdb63c8ef62151ee99748c370dc3084aa06b9e2c902a9991db8d2134cded71dac18b1271d1bd2db
DIST dnsdist-2.0.1.tar.xz 2279512 BLAKE2B 6eee67a678ef1a044f60f8989befdcf84ce487bcbe03d2aedbb196b1393f7b5227e93ca25a56e4c400c4159e6e7ec1474e26311ae76c55116f438de234b724d7 SHA512 8e0b6b9d9db36e19c4617e79a36f86f8bc1a0096569dab0dc178ee9fa1b3af3b8baaa40252be9c7450a01e2d169a530edcc8f52e794e4efa649f5f0582b579d1
DIST dnsdist-2.0.2.tar.xz 2284864 BLAKE2B 87a4179f474d7f8117e4e03c4ff680f79207c8056765c6925ee21b3011e4555e47ad9c97950f30ab2876ac0978ee07555017cb1bbc6b93792992c1821f8da27a SHA512 7f53d13bb90b7b70da364341e50473b88be0bc9619e3263e352bed75aa57edbc018824439749956281a2c7a5d32c653e7378fe9d3cbc296042fa8120eee75fae
DIST dnsdist-docs-2.0.1.tar.xz 1382776 BLAKE2B 9b701e1c06118f242cf5fef019c015d5bd9608db893c1e708666d572cc8d0b3745f5bd935e76995e2894288a3d039aea9de6a409295ba096a72acd960d4e5507 SHA512 fc0ce707ec6dddf0057f8fd4bafe7513017b8e71e39b77e0525a67fbab68bbc1393490368eacad31ffccebebed156d0cc6ec646dbba30369ff67c63d71410057
DIST dnsdist-docs-2.0.2.tar.xz 1385828 BLAKE2B 79b4bb02f42f9bb3829fec6c6788ea2cc79c3f55d31b462e3c54d32f8afb0dfc84d8b347cbdae6cc3f9d8c9ebd1207a71f097f5201f14b9b2b6b20c72842d6b2 SHA512 ab73d30193bd99b4163962be5564c596fdd1d0c85c20d6606a70ed491ceb8ff801418aa7890c9ad2025ef3c9767f1d8252c0c18cfee5ebf9d845cce7e681f578
DIST dnsdist-rust-2.0.1-crates.tar.xz 5268364 BLAKE2B 36b370eacb7332d04de0fa1be2a49983c030c94df00abcc6681180b1ad5fa8bfe3e19744543b3707e305d57649837a632c1400fd4ae1b4626f084310db8f9bad SHA512 a9f1e10a71a9fb2e6879077224823dd278f1a27c5698076e69bc4bcdf89cff5e54ffd0fce90113131358398289400da263b90c895d167cb3c007fcc96654e116
DIST dnsdist-rust-2.0.2-crates.tar.xz 5268364 BLAKE2B 36b370eacb7332d04de0fa1be2a49983c030c94df00abcc6681180b1ad5fa8bfe3e19744543b3707e305d57649837a632c1400fd4ae1b4626f084310db8f9bad SHA512 a9f1e10a71a9fb2e6879077224823dd278f1a27c5698076e69bc4bcdf89cff5e54ffd0fce90113131358398289400da263b90c895d167cb3c007fcc96654e116

View File

@@ -0,0 +1,184 @@
# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
LUA_COMPAT=( lua5-{1..4} luajit )
PYTHON_COMPAT=( python3_{11..14} )
RUST_MIN_VER="1.85.1"
RUST_OPTIONAL=1
inherit cargo flag-o-matic lua-single meson python-any-r1 toolchain-funcs
DESCRIPTION="A highly DNS-, DoS- and abuse-aware loadbalancer"
HOMEPAGE="https://www.dnsdist.org/index.html"
if [[ ${PV} == *9999* ]] ; then
EGIT_REPO_URI="https://github.com/PowerDNS/pdns"
EGIT_BRANCH="master"
inherit git-r3
else
SRC_URI="https://downloads.powerdns.com/releases/${P}.tar.xz"
KEYWORDS="~amd64 ~x86"
fi
SRC_URI+="
doc? ( https://www.applied-asynchrony.com/distfiles/${PN}-docs-${PV}.tar.xz )
yaml? ( https://www.applied-asynchrony.com/distfiles/${PN}-rust-${PV}-crates.tar.xz )
"
LICENSE="GPL-2"
SLOT="0"
IUSE="bpf cdb dnscrypt dnstap doc doh doh3 ipcipher lmdb quic regex snmp +ssl systemd test web xdp yaml"
RESTRICT="!test? ( test )"
REQUIRED_USE="${LUA_REQUIRED_USE}
dnscrypt? ( ssl )
doh? ( ssl )
doh3? ( ssl quic )
ipcipher? ( ssl )
quic? ( ssl )"
RDEPEND="acct-group/dnsdist
acct-user/dnsdist
bpf? ( dev-libs/libbpf:= )
cdb? ( dev-db/tinycdb:= )
dev-libs/boost:=
sys-libs/libcap
dev-libs/libedit
dev-libs/libsodium:=
dnstap? ( dev-libs/fstrm )
doh? ( net-libs/nghttp2:= )
doh3? ( net-libs/quiche:= )
lmdb? ( dev-db/lmdb:= )
quic? ( net-libs/quiche )
regex? ( dev-libs/re2:= )
snmp? ( net-analyzer/net-snmp:= )
ssl? ( dev-libs/openssl:= )
systemd? ( sys-apps/systemd:0= )
xdp? ( net-libs/xdp-tools )
${LUA_DEPS}
"
DEPEND="${RDEPEND}"
BDEPEND="$(python_gen_any_dep 'dev-python/pyyaml[${PYTHON_USEDEP}]')
virtual/pkgconfig
yaml? ( ${RUST_DEPEND} )
"
# special requirements for live
if [[ ${PV} == *9999* ]] ; then
BDEPEND+=" dev-util/ragel"
S="${S}/pdns/dnsdistdist"
fi
PATCHES=(
"${FILESDIR}"/2.0.2-roundrobin-fast-path.patch
"${FILESDIR}"/2.0.2-speed-up-cache-hits.patch
)
pkg_setup() {
lua-single_pkg_setup
python-any-r1_pkg_setup
use yaml && rust_pkg_setup
}
python_check_deps() {
python_has_version "dev-python/pyyaml[${PYTHON_USEDEP}]"
}
# git-r3 overrides automatic SRC_URI unpacking
src_unpack() {
default
if [[ ${PV} == *9999* ]] ; then
git-r3_src_unpack
fi
}
src_prepare() {
default
# clean up duplicate file
rm -f README.md
}
src_configure() {
# bug #822855
append-lfs-flags
# There is currently no reliable way to handle mixed C++/Rust + LTO
# correctly: https://bugs.gentoo.org/963128
if use yaml && tc-is-lto ; then
ewarn "Disabling LTO because of mixed C++/Rust toolchains."
filter-lto
fi
# some things can only be enabled/disabled by defines
! use dnstap && append-cppflags -DDISABLE_PROTOBUF
! use web && append-cppflags -DDISABLE_BUILTIN_HTML
local emesonargs=(
--sysconfdir="${EPREFIX}/etc/dnsdist"
# always use libsodium
-Dlibsodium=enabled
-Dlua=${ELUA}
# never try to build man pages (virtualenv)
-Dman-pages=false
# never use gnutls (openssl only)
-Dtls-gnutls=disabled
$(meson_feature bpf ebpf)
$(meson_feature cdb)
$(meson_feature dnscrypt)
$(meson_feature dnstap)
$(meson_feature doh dns-over-https)
$(meson_feature doh nghttp2)
$(meson_feature doh3 dns-over-http3)
$(meson_feature ipcipher)
$(meson_feature lmdb)
$(meson_feature quic dns-over-quic)
$(meson_feature regex re2)
$(meson_feature snmp)
$(meson_feature ssl libcrypto)
$(meson_feature ssl tls-libssl)
$(meson_feature ssl dns-over-tls)
$(meson_feature systemd systemd-service)
$(meson_use test unit-tests)
$(meson_feature xdp xsk)
$(meson_feature yaml)
)
meson_src_configure
}
# explicitly implement src_compile/test to override the
# otherwise automagic cargo_src_compile/test phases
src_compile() {
cargo_gen_config
cargo_env meson_src_compile
}
src_test() {
meson_src_test
}
src_install() {
meson_src_install
use doc && dodoc -r "${WORKDIR}"/html
insinto /etc/dnsdist
doins "${FILESDIR}"/dnsdist.conf.example
newconfd "${FILESDIR}"/dnsdist.confd ${PN}
newinitd "${FILESDIR}"/dnsdist.initd ${PN}
}
pkg_postinst() {
elog "dnsdist provides multiple instances support. You can create more instances"
elog "by symlinking the dnsdist init script to another name."
elog
elog "The name must be in the format dnsdist.<suffix> and dnsdist will use the"
elog "/etc/dnsdist/dnsdist-<suffix>.conf configuration file instead of the default."
}

View File

@@ -0,0 +1,39 @@
Backport of:
https://github.com/PowerDNS/pdns/commit/495f8e5f1f2c147f7431c5a6bfd4f4606b640fe3
From: =?UTF-8?q?Holger=20Hoffst=C3=A4tte?= <holger@applied-asynchrony.com>
Date: Thu, 9 Oct 2025 22:04:07 +0200
Subject: [PATCH] dnsdist: add fast path to roundrobin load balancing policy
There is no need to collect all servers that are up when the current
server is already a good candidate. This avoids needless heap allocation
and deallocation in the vast majority of cases.
Signed-off-by: Holger Hoffstätte <holger@applied-asynchrony.com>
--- a/dnsdist-lbpolicies.cc
+++ b/dnsdist-lbpolicies.cc
@@ -237,6 +237,14 @@ shared_ptr<DownstreamState> roundrobin(c
return shared_ptr<DownstreamState>();
}
+ static std::atomic<unsigned int> counter{0};
+
+ size_t serverIdx = (counter++) % servers.size();
+ shared_ptr<DownstreamState> serverState = servers.at(serverIdx).second;
+ if (serverState->isUp()) {
+ return serverState;
+ }
+
vector<size_t> candidates;
candidates.reserve(servers.size());
@@ -255,8 +264,7 @@ shared_ptr<DownstreamState> roundrobin(c
}
}
- static std::atomic<unsigned int> counter{0};
- return servers.at(candidates.at((counter++) % candidates.size()) - 1).second;
+ return servers.at(candidates.at(counter % candidates.size()) - 1).second;
}
shared_ptr<DownstreamState> orderedWrandUntag(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dnsq)

View File

@@ -0,0 +1,327 @@
Backport of:
https://github.com/PowerDNS/pdns/commit/8cad5a2288c9a4af5e6269277483df250adfce52
From: Remi Gacogne <remi.gacogne@powerdns.com>
Date: Tue, 26 Aug 2025 14:00:26 +0200
Subject: [PATCH] dnsdist: Speed up cache hits by skipping the LB policy when possible
We use to execute the load-balancing policy to select a backend before
doing the cache lookup, because in some corner cases the selected
backend might have settings that impact our cache lookup. In practice
most configurations have a consistent set of settings for all servers
in a given pool, so it makes no sense to waste CPU cycles selecting a
backend if we are going to get a hit from the cache.
This PR adds a bit of code to check if a pool is in a consistent state,
and if it is it delays the execution of the load-balancing policy to
after the cache lookup, skipping it entirely for cache hits.
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
--- a/dnsdist-backend.cc
+++ b/dnsdist-backend.cc
@@ -1049,6 +1049,18 @@ size_t ServerPool::poolLoad()
return load;
}
+bool ServerPool::hasAtLeastOneServerAvailable()
+{
+ auto servers = d_servers.read_lock();
+ // NOLINTNEXTLINE(readability-use-anyofallof): no it's not more readable
+ for (const auto& server : **servers) {
+ if (std::get<1>(server)->isUp()) {
+ return true;
+ }
+ }
+ return false;
+}
+
const std::shared_ptr<const ServerPolicy::NumberedServerVector> ServerPool::getServers()
{
std::shared_ptr<const ServerPolicy::NumberedServerVector> result;
@@ -1060,59 +1072,117 @@ const std::shared_ptr<const ServerPolicy::NumberedServerVector> ServerPool::getS
void ServerPool::addServer(shared_ptr<DownstreamState>& server)
{
- auto servers = d_servers.write_lock();
- /* we can't update the content of the shared pointer directly even when holding the lock,
- as other threads might hold a copy. We can however update the pointer as long as we hold the lock. */
- unsigned int count = static_cast<unsigned int>((*servers)->size());
- auto newServers = ServerPolicy::NumberedServerVector(*(*servers));
- newServers.emplace_back(++count, server);
- /* we need to reorder based on the server 'order' */
- std::stable_sort(newServers.begin(), newServers.end(), [](const std::pair<unsigned int,std::shared_ptr<DownstreamState> >& a, const std::pair<unsigned int,std::shared_ptr<DownstreamState> >& b) {
- return a.second->d_config.order < b.second->d_config.order;
+ {
+ auto servers = d_servers.write_lock();
+ /* we can't update the content of the shared pointer directly even when holding the lock,
+ as other threads might hold a copy. We can however update the pointer as long as we hold the lock. */
+ auto count = static_cast<unsigned int>((*servers)->size());
+ auto newServers = ServerPolicy::NumberedServerVector(*(*servers));
+ newServers.emplace_back(++count, server);
+ /* we need to reorder based on the server 'order' */
+ std::stable_sort(newServers.begin(), newServers.end(), [](const std::pair<unsigned int,std::shared_ptr<DownstreamState> >& lhs, const std::pair<unsigned int,std::shared_ptr<DownstreamState> >& rhs) {
+ return lhs.second->d_config.order < rhs.second->d_config.order;
});
- /* and now we need to renumber for Lua (custom policies) */
- size_t idx = 1;
- for (auto& serv : newServers) {
- serv.first = idx++;
- }
- *servers = std::make_shared<const ServerPolicy::NumberedServerVector>(std::move(newServers));
+ /* and now we need to renumber for Lua (custom policies) */
+ size_t idx = 1;
+ for (auto& serv : newServers) {
+ serv.first = idx++;
+ }
+ *servers = std::make_shared<const ServerPolicy::NumberedServerVector>(std::move(newServers));
- if ((*servers)->size() == 1) {
- d_tcpOnly = server->isTCPOnly();
- }
- else if (!server->isTCPOnly()) {
- d_tcpOnly = false;
+ if ((*servers)->size() == 1) {
+ d_tcpOnly = server->isTCPOnly();
+ }
+ else if (!server->isTCPOnly()) {
+ d_tcpOnly = false;
+ }
}
+
+ updateConsistency();
}
void ServerPool::removeServer(shared_ptr<DownstreamState>& server)
{
- auto servers = d_servers.write_lock();
- /* we can't update the content of the shared pointer directly even when holding the lock,
- as other threads might hold a copy. We can however update the pointer as long as we hold the lock. */
- auto newServers = std::make_shared<ServerPolicy::NumberedServerVector>(*(*servers));
size_t idx = 1;
bool found = false;
- bool tcpOnly = true;
- for (auto it = newServers->begin(); it != newServers->end();) {
+ {
+ auto servers = d_servers.write_lock();
+ /* we can't update the content of the shared pointer directly even when holding the lock,
+ as other threads might hold a copy. We can however update the pointer as long as we hold the lock. */
+ auto newServers = std::make_shared<ServerPolicy::NumberedServerVector>(*(*servers));
+
+ for (auto it = newServers->begin(); it != newServers->end();) {
+ if (found) {
+ /* we need to renumber the servers placed
+ after the removed one, for Lua (custom policies) */
+ it->first = idx++;
+ it++;
+ }
+ else if (it->second == server) {
+ it = newServers->erase(it);
+ found = true;
+ } else {
+ idx++;
+ it++;
+ }
+ }
+
if (found) {
- tcpOnly = tcpOnly && it->second->isTCPOnly();
- /* we need to renumber the servers placed
- after the removed one, for Lua (custom policies) */
- it->first = idx++;
- it++;
+ *servers = std::move(newServers);
+ }
+ }
+
+ if (found && !d_isConsistent) {
+ updateConsistency();
+ }
+}
+
+void ServerPool::updateConsistency()
+{
+ bool first{true};
+ bool useECS{false};
+ bool tcpOnly{false};
+ bool disableZeroScope{false};
+
+ auto servers = d_servers.read_lock();
+ for (const auto& serverPair : **servers) {
+ const auto& server = serverPair.second;
+ if (first) {
+ first = false;
+ useECS = server->d_config.useECS;
+ tcpOnly = server->isTCPOnly();
+ disableZeroScope = server->d_config.disableZeroScope;
}
- else if (it->second == server) {
- it = newServers->erase(it);
- found = true;
- } else {
- tcpOnly = tcpOnly && it->second->isTCPOnly();
- idx++;
- it++;
+ else {
+ if (server->d_config.useECS != useECS ||
+ server->isTCPOnly() != tcpOnly ||
+ server->d_config.disableZeroScope != disableZeroScope) {
+ d_tcpOnly = false;
+ d_isConsistent = false;
+ return;
+ }
}
}
+
d_tcpOnly = tcpOnly;
- *servers = std::move(newServers);
+ /* at this point we know that all servers agree
+ on these settings, so let's just use the same
+ values for the pool itself */
+ d_useECS = useECS;
+ d_disableZeroScope = disableZeroScope;
+ d_isConsistent = true;
+}
+
+void ServerPool::setDisableZeroScope(bool disable)
+{
+ d_disableZeroScope = disable;
+ updateConsistency();
+}
+
+void ServerPool::setECS(bool useECS)
+{
+ d_useECS = useECS;
+ updateConsistency();
}
namespace dnsdist::backend
--- a/dnsdist-lua-bindings.cc
+++ b/dnsdist-lua-bindings.cc
@@ -107,6 +107,8 @@ void setupLuaBindings(LuaContext& luaCtx, bool client, bool configCheck)
});
luaCtx.registerFunction("getECS", &ServerPool::getECS);
luaCtx.registerFunction("setECS", &ServerPool::setECS);
+ luaCtx.registerFunction("getDisableZeroScope", &ServerPool::getDisableZeroScope);
+ luaCtx.registerFunction("setDisableZeroScope", &ServerPool::setDisableZeroScope);
#ifndef DISABLE_DOWNSTREAM_BINDINGS
/* DownstreamState */
--- a/dnsdist-settings-definitions.yml
+++ b/dnsdist-settings-definitions.yml
@@ -2040,6 +2040,14 @@ pool:
type: "String"
default: ""
description: "The name of the load-balancing policy associated to this pool. If left empty, the global policy will be used"
+ - name: "use_ecs"
+ type: "bool"
+ default: "false"
+ description: "Whether to add EDNS Client Subnet information to the query before looking up into the cache, when all servers from this pool are down. If at least one server is up, the preference of the selected server is used, this parameter is only useful if all the backends in this pool are down and have EDNS Client Subnet enabled, since the queries in the cache will have been inserted with ECS information"
+ - name: "disable_zero_scope"
+ type: "bool"
+ default: "false"
+ description: "Whether to disable the EDNS Client Subnet :doc:`../advanced/zero-scope` feature, which does a cache lookup for an answer valid for all subnets (ECS scope of 0) before adding ECS information to the query and doing the regular lookup, when all servers from this pool are down. If at least one server is up, the preference of the selected server is used, this parameter is only useful if all the backends in this pool are down, have EDNS Client Subnet enabled and zero scope disabled"
custom_load_balancing_policy:
description: "Settings for a custom load-balancing policy"
--- a/dnsdist.cc
+++ b/dnsdist.cc
@@ -1441,7 +1441,13 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dnsQuestion, std::shared_
}
std::shared_ptr<ServerPool> serverPool = getPool(dnsQuestion.ids.poolName);
dnsQuestion.ids.packetCache = serverPool->packetCache;
- selectBackendForOutgoingQuery(dnsQuestion, serverPool, selectedBackend);
+
+ bool backendLookupDone = false;
+ if (!dnsQuestion.ids.packetCache || !serverPool->isConsistent()) {
+ selectBackendForOutgoingQuery(dnsQuestion, serverPool, selectedBackend);
+ backendLookupDone = true;
+ }
+
bool willBeForwardedOverUDP = !dnsQuestion.overTCP() || dnsQuestion.ids.protocol == dnsdist::Protocol::DoH;
if (selectedBackend && selectedBackend->isTCPOnly()) {
willBeForwardedOverUDP = false;
@@ -1450,17 +1456,22 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dnsQuestion, std::shared_
willBeForwardedOverUDP = !serverPool->isTCPOnly();
}
- uint32_t allowExpired = selectedBackend ? 0 : dnsdist::configuration::getCurrentRuntimeConfiguration().d_staleCacheEntriesTTL;
+ uint32_t allowExpired = 0;
+ if (!selectedBackend && dnsdist::configuration::getCurrentRuntimeConfiguration().d_staleCacheEntriesTTL > 0 && (backendLookupDone || !serverPool->hasAtLeastOneServerAvailable())) {
+ allowExpired = dnsdist::configuration::getCurrentRuntimeConfiguration().d_staleCacheEntriesTTL;
+ }
if (dnsQuestion.ids.packetCache && !dnsQuestion.ids.skipCache && !dnsQuestion.ids.dnssecOK) {
dnsQuestion.ids.dnssecOK = (dnsdist::getEDNSZ(dnsQuestion) & EDNS_HEADER_FLAG_DO) != 0;
}
- if (dnsQuestion.useECS && ((selectedBackend && selectedBackend->d_config.useECS) || (!selectedBackend && serverPool->getECS()))) {
+ const bool useECS = dnsQuestion.useECS && ((selectedBackend && selectedBackend->d_config.useECS) || (!selectedBackend && serverPool->getECS()));
+ if (useECS) {
+ const bool useZeroScope = (selectedBackend && !selectedBackend->d_config.disableZeroScope) || (!selectedBackend && !serverPool->getDisableZeroScope());
// we special case our cache in case a downstream explicitly gave us a universally valid response with a 0 scope
// we need ECS parsing (parseECS) to be true so we can be sure that the initial incoming query did not have an existing
// ECS option, which would make it unsuitable for the zero-scope feature.
- if (dnsQuestion.ids.packetCache && !dnsQuestion.ids.skipCache && (!selectedBackend || !selectedBackend->d_config.disableZeroScope) && dnsQuestion.ids.packetCache->isECSParsingEnabled()) {
+ if (dnsQuestion.ids.packetCache && !dnsQuestion.ids.skipCache && useZeroScope && dnsQuestion.ids.packetCache->isECSParsingEnabled()) {
if (dnsQuestion.ids.packetCache->get(dnsQuestion, dnsQuestion.getHeader()->id, &dnsQuestion.ids.cacheKeyNoECS, dnsQuestion.ids.subnet, *dnsQuestion.ids.dnssecOK, willBeForwardedOverUDP, allowExpired, false, true, false)) {
vinfolog("Packet cache hit for query for %s|%s from %s (%s, %d bytes)", dnsQuestion.ids.qname.toLogString(), QType(dnsQuestion.ids.qtype).toString(), dnsQuestion.ids.origRemote.toStringWithPort(), dnsQuestion.ids.protocol.toString(), dnsQuestion.getData().size());
@@ -1543,9 +1554,14 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dnsQuestion, std::shared_
serverPool = getPool(dnsQuestion.ids.poolName);
dnsQuestion.ids.packetCache = serverPool->packetCache;
selectBackendForOutgoingQuery(dnsQuestion, serverPool, selectedBackend);
+ backendLookupDone = true;
}
}
+ if (!backendLookupDone) {
+ selectBackendForOutgoingQuery(dnsQuestion, serverPool, selectedBackend);
+ }
+
if (!selectedBackend) {
auto servFailOnNoPolicy = dnsdist::configuration::getCurrentRuntimeConfiguration().d_servFailOnNoPolicy;
++dnsdist::metrics::g_stats.noPolicy;
--- a/dnsdist.hh
+++ b/dnsdist.hh
@@ -951,9 +951,18 @@ struct ServerPool
return d_useECS;
}
- void setECS(bool useECS)
+ void setECS(bool useECS);
+
+ bool getDisableZeroScope() const
+ {
+ return d_disableZeroScope;
+ }
+
+ void setDisableZeroScope(bool disable);
+
+ bool isConsistent() const
{
- d_useECS = useECS;
+ return d_isConsistent;
}
std::shared_ptr<DNSDistPacketCache> packetCache{nullptr};
@@ -961,6 +970,7 @@ struct ServerPool
size_t poolLoad();
size_t countServers(bool upOnly);
+ bool hasAtLeastOneServerAvailable();
const std::shared_ptr<const ServerPolicy::NumberedServerVector> getServers();
void addServer(shared_ptr<DownstreamState>& server);
void removeServer(shared_ptr<DownstreamState>& server);
@@ -971,9 +981,13 @@ struct ServerPool
}
private:
+ void updateConsistency();
+
SharedLockGuarded<std::shared_ptr<const ServerPolicy::NumberedServerVector>> d_servers;
bool d_useECS{false};
bool d_tcpOnly{false};
+ bool d_disableZeroScope{false};
+ bool d_isConsistent{true};
};
enum ednsHeaderFlags