]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add per-backend `max_udp_outstanding` YAML config setting 17180/head
authorRobert Edmonds <edmonds@users.noreply.github.com>
Tue, 21 Apr 2026 21:22:32 +0000 (17:22 -0400)
committerRobert Edmonds <edmonds@users.noreply.github.com>
Tue, 21 Apr 2026 21:22:32 +0000 (17:22 -0400)
This commit adds a new per-backend config setting `max_udp_outstanding`
which overrides the global `tuning.udp.max_outstanding_per_backend`
setting.

If the per-backend `max_udp_outstanding` setting is omitted, the value
of the global option `tuning.udp.max_outstanding_per_backend` will be
used instead.

This allows tuning the number of UDP states allocated on a per-backend
basis in order to tune the amount of memory consumed by dnsdist.
Low-latency backends may only need a small number of UDP states, while
high-latency backends may need a higher number of UDP states.

The `tuning.udp.max_outstanding_per_backend` setting and the new
per-backend `max_udp_outstanding` setting directly control the sizes of
the vectors of `IDState` objects that are preallocated at startup.

The size of the `IDState` object can vary depending on compile time
options, but in my local build it is currently 496 bytes. This means
that a backend with the maximum number of UDP states (65535) will
require allocating at least (496 * 65535 / 1048576) = 31 MB. Similarly,
a backend with 8192 UDP states will require allocating 3.9 MB, and a
backend with 256 UDP states only requires 124 KB.

Signed-off-by: Robert Edmonds <edmonds@users.noreply.github.com>
pdns/dnsdistdist/dnsdist-backend.cc
pdns/dnsdistdist/dnsdist-configuration-yaml.cc
pdns/dnsdistdist/dnsdist-settings-definitions.yml
pdns/dnsdistdist/dnsdist.hh

index bb90467dd54f2e452877b268aba2a3be092ae0ff..38bf194da96a928d586ba9487460944d86adaad2 100644 (file)
@@ -380,7 +380,8 @@ void DownstreamState::connectUDPSockets()
     idStates.clear();
   }
   else {
-    idStates.resize(config.d_maxUDPOutstanding);
+    const auto maxUDPOutstanding = d_config.d_maxUDPOutstanding > 0 ? d_config.d_maxUDPOutstanding : config.d_maxUDPOutstanding;
+    idStates.resize(maxUDPOutstanding);
   }
   sockets.resize(d_config.d_numberOfSockets);
 
index 412a07b5bb791cb373e75b0e72289e6bf8ee66f2..518cf87270cc4e8de09a69346f7690b6c39e606e 100644 (file)
@@ -460,6 +460,7 @@ static std::shared_ptr<DownstreamState> createBackendFromConfiguration(const Con
   backendConfig.order = config.order;
   backendConfig.d_weight = config.weight;
   backendConfig.d_maxInFlightQueriesPerConn = config.max_in_flight;
+  backendConfig.d_maxUDPOutstanding = config.max_udp_outstanding;
   backendConfig.d_tcpConcurrentConnectionsLimit = config.max_concurrent_tcp_connections;
   backendConfig.name = std::string(config.name);
   if (!config.id.empty()) {
index 2919f524dc84bca9873a932053d580dec9ba8c35..922ef214f9cbf29279febe4aba48be75c13e8aee 100644 (file)
@@ -1458,6 +1458,10 @@ backend:
       type: "u32"
       default: "1"
       description: "Maximum number of in-flight queries. The default is 0, which disables out-of-order processing. It should only be enabled if the backend does support out-of-order processing. Out-of-order processing needs to be enabled on the frontend as well"
+    - name: "max_udp_outstanding"
+      type: "u32"
+      default: "0"
+      description: "Maximum number of outstanding UDP queries for this backend. If not set, defaults to ``tuning.udp.max_outstanding_per_backend``."
     - name: "tcp_only"
       type: "bool"
       default: "false"
index 766e602bd5c663f828f1785078c20b336992ac61..34834803f1268332007bf2fc74e6852b58213a3b 100644 (file)
@@ -599,6 +599,7 @@ struct DownstreamState : public std::enable_shared_from_this<DownstreamState>
 #endif /* HAVE_XSK */
     size_t d_numberOfSockets{1};
     size_t d_maxInFlightQueriesPerConn{1};
+    size_t d_maxUDPOutstanding{0};
     size_t d_tcpConcurrentConnectionsLimit{0};
     int order{1};
     int d_weight{1};