resolved: never cache RRs originating from localhost

After all, this is likely a local DNS forwarder that caches anyway,
hence there's no point in caching twice.

Fixes #2038.
This commit is contained in:
Lennart Poettering 2015-11-27 00:41:32 +01:00
parent 452b4e327d
commit d830ebbdf6
4 changed files with 25 additions and 2 deletions

View File

@ -44,7 +44,7 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
assert(u);
if (family == AF_INET)
return (be32toh(u->in.s_addr) & 0xFFFF0000) == (169U << 24 | 254U << 16);
return (be32toh(u->in.s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
if (family == AF_INET6)
return IN6_IS_ADDR_LINKLOCAL(&u->in6);
@ -52,6 +52,19 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
return -EAFNOSUPPORT;
}
int in_addr_is_localhost(int family, const union in_addr_union *u) {
assert(u);
if (family == AF_INET)
/* All of 127.x.x.x is localhost. */
return (be32toh(u->in.s_addr) & UINT32_C(0xFF000000)) == UINT32_C(127) << 24;
if (family == AF_INET)
return IN6_IS_ADDR_LOOPBACK(&u->in6);
return -EAFNOSUPPORT;
}
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) {
assert(a);
assert(b);

View File

@ -33,6 +33,7 @@ union in_addr_union {
int in_addr_is_null(int family, const union in_addr_union *u);
int in_addr_is_link_local(int family, const union in_addr_union *u);
int in_addr_is_localhost(int family, const union in_addr_union *u);
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b);
int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);

View File

@ -177,6 +177,14 @@ 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;
}
enum {
DNS_RCODE_SUCCESS = 0,
DNS_RCODE_FORMERR = 1,

View File

@ -478,7 +478,8 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) {
}
/* According to RFC 4795, section 2.9. only the RRs from the answer section shall be cached */
dns_cache_put(&t->scope->cache, t->key, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
if (DNS_PACKET_SHALL_CACHE(p))
dns_cache_put(&t->scope->cache, t->key, DNS_PACKET_RCODE(p), p->answer, DNS_PACKET_ANCOUNT(p), 0, p->family, &p->sender);
if (DNS_PACKET_RCODE(p) == DNS_RCODE_SUCCESS)
dns_transaction_complete(t, DNS_TRANSACTION_SUCCESS);