resolved-dns-cache.c revision 8e427d9be93e1289eba2a3055bbc632babc75b81
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering This file is part of systemd.
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering Copyright 2014 Lennart Poettering
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering systemd is free software; you can redistribute it and/or modify it
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering under the terms of the GNU Lesser General Public License as published by
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering (at your option) any later version.
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering systemd is distributed in the hope that it will be useful, but
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering Lesser General Public License for more details.
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering You should have received a copy of the GNU Lesser General Public License
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering/* Never cache more than 1K entries */
874ff7bf4d6fe693542209f127d23cd89adc499bLennart Poettering/* We never keep any item longer than 10min in our cache */
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering#define CACHE_TTL_MAX_USEC (10 * USEC_PER_MINUTE)
874ff7bf4d6fe693542209f127d23cd89adc499bLennart Poetteringtypedef enum DnsCacheItemType DnsCacheItemType;
874ff7bf4d6fe693542209f127d23cd89adc499bLennart Poetteringstatic void dns_cache_item_free(DnsCacheItem *i) {
2e3c585472540d69a1f4f2023bc5ed67bad8bdb2Susant SahaniDEFINE_TRIVIAL_CLEANUP_FUNC(DnsCacheItem*, dns_cache_item_free);
874ff7bf4d6fe693542209f127d23cd89adc499bLennart Poetteringstatic void dns_cache_item_remove_and_free(DnsCache *c, DnsCacheItem *i) {
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering assert_se(hashmap_replace(c->by_key, first->key, first) >= 0);
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poettering prioq_remove(c->by_expiry, i, &i->prioq_idx);
84e51726a38e133ca42d2f30f0668d3921b210cbLennart Poetteringstatic bool dns_cache_remove(DnsCache *c, DnsResourceKey *key) {
return exist;
assert(c);
if (add <= 0)
DnsCacheItem *i;
assert(i);
usec_t t = 0;
assert(c);
DnsCacheItem *i;
if (i->until > t)
static int dns_cache_item_prioq_compare_func(const void *a, const void *b) {
const DnsCacheItem *x = a, *y = b;
assert(c);
assert(c);
assert(i);
if (first) {
DnsCacheItem *i;
assert(c);
return NULL;
static void dns_cache_item_update_positive(DnsCache *c, DnsCacheItem *i, DnsResourceRecord *rr, usec_t timestamp) {
assert(c);
assert(i);
if (!i->by_key_prev)
static int dns_cache_put_positive(
DnsCache *c,
int owner_family,
assert(c);
if (existing) {
r = dns_cache_init(c);
return -ENOMEM;
r = dns_cache_link_item(c, i);
i = NULL;
static int dns_cache_put_negative(
DnsCache *c,
int rcode,
int owner_family,
assert(c);
if (soa_ttl <= 0) {
r = dns_cache_init(c);
return -ENOMEM;
r = dns_cache_link_item(c, i);
log_debug("Added %s cache entry for %s", i->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", key_str);
i = NULL;
int dns_cache_put(
DnsCache *c,
int rcode,
unsigned max_rrs,
int owner_family,
unsigned cache_keys, i;
assert(c);
if (key) {
if (!answer)
if (key)
cache_keys ++;
if (timestamp <= 0)
goto fail;
if (!key)
goto fail;
/* See https://tools.ietf.org/html/rfc2308, which
goto fail;
r = dns_cache_put_negative(c, key, rcode, timestamp, MIN(soa->soa.minimum, soa->ttl), owner_family, owner_address);
goto fail;
fail:
if (key)
bool nxdomain = false;
assert(c);
if (!first) {
if (j->rr)
nxdomain = true;
key_str);
if (!answer)
return -ENOMEM;
if (!j->rr)
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address) {
bool same_owner = true;
if (!first)
same_owner = false;
if (same_owner)
DnsCacheItem *i;
if (!cache)
f = stdout;
DnsCacheItem *j;
if (j->rr) {
log_oom();
fputs(t, f);
log_oom();
fputs(t, f);
if (!cache)