* systemd-resolved gained support for a new 'strict' DNS-over-TLS mode.
+ * systemd-resolved "Cache=" configuration option in resolved.conf has been extended
+ to also accept the 'no-negative' value. Previously,
+ only a boolean option was allowed (yes/no), having yes as the default.
+ If this option is set to 'no-negative', negative answers are skipped
+ from being cached while keeping the same cache heuristics for positive answers.
+ The default remains as "yes" (i. e. caching is enabled).
+
* The predictable naming scheme for network devices now supports
generating predictable names for "netdevsim" devices.
<varlistentry>
<term><varname>Cache=</varname></term>
- <listitem><para>Takes a boolean argument. If <literal>yes</literal> (the default), resolving a domain name
+ <listitem><para>Takes a boolean or <literal>no-negative</literal> as argument. If <literal>yes</literal> (the default), resolving a domain name
which already got queried earlier will return the previous result as long as it is still valid, and thus does
not result in a new network request. Be aware that turning off caching comes at a performance penalty, which
is particularly high when DNSSEC is used.</para>
+ If <literal>no-negative</literal>, only positive answers are cached.
<para>Note that caching is turned off implicitly if the configured DNS server is on a host-local IP address
(such as 127.0.0.1 or ::1), in order to avoid duplicate local caching.</para></listitem>
int dns_cache_put(
DnsCache *c,
+ DnsCacheMode cache_mode,
DnsResourceKey *key,
int rcode,
DnsAnswer *answer,
return 0;
}
+ if (cache_mode == DNS_CACHE_MODE_NO_NEGATIVE) {
+ char key_str[DNS_RESOURCE_KEY_STRING_MAX];
+ log_debug("Not caching negative entry for: %s, cache mode set to no-negative",
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
+ return 0;
+ }
+
r = dns_cache_put_negative(
c,
key,
#include "hashmap.h"
#include "list.h"
#include "prioq.h"
+#include "resolve-util.h"
#include "time-util.h"
typedef struct DnsCache {
void dns_cache_flush(DnsCache *c);
void dns_cache_prune(DnsCache *c);
-int dns_cache_put(DnsCache *c, DnsResourceKey *key, int rcode, DnsAnswer *answer, bool authenticated, uint32_t nsec_ttl, usec_t timestamp, int owner_family, const union in_addr_union *owner_address);
+int dns_cache_put(DnsCache *c, DnsCacheMode cache_mode, DnsResourceKey *key, int rcode, DnsAnswer *answer, bool authenticated, uint32_t nsec_ttl, usec_t timestamp, int owner_family, const union in_addr_union *owner_address);
int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcode, DnsAnswer **answer, bool *authenticated);
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
return;
/* Caching disabled? */
- if (!t->scope->manager->enable_cache)
+ if (t->scope->manager->enable_cache == DNS_CACHE_MODE_NO)
return;
/* We never cache if this packet is from the local host, under
return;
dns_cache_put(&t->scope->cache,
+ t->scope->manager->enable_cache,
t->key,
t->answer_rcode,
t->answer,
Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Manager, dns_over_tls_mode)
-Resolve.Cache, config_parse_bool, 0, offsetof(Manager, enable_cache)
+Resolve.Cache, config_parse_dns_cache_mode, DNS_CACHE_MODE_YES, offsetof(Manager, enable_cache)
Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
-Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
+Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
\ No newline at end of file
.mdns_support = RESOLVE_SUPPORT_YES,
.dnssec_mode = DEFAULT_DNSSEC_MODE,
.dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
- .enable_cache = true,
+ .enable_cache = DNS_CACHE_MODE_YES,
.dns_stub_listener_mode = DNS_STUB_LISTENER_YES,
.read_resolv_conf = true,
.need_builtin_fallbacks = true,
ResolveSupport mdns_support;
DnssecMode dnssec_mode;
DnsOverTlsMode dns_over_tls_mode;
- bool enable_cache;
+ DnsCacheMode enable_cache;
DnsStubListenerMode dns_stub_listener_mode;
#if ENABLE_DNS_OVER_TLS
dns_transaction_process_reply(t, p);
}
- dns_cache_put(&scope->cache, NULL, DNS_PACKET_RCODE(p), p->answer, false, (uint32_t) -1, 0, p->family, &p->sender);
+ dns_cache_put(&scope->cache, scope->manager->enable_cache, NULL, DNS_PACKET_RCODE(p), p->answer, false, (uint32_t) -1, 0, p->family, &p->sender);
} else if (dns_packet_validate_query(p) > 0) {
log_debug("Got mDNS query packet for id %u", DNS_PACKET_ID(p));
return true;
}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_cache_mode, dns_cache_mode, DnsCacheMode, "Failed to parse DNS cache mode setting")
+
+static const char* const dns_cache_mode_table[_DNS_CACHE_MODE_MAX] = {
+ [DNS_CACHE_MODE_YES] = "yes",
+ [DNS_CACHE_MODE_NO] = "no",
+ [DNS_CACHE_MODE_NO_NEGATIVE] = "no-negative",
+};
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dns_cache_mode, DnsCacheMode, DNS_CACHE_MODE_YES);
/* 127.0.0.53 in native endian */
#define INADDR_DNS_STUB ((in_addr_t) 0x7f000035U)
+typedef enum DnsCacheMode DnsCacheMode;
+
+enum DnsCacheMode {
+ DNS_CACHE_MODE_NO,
+ DNS_CACHE_MODE_YES,
+ DNS_CACHE_MODE_NO_NEGATIVE,
+ _DNS_CACHE_MODE_MAX,
+ _DNS_CACHE_MODE_INVALID = 1
+};
+
typedef enum ResolveSupport ResolveSupport;
typedef enum DnssecMode DnssecMode;
typedef enum DnsOverTlsMode DnsOverTlsMode;
CONFIG_PARSER_PROTOTYPE(config_parse_resolve_support);
CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_mode);
CONFIG_PARSER_PROTOTYPE(config_parse_dns_over_tls_mode);
+CONFIG_PARSER_PROTOTYPE(config_parse_dns_cache_mode);
const char* resolve_support_to_string(ResolveSupport p) _const_;
ResolveSupport resolve_support_from_string(const char *s) _pure_;
DnsOverTlsMode dns_over_tls_mode_from_string(const char *s) _pure_;
bool dns_server_address_valid(int family, const union in_addr_union *sa);
+
+const char* dns_cache_mode_to_string(DnsCacheMode p) _const_;
+DnsCacheMode dns_cache_mode_from_string(const char *s) _pure_;