]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Refactor frontend configuration
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 18 Jun 2024 14:07:51 +0000 (16:07 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 15 Jul 2024 09:47:56 +0000 (11:47 +0200)
13 files changed:
pdns/dnsdistdist/Makefile.am
pdns/dnsdistdist/dnsdist-carbon.cc
pdns/dnsdistdist/dnsdist-configuration.hh
pdns/dnsdistdist/dnsdist-frontend.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-frontend.hh [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-bindings.cc
pdns/dnsdistdist/dnsdist-lua-inspection.cc
pdns/dnsdistdist/dnsdist-lua.cc
pdns/dnsdistdist/dnsdist-svc.cc
pdns/dnsdistdist/dnsdist-web.cc
pdns/dnsdistdist/dnsdist.cc
pdns/dnsdistdist/dnsdist.hh
pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc

index 0e85df5c990a2468fecefeb7300aaf15f7bdff50..19e57742ee291f3ca3d23d8e9037a4e6a4beb345 100644 (file)
@@ -162,6 +162,7 @@ dnsdist_SOURCES = \
        dnsdist-dynbpf.cc dnsdist-dynbpf.hh \
        dnsdist-ecs.cc dnsdist-ecs.hh \
        dnsdist-edns.cc dnsdist-edns.hh \
+       dnsdist-frontend.cc dnsdist-frontend.hh \
        dnsdist-healthchecks.cc dnsdist-healthchecks.hh \
        dnsdist-idstate.cc dnsdist-idstate.hh \
        dnsdist-internal-queries.cc dnsdist-internal-queries.hh \
@@ -285,6 +286,7 @@ testrunner_SOURCES = \
        dnsdist-dynbpf.cc dnsdist-dynbpf.hh \
        dnsdist-ecs.cc dnsdist-ecs.hh \
        dnsdist-edns.cc dnsdist-edns.hh \
+       dnsdist-frontend.cc dnsdist-frontend.hh \
        dnsdist-idstate.cc dnsdist-idstate.hh \
        dnsdist-kvs.cc dnsdist-kvs.hh \
        dnsdist-lbpolicies.cc dnsdist-lbpolicies.hh \
index 76b35e8f5131a6b05706090411f8e1a16e2dd5ac..6fa97a5341efef7e9c8756059797da68639403f2 100644 (file)
@@ -27,6 +27,7 @@
 #include "dnsdist.hh"
 #include "dnsdist-backoff.hh"
 #include "dnsdist-configuration.hh"
+#include "dnsdist-frontend.hh"
 #include "dnsdist-metrics.hh"
 
 #ifndef DISABLE_CARBON
@@ -113,7 +114,7 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint)
     }
 
     std::map<std::string, uint64_t> frontendDuplicates;
-    for (const auto& front : g_frontends) {
+    for (const auto& front : dnsdist::getFrontends()) {
       if (front->udpFD == -1 && front->tcpFD == -1) {
         continue;
       }
@@ -222,7 +223,7 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint)
     {
       std::map<std::string, uint64_t> dohFrontendDuplicates;
       const string base = "dnsdist." + hostname + ".main.doh.";
-      for (const auto& doh : g_dohlocals) {
+      for (const auto& doh : dnsdist::getDoHFrontends()) {
         string name = doh->d_tlsContext.d_addr.toStringWithPort();
         boost::replace_all(name, ".", "_");
         boost::replace_all(name, ":", "_");
index a102fb6db5e629604a7586cc873e56121cffa702..bca05ef2a0e37f7e77cbf7431a8020fc5c20c7ce 100644 (file)
@@ -143,6 +143,7 @@ public:
 class ServerPolicy;
 struct ServerPool;
 struct DownstreamState;
+struct ClientState;
 
 using servers_t = std::vector<std::shared_ptr<DownstreamState>>;
 
@@ -161,6 +162,7 @@ struct Configuration
 {
   std::set<std::string> d_capabilitiesToRetain;
   std::vector<uint32_t> d_tcpFastOpenKey;
+  std::vector<std::shared_ptr<ClientState>> d_frontends;
 #ifdef __linux__
   // On Linux this gives us 128k pending queries (default is 8192 queries),
   // which should be enough to deal with huge spikes
diff --git a/pdns/dnsdistdist/dnsdist-frontend.cc b/pdns/dnsdistdist/dnsdist-frontend.cc
new file mode 100644 (file)
index 0000000..20bef4e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "dnsdist-frontend.hh"
+#include "dnsdist.hh"
+
+namespace dnsdist
+{
+
+const std::vector<std::shared_ptr<ClientState>>& getFrontends()
+{
+  return dnsdist::configuration::getImmutableConfiguration().d_frontends;
+}
+
+std::vector<std::shared_ptr<DNSCryptContext>> getDNSCryptFrontends()
+{
+  std::vector<std::shared_ptr<DNSCryptContext>> results;
+  for (const auto& frontend : getFrontends()) {
+    if (frontend->getProtocol() == dnsdist::Protocol::DNSCryptUDP || frontend->getProtocol() == dnsdist::Protocol::DNSCryptTCP) {
+      results.push_back(frontend->dnscryptCtx);
+    }
+  }
+  return results;
+}
+
+std::vector<std::shared_ptr<TLSFrontend>> getDoTFrontends()
+{
+  std::vector<std::shared_ptr<TLSFrontend>> results;
+  for (const auto& frontend : getFrontends()) {
+    if (frontend->getProtocol() == dnsdist::Protocol::DoT) {
+      results.push_back(frontend->tlsFrontend);
+    }
+  }
+  return results;
+}
+
+std::vector<std::shared_ptr<DOHFrontend>> getDoHFrontends()
+{
+  std::vector<std::shared_ptr<DOHFrontend>> results;
+  for (const auto& frontend : getFrontends()) {
+    if (frontend->getProtocol() == dnsdist::Protocol::DoH) {
+      results.push_back(frontend->dohFrontend);
+    }
+  }
+  return results;
+}
+
+std::vector<std::shared_ptr<DOQFrontend>> getDoQFrontends()
+{
+  std::vector<std::shared_ptr<DOQFrontend>> results;
+  for (const auto& frontend : getFrontends()) {
+    if (frontend->getProtocol() == dnsdist::Protocol::DoQ) {
+      results.push_back(frontend->doqFrontend);
+    }
+  }
+  return results;
+}
+
+std::vector<std::shared_ptr<DOH3Frontend>> getDoH3Frontends()
+{
+  std::vector<std::shared_ptr<DOH3Frontend>> results;
+  for (const auto& frontend : getFrontends()) {
+    if (frontend->getProtocol() == dnsdist::Protocol::DoH3) {
+      results.push_back(frontend->doh3Frontend);
+    }
+  }
+  return results;
+}
+}
diff --git a/pdns/dnsdistdist/dnsdist-frontend.hh b/pdns/dnsdistdist/dnsdist-frontend.hh
new file mode 100644 (file)
index 0000000..fe7f1c2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+
+#include <memory>
+#include <vector>
+
+struct ClientState;
+class DNSCryptContext;
+class TLSFrontend;
+struct DOHFrontend;
+struct DOQFrontend;
+struct DOH3Frontend;
+
+namespace dnsdist
+{
+const std::vector<std::shared_ptr<ClientState>>& getFrontends();
+std::vector<std::shared_ptr<DNSCryptContext>> getDNSCryptFrontends();
+std::vector<std::shared_ptr<TLSFrontend>> getDoTFrontends();
+std::vector<std::shared_ptr<DOHFrontend>> getDoHFrontends();
+std::vector<std::shared_ptr<DOQFrontend>> getDoQFrontends();
+std::vector<std::shared_ptr<DOH3Frontend>> getDoH3Frontends();
+}
index bcec30e71297c4b090d6253a1b272866392c0492..eaf7a2a1a39a419073f946e387c0077f69094958 100644 (file)
@@ -23,6 +23,7 @@
 #include "config.h"
 #include "dnsdist.hh"
 #include "dnsdist-async.hh"
+#include "dnsdist-frontend.hh"
 #include "dnsdist-lua.hh"
 #include "dnsdist-resolver.hh"
 #include "dnsdist-svc.hh"
@@ -673,7 +674,7 @@ void setupLuaBindings(LuaContext& luaCtx, bool client, bool configCheck)
       return;
     }
     if (bpf) {
-      for (const auto& frontend : g_frontends) {
+      for (const auto& frontend : dnsdist::getFrontends()) {
         frontend->attachFilter(bpf, frontend->getSocket());
       }
     }
index ff3ba6090927db4fa9ad619a0918903926da2a2a..43d7e9b0828bb674dd76cef15398673a05e2bd2e 100644 (file)
@@ -24,6 +24,7 @@
 #include "dnsdist.hh"
 #include "dnsdist-console.hh"
 #include "dnsdist-dynblocks.hh"
+#include "dnsdist-frontend.hh"
 #include "dnsdist-lua.hh"
 #include "dnsdist-nghttp2.hh"
 #include "dnsdist-rings.hh"
@@ -732,7 +733,7 @@ void setupLuaInspection(LuaContext& luaCtx)
     ret << (fmt % "#" % "Address" % "Connections" % "Max concurrent conn" % "Died reading query" % "Died sending response" % "Gave up" % "Client timeouts" % "Downstream timeouts" % "Avg queries/conn" % "Avg duration" % "TLS new sessions" % "TLS Resumptions" % "TLS unknown ticket keys" % "TLS inactive ticket keys" % "TLS 1.0" % "TLS 1.1" % "TLS 1.2" % "TLS 1.3" % "TLS other") << endl;
 
     size_t counter = 0;
-    for (const auto& frontend : g_frontends) {
+    for (const auto& frontend : dnsdist::getFrontends()) {
       ret << (fmt % counter % frontend->local.toStringWithPort() % frontend->tcpCurrentConnections % frontend->tcpMaxConcurrentConnections % frontend->tcpDiedReadingQuery % frontend->tcpDiedSendingResponse % frontend->tcpGaveUp % frontend->tcpClientTimeouts % frontend->tcpDownstreamTimeouts % frontend->tcpAvgQueriesPerConnection % frontend->tcpAvgConnectionDuration % frontend->tlsNewSessions % frontend->tlsResumptions % frontend->tlsUnknownTicketKey % frontend->tlsInactiveTicketKey % frontend->tls10queries % frontend->tls11queries % frontend->tls12queries % frontend->tls13queries % frontend->tlsUnknownqueries) << endl;
       ++counter;
     }
@@ -759,7 +760,7 @@ void setupLuaInspection(LuaContext& luaCtx)
     ret << (fmt % "#" % "Address" % "DH key too small" % "Inappropriate fallback" % "No shared cipher" % "Unknown cipher type" % "Unknown exchange type" % "Unknown protocol" % "Unsupported EC" % "Unsupported protocol") << endl;
 
     size_t counter = 0;
-    for (const auto& frontend : g_frontends) {
+    for (const auto& frontend : dnsdist::getFrontends()) {
       if (!frontend->hasTLS()) {
         continue;
       }
index 3313a2f9350503aee03275b193a334e859122a01..d66e4c6eb8ef6db220171f0dd8a69964e2fed922 100644 (file)
@@ -46,6 +46,7 @@
 #include "dnsdist-dynblocks.hh"
 #include "dnsdist-discovery.hh"
 #include "dnsdist-ecs.hh"
+#include "dnsdist-frontend.hh"
 #include "dnsdist-healthchecks.hh"
 #include "dnsdist-lua.hh"
 #include "dnsdist-lua-hooks.hh"
@@ -982,12 +983,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
     parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections, enableProxyProtocol);
 
+    auto frontends = dnsdist::configuration::getImmutableConfiguration().d_frontends;
     try {
       ComboAddress loc(addr, 53);
-      for (auto it = g_frontends.begin(); it != g_frontends.end();) {
+      for (auto it = frontends.begin(); it != frontends.end();) {
         /* DoH, DoT and DNSCrypt frontends are separate */
         if ((*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr && (*it)->dohFrontend == nullptr) {
-          it = g_frontends.erase(it);
+          it = frontends.erase(it);
         }
         else {
           ++it;
@@ -995,8 +997,8 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       }
 
       // only works pre-startup, so no sync necessary
-      auto udpCS = std::make_unique<ClientState>(loc, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
-      auto tcpCS = std::make_unique<ClientState>(loc, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      auto udpCS = std::make_shared<ClientState>(loc, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      auto tcpCS = std::make_shared<ClientState>(loc, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
       if (tcpListenQueueSize > 0) {
         tcpCS->tcpListenQueueSize = tcpListenQueueSize;
       }
@@ -1019,10 +1021,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
         vinfolog("Enabling XSK in %s mode for incoming UDP packets to %s", socket->getXDPMode(), loc.toStringWithPort());
       }
 #endif /* HAVE_XSK */
-      g_frontends.push_back(std::move(udpCS));
-      g_frontends.push_back(std::move(tcpCS));
+      frontends.push_back(std::move(udpCS));
+      frontends.push_back(std::move(tcpCS));
 
       checkAllParametersConsumed("setLocal", vars);
+      dnsdist::configuration::updateImmutableConfiguration([&frontends](dnsdist::configuration::Configuration& config) {
+        config.d_frontends = std::move(frontends);
+      });
     }
     catch (const std::exception& e) {
       g_outputBuffer = "Error: " + string(e.what()) + "\n";
@@ -1052,8 +1057,8 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     try {
       ComboAddress loc(addr, 53);
       // only works pre-startup, so no sync necessary
-      auto udpCS = std::make_unique<ClientState>(loc, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
-      auto tcpCS = std::make_unique<ClientState>(loc, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      auto udpCS = std::make_shared<ClientState>(loc, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      auto tcpCS = std::make_shared<ClientState>(loc, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
       if (tcpListenQueueSize > 0) {
         tcpCS->tcpListenQueueSize = tcpListenQueueSize;
       }
@@ -1075,8 +1080,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
         vinfolog("Enabling XSK in %s mode for incoming UDP packets to %s", socket->getXDPMode(), loc.toStringWithPort());
       }
 #endif /* HAVE_XSK */
-      g_frontends.push_back(std::move(udpCS));
-      g_frontends.push_back(std::move(tcpCS));
+      dnsdist::configuration::updateImmutableConfiguration([&udpCS, &tcpCS](dnsdist::configuration::Configuration& config) {
+        config.d_frontends.push_back(std::move(udpCS));
+        config.d_frontends.push_back(std::move(tcpCS));
+      });
 
       checkAllParametersConsumed("addLocal", vars);
     }
@@ -1147,10 +1154,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 #if 0
     // Useful for debugging leaks, but might lead to race under load
     // since other threads are still running.
-    for (auto& frontend : g_tlslocals) {
+    for (auto& frontend : getDoTFrontends()) {
       frontend->cleanup();
     }
-    g_tlslocals.clear();
     g_rings.clear();
 #endif /* 0 */
     pdns::coverage::dumpCoverageData();
@@ -1769,13 +1775,15 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       auto ctx = std::make_shared<DNSCryptContext>(providerName, certKeys);
 
       /* UDP */
-      auto clientState = std::make_unique<ClientState>(ComboAddress(addr, 443), false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      auto clientState = std::make_shared<ClientState>(ComboAddress(addr, 443), false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
       clientState->dnscryptCtx = ctx;
-      g_dnsCryptLocals.push_back(ctx);
-      g_frontends.push_back(std::move(clientState));
+
+      dnsdist::configuration::updateImmutableConfiguration([&clientState](dnsdist::configuration::Configuration& config) {
+        config.d_frontends.push_back(std::move(clientState));
+      });
 
       /* TCP */
-      clientState = std::make_unique<ClientState>(ComboAddress(addr, 443), true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      clientState = std::make_shared<ClientState>(ComboAddress(addr, 443), true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
       clientState->dnscryptCtx = std::move(ctx);
       if (tcpListenQueueSize > 0) {
         clientState->tcpListenQueueSize = tcpListenQueueSize;
@@ -1787,7 +1795,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
         clientState->d_tcpConcurrentConnectionsLimit = tcpMaxConcurrentConnections;
       }
 
-      g_frontends.push_back(std::move(clientState));
+      dnsdist::configuration::updateImmutableConfiguration([&clientState](dnsdist::configuration::Configuration& config) {
+        config.d_frontends.push_back(std::move(clientState));
+      });
     }
     catch (const std::exception& e) {
       errlog("Error during addDNSCryptBind() processing: %s", e.what());
@@ -1803,7 +1813,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     size_t idx = 0;
 
     std::unordered_set<std::shared_ptr<DNSCryptContext>> contexts;
-    for (const auto& frontend : g_frontends) {
+    for (const auto& frontend : dnsdist::getFrontends()) {
       const std::shared_ptr<DNSCryptContext> ctx = frontend->dnscryptCtx;
       if (!ctx || contexts.count(ctx) != 0) {
         continue;
@@ -1819,15 +1829,16 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
   luaCtx.writeFunction("getDNSCryptBind", [](uint64_t idx) {
     setLuaNoSideEffect();
     std::shared_ptr<DNSCryptContext> ret = nullptr;
-    if (idx < g_dnsCryptLocals.size()) {
-      ret = g_dnsCryptLocals.at(idx);
+    auto frontends = dnsdist::getDNSCryptFrontends();
+    if (idx < frontends.size()) {
+      ret = frontends.at(idx);
     }
     return ret;
   });
 
   luaCtx.writeFunction("getDNSCryptBindCount", []() {
     setLuaNoSideEffect();
-    return g_dnsCryptLocals.size();
+    return dnsdist::getDNSCryptFrontends().size();
   });
 #endif /* HAVE_DNSCRYPT */
 
@@ -1936,7 +1947,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       ret << (fmt % "#" % "Address" % "Protocol" % "Queries") << endl;
 
       size_t counter = 0;
-      for (const auto& front : g_frontends) {
+      for (const auto& front : dnsdist::getFrontends()) {
         ret << (fmt % counter % front->local.toStringWithPort() % front->getType() % front->queries) << endl;
         counter++;
       }
@@ -1951,15 +1962,16 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
   luaCtx.writeFunction("getBind", [](uint64_t num) {
     setLuaNoSideEffect();
     ClientState* ret = nullptr;
-    if (num < g_frontends.size()) {
-      ret = g_frontends[num].get();
+    auto frontends = dnsdist::getFrontends();
+    if (num < frontends.size()) {
+      ret = frontends[num].get();
     }
     return ret;
   });
 
   luaCtx.writeFunction("getBindCount", []() {
     setLuaNoSideEffect();
-    return g_frontends.size();
+    return dnsdist::getFrontends().size();
   });
 
   luaCtx.writeFunction("help", [](boost::optional<std::string> command) {
@@ -2554,8 +2566,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       }
     }
 
-    g_dohlocals.push_back(frontend);
-    auto clientState = std::make_unique<ClientState>(frontend->d_tlsContext.d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+    auto clientState = std::make_shared<ClientState>(frontend->d_tlsContext.d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
     clientState->dohFrontend = std::move(frontend);
     clientState->d_additionalAddresses = std::move(additionalAddresses);
 
@@ -2565,7 +2576,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     if (tcpMaxConcurrentConnections > 0) {
       clientState->d_tcpConcurrentConnectionsLimit = tcpMaxConcurrentConnections;
     }
-    g_frontends.push_back(std::move(clientState));
+
+    dnsdist::configuration::updateImmutableConfiguration([&clientState](dnsdist::configuration::Configuration& config) {
+      config.d_frontends.push_back(std::move(clientState));
+    });
 #else /* HAVE_DNS_OVER_HTTPS */
       throw std::runtime_error("addDOHLocal() called but DNS over HTTPS support is not present!");
 #endif /* HAVE_DNS_OVER_HTTPS */
@@ -2635,12 +2649,14 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
       checkAllParametersConsumed("addDOH3Local", vars);
     }
-    g_doh3locals.push_back(frontend);
-    auto clientState = std::make_unique<ClientState>(frontend->d_local, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+
+    auto clientState = std::make_shared<ClientState>(frontend->d_local, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
     clientState->doh3Frontend = frontend;
     clientState->d_additionalAddresses = std::move(additionalAddresses);
 
-    g_frontends.push_back(std::move(clientState));
+    dnsdist::configuration::updateImmutableConfiguration([&clientState](dnsdist::configuration::Configuration& config) {
+      config.d_frontends.push_back(std::move(clientState));
+    });
 #else
       throw std::runtime_error("addDOH3Local() called but DNS over HTTP/3 support is not present!");
 #endif
@@ -2710,12 +2726,14 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
       checkAllParametersConsumed("addDOQLocal", vars);
     }
-    g_doqlocals.push_back(frontend);
-    auto clientState = std::make_unique<ClientState>(frontend->d_local, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+
+    auto clientState = std::make_shared<ClientState>(frontend->d_local, false, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
     clientState->doqFrontend = std::move(frontend);
     clientState->d_additionalAddresses = std::move(additionalAddresses);
 
-    g_frontends.push_back(std::move(clientState));
+    dnsdist::configuration::updateImmutableConfiguration([&clientState](dnsdist::configuration::Configuration& config) {
+      config.d_frontends.push_back(std::move(clientState));
+    });
 #else
       throw std::runtime_error("addDOQLocal() called but DNS over QUIC support is not present!");
 #endif
@@ -2729,7 +2747,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       boost::format fmt("%-3d %-20.20s %-15d %-15d %-15d %-15d");
       ret << (fmt % "#" % "Address" % "Bad Version" % "Invalid Token" % "Errors" % "Valid") << endl;
       size_t counter = 0;
-      for (const auto& ctx : g_doqlocals) {
+      for (const auto& ctx : dnsdist::getDoQFrontends()) {
         ret << (fmt % counter % ctx->d_local.toStringWithPort() % ctx->d_doqUnsupportedVersionErrors % ctx->d_doqInvalidTokensReceived % ctx->d_errorResponses % ctx->d_validResponses) << endl;
         counter++;
       }
@@ -2752,12 +2770,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     }
     setLuaNoSideEffect();
     try {
-      if (index < g_doqlocals.size()) {
-        result = g_doqlocals.at(index);
+      auto doqFrontends = dnsdist::getDoQFrontends();
+      if (index < doqFrontends.size()) {
+        result = doqFrontends.at(index);
       }
       else {
-        errlog("Error: trying to get DOQ frontend with index %d but we only have %d frontend(s)\n", index, g_doqlocals.size());
-        g_outputBuffer = "Error: trying to get DOQ frontend with index " + std::to_string(index) + " but we only have " + std::to_string(g_doqlocals.size()) + " frontend(s)\n";
+        errlog("Error: trying to get DOQ frontend with index %d but we only have %d frontend(s)\n", index, doqFrontends.size());
+        g_outputBuffer = "Error: trying to get DOQ frontend with index " + std::to_string(index) + " but we only have " + std::to_string(doqFrontends.size()) + " frontend(s)\n";
       }
     }
     catch (const std::exception& e) {
@@ -2769,7 +2788,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
   luaCtx.writeFunction("getDOQFrontendCount", []() {
     setLuaNoSideEffect();
-    return g_doqlocals.size();
+    return dnsdist::getDoQFrontends().size();
   });
 
   luaCtx.registerFunction<void (std::shared_ptr<DOQFrontend>::*)()>("reloadCertificates", [](const std::shared_ptr<DOQFrontend>& frontend) {
@@ -2787,7 +2806,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       boost::format fmt("%-3d %-20.20s %-15d %-15d %-15d %-15d %-15d %-15d %-15d %-15d %-15d %-15d %-15d %-15d");
       ret << (fmt % "#" % "Address" % "HTTP" % "HTTP/1" % "HTTP/2" % "GET" % "POST" % "Bad" % "Errors" % "Redirects" % "Valid" % "# ticket keys" % "Rotation delay" % "Next rotation") << endl;
       size_t counter = 0;
-      for (const auto& ctx : g_dohlocals) {
+      for (const auto& ctx : dnsdist::getDoHFrontends()) {
         ret << (fmt % counter % ctx->d_tlsContext.d_addr.toStringWithPort() % ctx->d_httpconnects % ctx->d_http1Stats.d_nbQueries % ctx->d_http2Stats.d_nbQueries % ctx->d_getqueries % ctx->d_postqueries % ctx->d_badrequests % ctx->d_errorresponses % ctx->d_redirectresponses % ctx->d_validresponses % ctx->getTicketsKeysCount() % ctx->getTicketsKeyRotationDelay() % ctx->getNextTicketsKeyRotation()) << endl;
         counter++;
       }
@@ -2810,7 +2829,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       boost::format fmt("%-3d %-20.20s %-15d %-15d %-15d %-15d");
       ret << (fmt % "#" % "Address" % "Bad Version" % "Invalid Token" % "Errors" % "Valid") << endl;
       size_t counter = 0;
-      for (const auto& ctx : g_doh3locals) {
+      for (const auto& ctx : dnsdist::getDoH3Frontends()) {
         ret << (fmt % counter % ctx->d_local.toStringWithPort() % ctx->d_doh3UnsupportedVersionErrors % ctx->d_doh3InvalidTokensReceived % ctx->d_errorResponses % ctx->d_validResponses) << endl;
         counter++;
       }
@@ -2833,12 +2852,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     }
     setLuaNoSideEffect();
     try {
-      if (index < g_doh3locals.size()) {
-        result = g_doh3locals.at(index);
+      auto doh3Frontends = dnsdist::getDoH3Frontends();
+      if (index < doh3Frontends.size()) {
+        result = doh3Frontends.at(index);
       }
       else {
-        errlog("Error: trying to get DOH3 frontend with index %d but we only have %d frontend(s)\n", index, g_doh3locals.size());
-        g_outputBuffer = "Error: trying to get DOH3 frontend with index " + std::to_string(index) + " but we only have " + std::to_string(g_doh3locals.size()) + " frontend(s)\n";
+        errlog("Error: trying to get DOH3 frontend with index %d but we only have %d frontend(s)\n", index, doh3Frontends.size());
+        g_outputBuffer = "Error: trying to get DOH3 frontend with index " + std::to_string(index) + " but we only have " + std::to_string(doh3Frontends.size()) + " frontend(s)\n";
       }
     }
     catch (const std::exception& e) {
@@ -2850,7 +2870,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
   luaCtx.writeFunction("getDOH3FrontendCount", []() {
     setLuaNoSideEffect();
-    return g_doh3locals.size();
+    return dnsdist::getDoH3Frontends().size();
   });
 
   luaCtx.registerFunction<void (std::shared_ptr<DOH3Frontend>::*)()>("reloadCertificates", [](const std::shared_ptr<DOH3Frontend>& frontend) {
@@ -2869,7 +2889,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       g_outputBuffer = "\n- HTTP/1:\n\n";
       ret << (fmt % "#" % "Address" % "200" % "400" % "403" % "500" % "502" % "Others") << endl;
       size_t counter = 0;
-      for (const auto& ctx : g_dohlocals) {
+      for (const auto& ctx : dnsdist::getDoHFrontends()) {
         ret << (fmt % counter % ctx->d_tlsContext.d_addr.toStringWithPort() % ctx->d_http1Stats.d_nb200Responses % ctx->d_http1Stats.d_nb400Responses % ctx->d_http1Stats.d_nb403Responses % ctx->d_http1Stats.d_nb500Responses % ctx->d_http1Stats.d_nb502Responses % ctx->d_http1Stats.d_nbOtherResponses) << endl;
         counter++;
       }
@@ -2879,7 +2899,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       g_outputBuffer += "\n- HTTP/2:\n\n";
       ret << (fmt % "#" % "Address" % "200" % "400" % "403" % "500" % "502" % "Others") << endl;
       counter = 0;
-      for (const auto& ctx : g_dohlocals) {
+      for (const auto& ctx : dnsdist::getDoHFrontends()) {
         ret << (fmt % counter % ctx->d_tlsContext.d_addr.toStringWithPort() % ctx->d_http2Stats.d_nb200Responses % ctx->d_http2Stats.d_nb400Responses % ctx->d_http2Stats.d_nb403Responses % ctx->d_http2Stats.d_nb500Responses % ctx->d_http2Stats.d_nb502Responses % ctx->d_http2Stats.d_nbOtherResponses) << endl;
         counter++;
       }
@@ -2902,12 +2922,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 #ifdef HAVE_DNS_OVER_HTTPS
     setLuaNoSideEffect();
     try {
-      if (index < g_dohlocals.size()) {
-        result = g_dohlocals.at(index);
+      auto dohFrontends = dnsdist::getDoHFrontends();
+      if (index < dohFrontends.size()) {
+        result = dohFrontends.at(index);
       }
       else {
-        errlog("Error: trying to get DOH frontend with index %d but we only have %d frontend(s)\n", index, g_dohlocals.size());
-        g_outputBuffer = "Error: trying to get DOH frontend with index " + std::to_string(index) + " but we only have " + std::to_string(g_dohlocals.size()) + " frontend(s)\n";
+        errlog("Error: trying to get DOH frontend with index %d but we only have %d frontend(s)\n", index, dohFrontends.size());
+        g_outputBuffer = "Error: trying to get DOH frontend with index " + std::to_string(index) + " but we only have " + std::to_string(dohFrontends.size()) + " frontend(s)\n";
       }
     }
     catch (const std::exception& e) {
@@ -2922,7 +2943,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
   luaCtx.writeFunction("getDOHFrontendCount", []() {
     setLuaNoSideEffect();
-    return g_dohlocals.size();
+    return dnsdist::getDoHFrontends().size();
   });
 
   luaCtx.registerFunction<void (std::shared_ptr<DOHFrontend>::*)()>("reloadCertificates", [](const std::shared_ptr<DOHFrontend>& frontend) {
@@ -3045,7 +3066,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
         vinfolog("Loading default TLS provider '%s'", provider);
       }
       // only works pre-startup, so no sync necessary
-      auto clientState = std::make_unique<ClientState>(frontend->d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
+      auto clientState = std::make_shared<ClientState>(frontend->d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus, enableProxyProtocol);
       clientState->tlsFrontend = frontend;
       clientState->d_additionalAddresses = std::move(additionalAddresses);
       if (tcpListenQueueSize > 0) {
@@ -3058,8 +3079,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
         clientState->d_tcpConcurrentConnectionsLimit = tcpMaxConcurrentConns;
       }
 
-      g_tlslocals.push_back(clientState->tlsFrontend);
-      g_frontends.push_back(std::move(clientState));
+      dnsdist::configuration::updateImmutableConfiguration([&clientState](dnsdist::configuration::Configuration& config) {
+        config.d_frontends.push_back(std::move(clientState));
+      });
     }
     catch (const std::exception& e) {
       g_outputBuffer = "Error: " + string(e.what()) + "\n";
@@ -3078,7 +3100,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
       //             1    2           3                 4                  5
       ret << (fmt % "#" % "Address" % "# ticket keys" % "Rotation delay" % "Next rotation") << endl;
       size_t counter = 0;
-      for (const auto& ctx : g_tlslocals) {
+      for (const auto& ctx : dnsdist::getDoTFrontends()) {
         ret << (fmt % counter % ctx->d_addr.toStringWithPort() % ctx->getTicketsKeysCount() % ctx->getTicketsKeyRotationDelay() % ctx->getNextTicketsKeyRotation()) << endl;
         counter++;
       }
@@ -3097,13 +3119,14 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
     std::shared_ptr<TLSCtx> result = nullptr;
 #ifdef HAVE_DNS_OVER_TLS
     setLuaNoSideEffect();
+    const auto tlsFrontends = dnsdist::getDoTFrontends();
     try {
-      if (index < g_tlslocals.size()) {
-        result = g_tlslocals.at(index)->getContext();
+      if (index < tlsFrontends.size()) {
+        result = tlsFrontends.at(index)->getContext();
       }
       else {
-        errlog("Error: trying to get TLS context with index %d but we only have %d context(s)\n", index, g_tlslocals.size());
-        g_outputBuffer = "Error: trying to get TLS context with index " + std::to_string(index) + " but we only have " + std::to_string(g_tlslocals.size()) + " context(s)\n";
+        errlog("Error: trying to get TLS context with index %d but we only have %d context(s)\n", index, tlsFrontends.size());
+        g_outputBuffer = "Error: trying to get TLS context with index " + std::to_string(index) + " but we only have " + std::to_string(tlsFrontends.size()) + " context(s)\n";
       }
     }
     catch (const std::exception& e) {
@@ -3121,12 +3144,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 #ifdef HAVE_DNS_OVER_TLS
     setLuaNoSideEffect();
     try {
-      if (index < g_tlslocals.size()) {
-        result = g_tlslocals.at(index);
+      auto tlsFrontends = dnsdist::getDoTFrontends();
+      if (index < tlsFrontends.size()) {
+        result = tlsFrontends.at(index);
       }
       else {
-        errlog("Error: trying to get TLS frontend with index %d but we only have %d frontends\n", index, g_tlslocals.size());
-        g_outputBuffer = "Error: trying to get TLS frontend with index " + std::to_string(index) + " but we only have " + std::to_string(g_tlslocals.size()) + " frontend(s)\n";
+        errlog("Error: trying to get TLS frontend with index %d but we only have %d frontends\n", index, tlsFrontends.size());
+        g_outputBuffer = "Error: trying to get TLS frontend with index " + std::to_string(index) + " but we only have " + std::to_string(tlsFrontends.size()) + " frontend(s)\n";
       }
     }
     catch (const std::exception& e) {
@@ -3141,7 +3165,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
 
   luaCtx.writeFunction("getTLSFrontendCount", []() {
     setLuaNoSideEffect();
-    return g_tlslocals.size();
+    return dnsdist::getDoTFrontends().size();
   });
 
   luaCtx.registerFunction<void (std::shared_ptr<TLSCtx>::*)()>("rotateTicketsKey", [](std::shared_ptr<TLSCtx>& ctx) {
@@ -3199,7 +3223,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck)
   });
 
   luaCtx.writeFunction("reloadAllCertificates", []() {
-    for (auto& frontend : g_frontends) {
+    for (auto& frontend : dnsdist::getFrontends()) {
       if (!frontend) {
         continue;
       }
index d09d8d7bf02f85324312c70eed14c5b31110071f..a92fdb2072f93810010d235f3d9101e70d34979b 100644 (file)
@@ -175,7 +175,6 @@ bool generateSVCResponse(DNSQuestion& dnsQuestion, const std::vector<std::vector
     }
   }
 
-
   const auto& runtimeConfig = dnsdist::configuration::getCurrentRuntimeConfiguration();
   if (runtimeConfig.d_addEDNSToSelfGeneratedResponses && queryHasEDNS(dnsQuestion)) {
     bool dnssecOK = ((getEDNSZ(dnsQuestion) & EDNS_HEADER_FLAG_DO) != 0);
index 3fbbd1180fcc916bce7dfedbc78be32f0576a7a9..23cb39fcc78c82bb436d8e60149f3ed58cbcc179 100644 (file)
@@ -34,6 +34,7 @@
 #include "dnsdist.hh"
 #include "dnsdist-configuration.hh"
 #include "dnsdist-dynblocks.hh"
+#include "dnsdist-frontend.hh"
 #include "dnsdist-healthchecks.hh"
 #include "dnsdist-metrics.hh"
 #include "dnsdist-prometheus.hh"
@@ -696,7 +697,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
   output << "# TYPE " << frontsbase << "tlshandshakefailures " << "counter" << "\n";
 
   std::map<std::string,uint64_t> frontendDuplicates;
-  for (const auto& front : g_frontends) {
+  for (const auto& front : dnsdist::getFrontends()) {
     if (front->udpFD == -1 && front->tcpFD == -1) {
       continue;
     }
@@ -782,7 +783,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp)
 
 #ifdef HAVE_DNS_OVER_HTTPS
   std::map<std::string,uint64_t> dohFrontendDuplicates;
-  for(const auto& doh : g_dohlocals) {
+  for(const auto& doh : dnsdist::getDoHFrontends()) {
     const string frontName = doh->d_tlsContext.d_addr.toStringWithPort();
     uint64_t threadNumber = 0;
     auto dupPair = frontendDuplicates.emplace(frontName, 1);
@@ -1144,8 +1145,8 @@ static void handleStats(const YaHTTP::Request& req, YaHTTP::Response& resp)
 
   Json::array frontends;
   num = 0;
-  frontends.reserve(g_frontends.size());
-  for (const auto& front : g_frontends) {
+  frontends.reserve(dnsdist::getFrontends().size());
+  for (const auto& front : dnsdist::getFrontends()) {
     if (front->udpFD == -1 && front->tcpFD == -1) {
       continue;
     }
@@ -1200,9 +1201,10 @@ static void handleStats(const YaHTTP::Request& req, YaHTTP::Response& resp)
   Json::array dohs;
 #ifdef HAVE_DNS_OVER_HTTPS
   {
-    dohs.reserve(g_dohlocals.size());
+    const auto dohFrontends = dnsdist::getDoHFrontends();
+    dohs.reserve(dohFrontends.size());
     num = 0;
-    for (const auto& doh : g_dohlocals) {
+    for (const auto& doh : dohFrontends) {
       dohs.emplace_back(Json::object{
         {"id", num++},
         {"address", doh->d_tlsContext.d_addr.toStringWithPort()},
@@ -1271,7 +1273,7 @@ static void handleStats(const YaHTTP::Request& req, YaHTTP::Response& resp)
   string localaddressesStr;
   {
     std::set<std::string> localaddresses;
-    for (const auto& front : g_frontends) {
+    for (const auto& front : dnsdist::getFrontends()) {
       localaddresses.insert(front->local.toStringWithPort());
     }
     for (const auto& addr : localaddresses) {
index ecc54d586da5af5a06acff60b9a731d3e96b0e89..ff6318ef70c871dbcf7bd2d0c88392f39b6a1cc7 100644 (file)
@@ -50,6 +50,7 @@
 #include "dnsdist-dynblocks.hh"
 #include "dnsdist-ecs.hh"
 #include "dnsdist-edns.hh"
+#include "dnsdist-frontend.hh"
 #include "dnsdist-healthchecks.hh"
 #include "dnsdist-lua.hh"
 #include "dnsdist-lua-hooks.hh"
@@ -96,16 +97,9 @@ using std::thread;
 
 string g_outputBuffer;
 
-std::vector<std::shared_ptr<TLSFrontend>> g_tlslocals;
-std::vector<std::shared_ptr<DOHFrontend>> g_dohlocals;
-std::vector<std::shared_ptr<DOQFrontend>> g_doqlocals;
-std::vector<std::shared_ptr<DOH3Frontend>> g_doh3locals;
-std::vector<std::shared_ptr<DNSCryptContext>> g_dnsCryptLocals;
-
 shared_ptr<BPFFilter> g_defaultBPFFilter{nullptr};
 std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
 
-std::vector<std::unique_ptr<ClientState>> g_frontends;
 /* UDP: the grand design. Per socket we listen on for incoming queries there is one thread.
    Then we have a bunch of connected sockets for talking to downstream servers.
    We send directly to those sockets.
@@ -2685,37 +2679,37 @@ static void setupLocalSocket(ClientState& clientState, const ComboAddress& addr,
   }
 }
 
-static void setUpLocalBind(std::unique_ptr<ClientState>& cstate)
+static void setUpLocalBind(ClientState& cstate)
 {
   /* skip some warnings if there is an identical UDP context */
-  bool warn = !cstate->tcp || cstate->tlsFrontend != nullptr || cstate->dohFrontend != nullptr;
-  int& descriptor = !cstate->tcp ? cstate->udpFD : cstate->tcpFD;
+  bool warn = !cstate.tcp || cstate.tlsFrontend != nullptr || cstate.dohFrontend != nullptr;
+  int& descriptor = !cstate.tcp ? cstate.udpFD : cstate.tcpFD;
   (void)warn;
 
-  setupLocalSocket(*cstate, cstate->local, descriptor, cstate->tcp, warn);
+  setupLocalSocket(cstate, cstate.local, descriptor, cstate.tcp, warn);
 
-  for (auto& [addr, socket] : cstate->d_additionalAddresses) {
-    setupLocalSocket(*cstate, addr, socket, true, false);
+  for (auto& [addr, socket] : cstate.d_additionalAddresses) {
+    setupLocalSocket(cstate, addr, socket, true, false);
   }
 
-  if (cstate->tlsFrontend != nullptr) {
-    if (!cstate->tlsFrontend->setupTLS()) {
-      errlog("Error while setting up TLS on local address '%s', exiting", cstate->local.toStringWithPort());
+  if (cstate.tlsFrontend != nullptr) {
+    if (!cstate.tlsFrontend->setupTLS()) {
+      errlog("Error while setting up TLS on local address '%s', exiting", cstate.local.toStringWithPort());
       _exit(EXIT_FAILURE);
     }
   }
 
-  if (cstate->dohFrontend != nullptr) {
-    cstate->dohFrontend->setup();
+  if (cstate.dohFrontend != nullptr) {
+    cstate.dohFrontend->setup();
   }
-  if (cstate->doqFrontend != nullptr) {
-    cstate->doqFrontend->setup();
+  if (cstate.doqFrontend != nullptr) {
+    cstate.doqFrontend->setup();
   }
-  if (cstate->doh3Frontend != nullptr) {
-    cstate->doh3Frontend->setup();
+  if (cstate.doh3Frontend != nullptr) {
+    cstate.doh3Frontend->setup();
   }
 
-  cstate->ready = true;
+  cstate.ready = true;
 }
 
 struct CommandLineParameters
@@ -3131,11 +3125,13 @@ static void dropPrivileges(const CommandLineParameters& cmdLine)
 
 static void initFrontends(const CommandLineParameters& cmdLine)
 {
+  auto frontends = dnsdist::configuration::getImmutableConfiguration().d_frontends;
+
   if (!cmdLine.locals.empty()) {
-    for (auto it = g_frontends.begin(); it != g_frontends.end();) {
+    for (auto it = frontends.begin(); it != frontends.end();) {
       /* DoH, DoT and DNSCrypt frontends are separate */
       if ((*it)->dohFrontend == nullptr && (*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr && (*it)->doqFrontend == nullptr && (*it)->doh3Frontend == nullptr) {
-        it = g_frontends.erase(it);
+        it = frontends.erase(it);
       }
       else {
         ++it;
@@ -3144,18 +3140,22 @@ static void initFrontends(const CommandLineParameters& cmdLine)
 
     for (const auto& loc : cmdLine.locals) {
       /* UDP */
-      g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress(loc, 53), false, false, 0, "", std::set<int>{}, true));
+      frontends.emplace_back(std::make_unique<ClientState>(ComboAddress(loc, 53), false, false, 0, "", std::set<int>{}, true));
       /* TCP */
-      g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress(loc, 53), true, false, 0, "", std::set<int>{}, true));
+      frontends.emplace_back(std::make_unique<ClientState>(ComboAddress(loc, 53), true, false, 0, "", std::set<int>{}, true));
     }
   }
 
-  if (g_frontends.empty()) {
+  if (frontends.empty()) {
     /* UDP */
-    g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), false, false, 0, "", std::set<int>{}, true));
+    frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), false, false, 0, "", std::set<int>{}, true));
     /* TCP */
-    g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set<int>{}, true));
+    frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set<int>{}, true));
   }
+
+  dnsdist::configuration::updateImmutableConfiguration([&frontends](dnsdist::configuration::Configuration& config) {
+    config.d_frontends = std::move(frontends);
+  });
 }
 
 namespace dnsdist
@@ -3171,7 +3171,7 @@ static void startFrontends()
 
   std::vector<ClientState*> tcpStates;
   std::vector<ClientState*> udpStates;
-  for (auto& clientState : g_frontends) {
+  for (auto& clientState : dnsdist::getFrontends()) {
 #ifdef HAVE_XSK
     if (clientState->xskInfo) {
       dnsdist::xsk::addDestinationAddress(clientState->local);
@@ -3389,7 +3389,7 @@ int main(int argc, char** argv)
 
     initFrontends(cmdLine);
 
-    for (const auto& frontend : g_frontends) {
+    for (const auto& frontend : dnsdist::getFrontends()) {
       if (!frontend->tcp) {
         ++udpBindsCount;
       }
@@ -3423,8 +3423,8 @@ int main(int argc, char** argv)
       g_rings.init(config.d_ringsCapacity, config.d_ringsNumberOfShards, config.d_ringsNbLockTries, config.d_ringsRecordQueries, config.d_ringsRecordResponses);
     }
 
-    for (auto& frontend : g_frontends) {
-      setUpLocalBind(frontend);
+    for (auto& frontend : dnsdist::getFrontends()) {
+      setUpLocalBind(*frontend);
     }
 
     {
index f131ab8f876297cb3ec5b3db616f95398bb8f5be..378cd764158e7104ee861801cacb9bbe5ce40460 100644 (file)
@@ -1020,12 +1020,6 @@ enum ednsHeaderFlags
   EDNS_HEADER_FLAG_DO = 32768
 };
 
-extern std::vector<shared_ptr<TLSFrontend>> g_tlslocals;
-extern std::vector<shared_ptr<DOHFrontend>> g_dohlocals;
-extern std::vector<shared_ptr<DOQFrontend>> g_doqlocals;
-extern std::vector<shared_ptr<DOH3Frontend>> g_doh3locals;
-extern std::vector<std::unique_ptr<ClientState>> g_frontends;
-
 extern shared_ptr<BPFFilter> g_defaultBPFFilter;
 extern std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
 
@@ -1040,7 +1034,6 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname,
 
 bool checkQueryHeaders(const struct dnsheader& dnsHeader, ClientState& clientState);
 
-extern std::vector<std::shared_ptr<DNSCryptContext>> g_dnsCryptLocals;
 bool handleDNSCryptQuery(PacketBuffer& packet, DNSCryptQuery& query, bool tcp, time_t now, PacketBuffer& response);
 bool checkDNSCryptQuery(const ClientState& clientState, PacketBuffer& query, std::unique_ptr<DNSCryptQuery>& dnsCryptQuery, time_t now, bool tcp);
 
index 0391f8fb4aa9f6b42192a3d05fcf3a1417d19df2..abe9a95c9e6e3a2937c367a0f4994e4d353c48ea 100644 (file)
@@ -23,8 +23,6 @@ std::unique_ptr<DNSDistSNMPAgent> g_snmpAgent{nullptr};
 Rings g_rings;
 #endif /* BENCH_POLICIES */
 
-std::vector<std::unique_ptr<ClientState>> g_frontends;
-
 /* add stub implementations, we don't want to include the corresponding object files
    and their dependencies */