From: Pavel Sapezhko Date: Tue, 24 Nov 2020 13:44:07 +0000 (+0300) Subject: resolved: allow cache responses from local DNS servers X-Git-Tag: v248-rc1~630 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6d8325f66a40d802b280492416660246db3476a6;p=thirdparty%2Fsystemd.git resolved: allow cache responses from local DNS servers --- diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml index 35a5740c914..3fdf5de58b0 100644 --- a/man/resolved.conf.xml +++ b/man/resolved.conf.xml @@ -251,8 +251,16 @@ request. Be aware that turning off caching comes at a performance penalty, which is particularly high when DNSSEC is used. If no-negative, only positive answers are cached. - 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. + Note that caching is turned off by default for host-local DNS servers. + See CacheFromLocalhost= for details. + + + + CacheFromLocalhost= + Takes a boolean as argument. If no (the default), and response cames from + host-local IP address (such as 127.0.0.1 or ::1), the result wouldn't be cached in order to avoid + potential duplicate local caching. + diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h index 7d6ee2bc4c1..0c804d6d2be 100644 --- a/src/resolve/resolved-dns-packet.h +++ b/src/resolve/resolved-dns-packet.h @@ -221,14 +221,6 @@ void dns_packet_rewind(DnsPacket *p, size_t idx); int dns_packet_skip_question(DnsPacket *p); int dns_packet_extract(DnsPacket *p); -static inline bool DNS_PACKET_SHALL_CACHE(DnsPacket *p) { - /* Never cache data originating from localhost, under the - * assumption, that it's coming from a locally DNS forwarder - * or server, that is caching on its own. */ - - return in_addr_is_localhost(p->family, &p->sender) == 0; -} - /* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 */ enum { DNS_RCODE_SUCCESS = 0, diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 1b8bead7c35..7a2d8723a0d 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -682,11 +682,9 @@ static void dns_transaction_cache_answer(DnsTransaction *t) { if (t->scope->manager->enable_cache == DNS_CACHE_MODE_NO) return; - /* We never cache if this packet is from the local host, under - * the assumption that a locally running DNS server would - * cache this anyway, and probably knows better when to flush - * the cache then we could. */ - if (!DNS_PACKET_SHALL_CACHE(t->received)) + /* Packet from localhost? */ + if (!t->scope->manager->cache_from_localhost && + in_addr_is_localhost(t->received->family, &t->received->sender) != 0) return; dns_cache_put(&t->scope->cache, diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h index 88b0d8eab9f..7f0b8e78472 100644 --- a/src/resolve/resolved-dns-transaction.h +++ b/src/resolve/resolved-dns-transaction.h @@ -2,6 +2,7 @@ #pragma once #include "sd-event.h" +#include "in-addr-util.h" typedef struct DnsTransaction DnsTransaction; typedef enum DnsTransactionState DnsTransactionState; diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf index b54fa1ba99b..2da273ab1e6 100644 --- a/src/resolve/resolved-gperf.gperf +++ b/src/resolve/resolved-gperf.gperf @@ -30,3 +30,4 @@ Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts) Resolve.ResolveUnicastSingleLabel, config_parse_bool, 0, offsetof(Manager, resolve_unicast_single_label) Resolve.DNSStubListenerExtra, config_parse_dns_stub_listener_extra, 0, offsetof(Manager, dns_extra_stub_listeners) +Resolve.CacheFromLocalhost, config_parse_bool, 0, offsetof(Manager, cache_from_localhost) diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 20afab05fdf..739683cbb52 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -39,6 +39,7 @@ struct Manager { DnssecMode dnssec_mode; DnsOverTlsMode dns_over_tls_mode; DnsCacheMode enable_cache; + bool cache_from_localhost; DnsStubListenerMode dns_stub_listener_mode; #if ENABLE_DNS_OVER_TLS diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in index 93279b3dff1..e1d06c0fb19 100644 --- a/src/resolve/resolved.conf.in +++ b/src/resolve/resolved.conf.in @@ -24,6 +24,7 @@ #MulticastDNS=@DEFAULT_MDNS_MODE@ #LLMNR=@DEFAULT_LLMNR_MODE@ #Cache=yes +#CacheFromLocalhost=no #DNSStubListener=yes #DNSStubListenerExtra= #ReadEtcHosts=yes diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service index 30ce98687a4..464496e2575 100644 --- a/test/fuzz/fuzz-unit-file/directives.service +++ b/test/fuzz/fuzz-unit-file/directives.service @@ -374,6 +374,7 @@ Bond= Bridge= Broadcast= Cache= +CacheFromLocalhost= ClientIdentifier= ConfigureWithoutCarrier= CopyDSCP=