]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: disallow (by answering Refused) RD=0 by default
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 17 Nov 2023 10:24:48 +0000 (11:24 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 17 Nov 2023 11:16:10 +0000 (12:16 +0100)
Fixes #13386

pdns/recursordist/pdns_recursor.cc
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-main.hh
pdns/recursordist/settings/table.py

index 9435f555e53f771ecb47847775681868ebb9218d..7ecd38b7bde43a652504d18eeb5bf0455a72129f 100644 (file)
@@ -71,6 +71,7 @@ unsigned int g_paddingTag;
 PaddingMode g_paddingMode;
 uint16_t g_udpTruncationThreshold;
 std::atomic<bool> g_quiet;
+bool g_allowNoRD;
 bool g_logCommonErrors;
 bool g_reusePort{false};
 bool g_gettagNeedsEDNSOptions{false};
@@ -1154,7 +1155,14 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi
     }
 
     if (!comboWriter->d_mdp.d_header.rd) {
-      resolver.setCacheOnly();
+      if (g_allowNoRD) {
+        resolver.setCacheOnly();
+      }
+      else {
+        ret.clear();
+        res = RCode::Refused;
+        goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto)
+      }
     }
 
     if (comboWriter->d_luaContext) {
index 9cc1cde07ab463162800dd5ed8a213c02def9da4..ed853cfbacdf0f8230ba0ae986f9fe432f3df342 100644 (file)
@@ -2100,6 +2100,7 @@ static int serviceMain(Logr::log_t log)
   g_logRPZChanges = ::arg().mustDo("log-rpz-changes");
 
   g_anyToTcp = ::arg().mustDo("any-to-tcp");
+  g_allowNoRD = ::arg().mustDo("allow-no-rd");
   g_udpTruncationThreshold = ::arg().asNum("udp-truncation-threshold");
 
   g_lowercaseOutgoing = ::arg().mustDo("lowercase-outgoing");
@@ -2849,313 +2850,6 @@ static void recursorThread()
   }
 }
 
-#if 0
-// THIS FUNCTION IS REPLACED BY GENERATED CODE IN settings/cxxsettings-generated.cc
-static void initArgs()
-{
-#if HAVE_FIBER_SANITIZER
-  // Asan needs more stack
-  ::arg().set("stack-size", "stack size per mthread") = "600000";
-#else
-  ::arg().set("stack-size", "stack size per mthread") = "200000";
-#endif
-  ::arg().set("stack-cache-size", "Size of the stack cache, per mthread") = "100";
-  // This mode forces metrics snap updates and disable root-refresh, to get consistent counters
-  ::arg().setSwitch("devonly-regression-test-mode", "internal use only") = "no";
-  ::arg().set("soa-minimum-ttl", "Don't change") = "0";
-  ::arg().setSwitch("no-shuffle", "Don't change") = "off";
-  ::arg().set("local-port", "port to listen on") = "53";
-  ::arg().set("local-address", "IP addresses to listen on, separated by spaces or commas. Also accepts ports.") = "127.0.0.1";
-  ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options") = "no";
-  ::arg().set("trace", "if we should output heaps of logging. set to 'fail' to only log failing domains") = "off";
-  ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process";
-  ::arg().setSwitch("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no";
-  ::arg().set("signature-inception-skew", "Allow the signature inception to be off by this number of seconds") = "60";
-  ::arg().set("dnssec-disabled-algorithms", "List of DNSSEC algorithm numbers that are considered unsupported") = "";
-  ::arg().setSwitch("daemon", "Operate as a daemon") = "no";
-  ::arg().setSwitch("write-pid", "Write a PID file") = "yes";
-  ::arg().set("loglevel", "Amount of logging. Higher is more. Do not set below 3") = "6";
-  ::arg().setSwitch("disable-syslog", "Disable logging to syslog, useful when running inside a supervisor that logs stdout") = "no";
-  ::arg().setSwitch("log-timestamp", "Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already") = "yes";
-  ::arg().setSwitch("log-common-errors", "If we should log rather common errors") = "no";
-  ::arg().set("chroot", "switch to chroot jail") = "";
-  ::arg().set("setgid", "If set, change group id to this gid for more security"
-#ifdef HAVE_SYSTEMD
-#define SYSTEMD_SETID_MSG ". When running inside systemd, use the User and Group settings in the unit-file!"
-              SYSTEMD_SETID_MSG
-#endif
-              )
-    = "";
-  ::arg().set("setuid", "If set, change user id to this uid for more security"
-#ifdef HAVE_SYSTEMD
-              SYSTEMD_SETID_MSG
-#endif
-              )
-    = "";
-  ::arg().set("network-timeout", "Wait this number of milliseconds for network i/o") = "1500";
-  ::arg().set("threads", "Launch this number of threads") = "2";
-  ::arg().set("distributor-threads", "Launch this number of distributor threads, distributing queries to other threads") = "0";
-  ::arg().set("processes", "Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)") = "1"; // if we un-experimental this, need to fix openssl rand seeding for multiple PIDs!
-  ::arg().set("config-name", "Name of this virtual configuration - will rename the binary image") = "";
-  ::arg().set("api-config-dir", "Directory where REST API stores config and zones") = "";
-  ::arg().set("api-key", "Static pre-shared authentication key for access to the REST API") = "";
-  ::arg().setSwitch("webserver", "Start a webserver (for REST API)") = "no";
-  ::arg().set("webserver-address", "IP Address of webserver to listen on") = "127.0.0.1";
-  ::arg().set("webserver-port", "Port of webserver to listen on") = "8082";
-  ::arg().set("webserver-password", "Password required for accessing the webserver") = "";
-  ::arg().set("webserver-allow-from", "Webserver access is only allowed from these subnets") = "127.0.0.1,::1";
-  ::arg().set("webserver-loglevel", "Amount of logging in the webserver (none, normal, detailed)") = "normal";
-  ::arg().setSwitch("webserver-hash-plaintext-credentials", "Whether to hash passwords and api keys supplied in plaintext, to prevent keeping the plaintext version in memory at runtime") = "no";
-  ::arg().set("carbon-ourname", "If set, overrides our reported hostname for carbon stats") = "";
-  ::arg().set("carbon-server", "If set, send metrics in carbon (graphite) format to this server IP address") = "";
-  ::arg().set("carbon-interval", "Number of seconds between carbon (graphite) updates") = "30";
-  ::arg().set("carbon-namespace", "If set overwrites the first part of the carbon string") = "pdns";
-  ::arg().set("carbon-instance", "If set overwrites the instance name default") = "recursor";
-
-  ::arg().set("statistics-interval", "Number of seconds between printing of recursor statistics, 0 to disable") = "1800";
-  ::arg().setSwitch("quiet", "Suppress logging of questions and answers") = "yes";
-  ::arg().set("logging-facility", "Facility to log messages as. 0 corresponds to local0") = "";
-  ::arg().set("config-dir", "Location of configuration directory (recursor.conf)") = SYSCONFDIR;
-  ::arg().set("socket-owner", "Owner of socket") = "";
-  ::arg().set("socket-group", "Group of socket") = "";
-  ::arg().set("socket-mode", "Permissions for socket") = "";
-
-  ::arg().set("socket-dir", string("Where the controlsocket will live, ") + LOCALSTATEDIR + "/pdns-recursor when unset and not chrooted"
-#ifdef HAVE_SYSTEMD
-                + ". Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).")
-    = "";
-  auto* runtimeDir = getenv("RUNTIME_DIRECTORY"); // NOLINT(concurrency-mt-unsafe,cppcoreguidelines-pro-type-vararg)
-  if (runtimeDir != nullptr) {
-    ::arg().set("socket-dir") = runtimeDir;
-  }
-#else
-              )
-    = "";
-#endif
-  ::arg().set("query-local-address", "Source IP address for sending queries") = "0.0.0.0";
-  ::arg().set("client-tcp-timeout", "Timeout in seconds when talking to TCP clients") = "2";
-  ::arg().set("max-mthreads", "Maximum number of simultaneous Mtasker threads") = "2048";
-  ::arg().set("max-tcp-clients", "Maximum number of simultaneous TCP clients") = "128";
-  ::arg().set("max-concurrent-requests-per-tcp-connection", "Maximum number of requests handled concurrently per TCP connection") = "10";
-  ::arg().set("server-down-max-fails", "Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )") = "64";
-  ::arg().set("server-down-throttle-time", "Number of seconds to throttle all queries to a server after being marked as down") = "60";
-  ::arg().set("dont-throttle-names", "Do not throttle nameservers with this name or suffix") = "";
-  ::arg().set("dont-throttle-netmasks", "Do not throttle nameservers with this IP netmask") = "";
-  ::arg().set("non-resolving-ns-max-fails", "Number of failed address resolves of a nameserver to start throttling it, 0 is disabled") = "5";
-  ::arg().set("non-resolving-ns-throttle-time", "Number of seconds to throttle a nameserver with a name failing to resolve") = "60";
-
-  ::arg().set("hint-file", "If set, load root hints from this file") = "";
-  ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache") = "1000000";
-  ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory") = "3600";
-  ::arg().set("max-cache-bogus-ttl", "maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory") = "3600";
-  ::arg().set("max-cache-ttl", "maximum number of seconds to keep a cached entry in memory") = "86400";
-  ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "86400";
-  ::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000";
-  ::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60";
-  ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60";
-  ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname, set custom or 'disabled'") = "";
-  ::arg().set("stats-ringbuffer-entries", "maximum number of packets to store statistics for") = "10000";
-  ::arg().set("version-string", "string reported on version.pdns or version.bind") = fullVersionString();
-  ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse") = LOCAL_NETS;
-  ::arg().set("allow-from-file", "If set, load allowed netmasks from this file") = "";
-  ::arg().set("allow-notify-for", "If set, NOTIFY requests for these zones will be allowed") = "";
-  ::arg().set("allow-notify-for-file", "If set, load NOTIFY-allowed zones from this file") = "";
-  ::arg().set("allow-notify-from", "If set, NOTIFY requests from these comma separated netmasks will be allowed") = "";
-  ::arg().set("allow-notify-from-file", "If set, load NOTIFY-allowed netmasks from this file") = "";
-  ::arg().set("entropy-source", "If set, read entropy from this file") = "/dev/urandom";
-  ::arg().set("dont-query", "If set, do not query these netmasks for DNS data") = DONT_QUERY;
-  ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)") = "0";
-  ::arg().set("max-tcp-queries-per-connection", "If set, maximum number of TCP queries in a TCP connection") = "0";
-  ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses") = "1";
-  ::arg().setSwitch("single-socket", "If set, only use a single socket for outgoing queries") = "off";
-  ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ") = "";
-  ::arg().set("lua-config-file", "More powerful configuration options") = "";
-  ::arg().setSwitch("allow-trust-anchor-query", "Allow queries for trustanchor.server CH TXT and negativetrustanchor.server CH TXT") = "no";
-
-  ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs") = "";
-  ::arg().set("forward-zones-recurse", "Zones for which we forward queries with recursion bit, comma separated domain=ip pairs") = "";
-  ::arg().set("forward-zones-file", "File with (+)domain=ip pairs for forwarding") = "";
-  ::arg().setSwitch("export-etc-hosts", "If we should serve up contents from /etc/hosts") = "off";
-  ::arg().set("export-etc-hosts-search-suffix", "Also serve up the contents of /etc/hosts with this suffix") = "";
-  ::arg().set("etc-hosts-file", "Path to 'hosts' file") = "/etc/hosts";
-  ::arg().setSwitch("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space") = "yes";
-  ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers") = "";
-  ::arg().set("lua-maintenance-interval", "Number of seconds between calls to the lua user defined maintenance() function") = "1";
-  ::arg().set("latency-statistic-size", "Number of latency values to calculate the qa-latency average") = "10000";
-  ::arg().setSwitch("disable-packetcache", "Disable packetcache") = "no";
-  ::arg().set("ecs-ipv4-bits", "Number of bits of IPv4 address to pass for EDNS Client Subnet") = "24";
-  ::arg().set("ecs-ipv4-cache-bits", "Maximum number of bits of IPv4 mask to cache ECS response") = "24";
-  ::arg().set("ecs-ipv6-bits", "Number of bits of IPv6 address to pass for EDNS Client Subnet") = "56";
-  ::arg().set("ecs-ipv6-cache-bits", "Maximum number of bits of IPv6 mask to cache ECS response") = "56";
-  ::arg().setSwitch("ecs-ipv4-never-cache", "If we should never cache IPv4 ECS responses") = "no";
-  ::arg().setSwitch("ecs-ipv6-never-cache", "If we should never cache IPv6 ECS responses") = "no";
-  ::arg().set("ecs-minimum-ttl-override", "The minimum TTL for records in ECS-specific answers") = "1";
-  ::arg().set("ecs-cache-limit-ttl", "Minimum TTL to cache ECS response") = "0";
-  ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for (deprecated)") = "";
-  ::arg().set("edns-subnet-allow-list", "List of netmasks and domains that we should enable EDNS subnet for") = "";
-  ::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added") = "0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE;
-  ::arg().set("ecs-scope-zero-address", "Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0") = "";
-  ::arg().setSwitch("use-incoming-edns-subnet", "Pass along received EDNS Client Subnet information") = "no";
-  ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "no";
-  ::arg().setSwitch("root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist") = "yes";
-  ::arg().setSwitch("any-to-tcp", "Answer ANY queries with tc=1, shunting to TCP") = "no";
-  ::arg().setSwitch("lowercase-outgoing", "Force outgoing questions to lowercase") = "no";
-  ::arg().setSwitch("gettag-needs-edns-options", "If EDNS Options should be extracted before calling the gettag() hook") = "no";
-  ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate") = "1232";
-  ::arg().set("edns-outgoing-bufsize", "Outgoing EDNS buffer size") = "1232";
-  ::arg().set("minimum-ttl-override", "The minimum TTL") = "1";
-  ::arg().set("max-qperq", "Maximum outgoing queries per query") = "60";
-  ::arg().set("max-ns-per-resolve", "Maximum number of NS records to consider to resolve a name, 0 is no limit") = "13";
-  ::arg().set("max-ns-address-qperq", "Maximum outgoing NS address queries per query") = "10";
-  ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited") = "7000";
-  ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "16";
-  ::arg().set("max-udp-queries-per-round", "Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing") = "10000";
-  ::arg().set("protobuf-use-kernel-timestamp", "Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)") = "";
-  ::arg().set("distribution-pipe-buffer-size", "Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread") = "0";
-
-  ::arg().set("include-dir", "Include *.conf files from this directory") = "";
-  ::arg().set("security-poll-suffix", "Domain name from which to query security update notifications") = "secpoll.powerdns.com.";
-
-#ifdef SO_REUSEPORT
-  ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "yes";
-#else
-  ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "no";
-#endif
-  ::arg().setSwitch("snmp-agent", "If set, register as an SNMP agent") = "no";
-  ::arg().set("snmp-master-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)") = "";
-  ::arg().set("snmp-daemon-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon") = "";
-
-  std::string defaultAPIDisabledStats = "cache-bytes, packetcache-bytes, special-memory-usage";
-  for (size_t idx = 0; idx < 32; idx++) {
-    defaultAPIDisabledStats += ", ecs-v4-response-bits-" + std::to_string(idx + 1);
-  }
-  for (size_t idx = 0; idx < 128; idx++) {
-    defaultAPIDisabledStats += ", ecs-v6-response-bits-" + std::to_string(idx + 1);
-  }
-  std::string defaultDisabledStats = defaultAPIDisabledStats + ", cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count";
-
-  ::arg().set("stats-api-blacklist", "List of statistics that are disabled when retrieving the complete list of statistics via the API (deprecated)") = defaultAPIDisabledStats;
-  ::arg().set("stats-carbon-blacklist", "List of statistics that are prevented from being exported via Carbon (deprecated)") = defaultDisabledStats;
-  ::arg().set("stats-rec-control-blacklist", "List of statistics that are prevented from being exported via rec_control get-all (deprecated)") = defaultDisabledStats;
-  ::arg().set("stats-snmp-blacklist", "List of statistics that are prevented from being exported via SNMP (deprecated)") = defaultDisabledStats;
-
-  ::arg().set("stats-api-disabled-list", "List of statistics that are disabled when retrieving the complete list of statistics via the API") = defaultAPIDisabledStats;
-  ::arg().set("stats-carbon-disabled-list", "List of statistics that are prevented from being exported via Carbon") = defaultDisabledStats;
-  ::arg().set("stats-rec-control-disabled-list", "List of statistics that are prevented from being exported via rec_control get-all") = defaultDisabledStats;
-  ::arg().set("stats-snmp-disabled-list", "List of statistics that are prevented from being exported via SNMP") = defaultDisabledStats;
-
-  ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size") = "0";
-  ::arg().setSwitch("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets") = "no";
-  ::arg().set("nsec3-max-iterations", "Maximum number of iterations allowed for an NSEC3 record") = "150";
-
-  ::arg().set("cpu-map", "Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs") = "";
-
-  ::arg().setSwitch("log-rpz-changes", "Log additions and removals to RPZ zones at Info level") = "no";
-
-  ::arg().set("proxy-protocol-from", "A Proxy Protocol header is only allowed from these subnets") = "";
-  ::arg().set("proxy-protocol-maximum-size", "The maximum size of a proxy protocol payload, including the TLV values") = "512";
-
-  ::arg().set("dns64-prefix", "DNS64 prefix") = "";
-
-  ::arg().set("udp-source-port-min", "Minimum UDP port to bind on") = "1024";
-  ::arg().set("udp-source-port-max", "Maximum UDP port to bind on") = "65535";
-  ::arg().set("udp-source-port-avoid", "List of comma separated UDP port number to avoid") = "11211";
-  ::arg().set("rng", "Specify random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.") = "auto";
-  ::arg().set("public-suffix-list-file", "Path to the Public Suffix List file, if any") = "";
-  ::arg().set("distribution-load-factor", "The load factor used when PowerDNS is distributing queries to worker threads") = "0.0";
-
-  ::arg().setSwitch("qname-minimization", "Use Query Name Minimization") = "yes";
-  ::arg().set("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec";
-  ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0";
-  ::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20";
-
-  ::arg().set("record-cache-shards", "Number of shards in the record cache") = "1024";
-  ::arg().set("packetcache-shards", "Number of shards in the packet cache") = "1024";
-
-  ::arg().set("refresh-on-ttl-perc", "If a record is requested from the cache and only this % of original TTL remains, refetch") = "0";
-  ::arg().set("record-cache-locked-ttl-perc", "Replace records in record cache only after this % of original TTL has passed") = "0";
-
-  ::arg().set("x-dnssec-names", "Collect DNSSEC statistics for names or suffixes in this list in separate x-dnssec counters") = "";
-
-#ifdef NOD_ENABLED
-  ::arg().setSwitch("new-domain-tracking", "Track newly observed domains (i.e. never seen before).") = "no";
-  ::arg().setSwitch("new-domain-log", "Log newly observed domains.") = "yes";
-  ::arg().set("new-domain-lookup", "Perform a DNS lookup newly observed domains as a subdomain of the configured domain") = "";
-  ::arg().set("new-domain-history-dir", "Persist new domain tracking data here to persist between restarts") = string(NODCACHEDIR) + "/nod";
-  ::arg().set("new-domain-whitelist", "List of domains (and implicitly all subdomains) which will never be considered a new domain (deprecated)") = "";
-  ::arg().set("new-domain-ignore-list", "List of domains (and implicitly all subdomains) which will never be considered a new domain") = "";
-  ::arg().set("new-domain-db-size", "Size of the DB used to track new domains in terms of number of cells. Defaults to 67108864") = "67108864";
-  ::arg().set("new-domain-pb-tag", "If protobuf is configured, the tag to use for messages containing newly observed domains. Defaults to 'pdns-nod'") = "pdns-nod";
-  ::arg().setSwitch("unique-response-tracking", "Track unique responses (tuple of query name, type and RR).") = "no";
-  ::arg().setSwitch("unique-response-log", "Log unique responses") = "yes";
-  ::arg().set("unique-response-history-dir", "Persist unique response tracking data here to persist between restarts") = string(NODCACHEDIR) + "/udr";
-  ::arg().set("unique-response-db-size", "Size of the DB used to track unique responses in terms of number of cells. Defaults to 67108864") = "67108864";
-  ::arg().set("unique-response-pb-tag", "If protobuf is configured, the tag to use for messages containing unique DNS responses. Defaults to 'pdns-udr'") = "pdns-udr";
-#endif /* NOD_ENABLED */
-
-  ::arg().setSwitch("extended-resolution-errors", "If set, send an EDNS Extended Error extension on resolution failures, like DNSSEC validation errors") = "no";
-
-  ::arg().set("aggressive-nsec-cache-size", "The number of records to cache in the aggressive cache. If set to a value greater than 0, and DNSSEC processing or validation is enabled, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in rfc8198") = "100000";
-  ::arg().set("aggressive-cache-min-nsec3-hit-ratio", "The minimum expected hit ratio to store NSEC3 records into the aggressive cache") = "2000";
-
-  ::arg().set("edns-padding-from", "List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that 'edns-padding-mode' applies") = "";
-  ::arg().set("edns-padding-mode", "Whether to add EDNS padding to all responses ('always') or only to responses for queries containing the EDNS padding option ('padded-queries-only', the default). In both modes, padding will only be added to responses for queries coming from `edns-padding-from`_ sources") = "padded-queries-only";
-  ::arg().set("edns-padding-tag", "Packetcache tag associated to responses sent with EDNS padding, to prevent sending these to clients for which padding is not enabled.") = "7830";
-  ::arg().setSwitch("edns-padding-out", "Whether to add EDNS padding to outgoing DoT messages") = "yes";
-
-  ::arg().setSwitch("dot-to-port-853", "Force DoT connection to target port 853 if DoT compiled in") = "yes";
-  ::arg().set("dot-to-auth-names", "Use DoT to authoritative servers with these names or suffixes") = "";
-  ::arg().set("event-trace-enabled", "If set, event traces are collected and send out via protobuf logging (1), logfile (2) or both(3)") = "0";
-
-  ::arg().set("tcp-out-max-idle-ms", "Time TCP/DoT connections are left idle in milliseconds or 0 if no limit") = "10000";
-  ::arg().set("tcp-out-max-idle-per-auth", "Maximum number of idle TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open") = "10";
-  ::arg().set("tcp-out-max-queries", "Maximum total number of queries per TCP/DoT connection, 0 means no limit") = "0";
-  ::arg().set("tcp-out-max-idle-per-thread", "Maximum number of idle TCP/DoT connections per thread") = "100";
-  ::arg().setSwitch("structured-logging", "Prefer structured logging") = "yes";
-  ::arg().set("structured-logging-backend", "Structured logging backend") = "default";
-  ::arg().setSwitch("save-parent-ns-set", "Save parent NS set to be used if child NS set fails") = "yes";
-  ::arg().set("max-busy-dot-probes", "Maximum number of concurrent DoT probes") = "0";
-  ::arg().set("serve-stale-extensions", "Number of times a record's ttl is extended by 30s to be served stale") = "0";
-
-  ::arg().setCmd("help", "Provide a helpful message");
-  ::arg().setCmd("version", "Print version string");
-  ::arg().setCmd("config", "Output blank configuration. You can use --config=check to test the config file and command line arguments.");
-  ::arg().setDefaults();
-  g_log.toConsole(Logger::Info);
-
-  if (s_generateConfigTable) {
-    auto file = ofstream("settings/table.py");
-    const std::map<std::string, std::string> overrideMap = {
-      {"allow-from", "LType.ListSubnets"},
-      {"allow-notify-for", "LType.ListStrings"},
-      {"allow-notify-from", "LType.ListSubnets"},
-      {"auth-zones", "LType.ListStrings"},
-      {"dnssec-disabled-algorithms", "LType.ListStrings"},
-      {"dont-query", "LType.ListSubnets"},
-      {"dont-throttle-names", "LType.ListStrings"},
-      {"dont-throttle-netmasks", "LType.ListSubnets"},
-      {"dot-to-auth-names", "LType.ListStrings"},
-      {"ecs-add-for", "LType.ListSubnets"},
-      {"edbs-padding-from", "LType.ListSubnets"},
-      {"edns-subnet-allow-list", "LType.ListSubnets"},
-      {"forwad-zones", "LType.ListStrings"},
-      {"forwad-zones-recurse", "LType.Strings"},
-      {"local-address", "LType.ListSocketAddresses"},
-      {"new-domain-ignore-list", "LType.ListStrings"},
-      {"query-local-address", "LType.ListSubnets"},
-      {"stats-api-disabled-list", "LType.ListStrings"},
-      {"stats-carbon-disabled-list", "LType.ListStrings"},
-      {"stats-rec-control-disabled-list", "LType.ListStrings"},
-      {"stats-snmp-disabled-list", "LType.ListStrings"},
-      {"webserver-allow-from", "LType.ListSubnets"},
-      {"x-dnssec-names", "LType.ListStrings"},
-    };
-    file << ::arg().table(overrideMap);
-    file.close();
-  }
-}
-#endif
-
 static pair<int, bool> doYamlConfig(Logr::log_t /* startupLog */, int argc, char* argv[]) // NOLINT: Posix API
 {
   if (!::arg().mustDo("config")) {
index daeb0dc77f4d3e3e63fd614152ba3ce7d43ccd02..9fc1d96bc8f0be2808a89688f2b116ab16ed2c90 100644 (file)
@@ -211,6 +211,7 @@ extern uint16_t g_udpTruncationThreshold;
 extern double g_balancingFactor;
 extern size_t g_maxUDPQueriesPerRound;
 extern bool g_useKernelTimestamp;
+extern bool g_allowNoRD;
 extern thread_local std::shared_ptr<NetmaskGroup> t_allowFrom;
 extern thread_local std::shared_ptr<NetmaskGroup> t_allowNotifyFrom;
 extern thread_local std::shared_ptr<notifyset_t> t_allowNotifyFor;
index a4778bdb0897ba5c31895954403f78ff30871c80..5086ec7609e881a66bb2884e27d140ab9b865462 100644 (file)
@@ -194,6 +194,18 @@ Like :ref:`setting-allow-notify-from`, except reading a sequence of `Subnet`_ fr
  ''',
     'versionadded': '4.6.0'
     },
+    {
+        'name' : 'allow_no_rd',
+        'section' : 'incoming',
+        'type' : LType.Bool,
+        'default' : 'false',
+        'help' : 'Allow \'no recursion desired (RD=0)\' queries.',
+        'doc' : '''
+Allow ``no recursion desired (RD=0) queries`` to query cache contents.
+If not set (the default), these queries are answered with rcode ``Refused``.
+ ''',
+    'versionadded': '5.5.0'
+    },
     {
         'name' : 'any_to_tcp',
         'section' : 'recursor',
@@ -204,7 +216,7 @@ Like :ref:`setting-allow-notify-from`, except reading a sequence of `Subnet`_ fr
 Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP.
 Useful for mitigating ANY reflection attacks.
  ''',
-    }, 
+    },
     {
         'name' : 'allow_trust_anchor_query',
         'section' : 'recursor',