/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <net/if.h>

#include "af-list.h"
#include "alloc-util.h"
#include "dns-domain.h"
#include "format-util.h"
#include "resolved-dns-answer.h"
#include "resolved-dns-cache.h"
#include "resolved-dns-packet.h"
#include "string-util.h"

/* Never cache more than 4K entries. RFC 1536, Section 5 suggests to
 * leave DNS caches unbounded, but that's crazy. */
#define CACHE_MAX 4096

/* We never keep any item longer than 2h in our cache */
#define CACHE_TTL_MAX_USEC (2 * USEC_PER_HOUR)

/* How long to cache strange rcodes, i.e. rcodes != SUCCESS and != NXDOMAIN (specifically: that's only SERVFAIL for
 * now) */
#define CACHE_TTL_STRANGE_RCODE_USEC (10 * USEC_PER_SEC)

#define CACHEABLE_QUERY_FLAGS (SD_RESOLVED_AUTHENTICATED|SD_RESOLVED_CONFIDENTIAL)

typedef enum DnsCacheItemType DnsCacheItemType;
typedef struct DnsCacheItem DnsCacheItem;

enum DnsCacheItemType {
        DNS_CACHE_POSITIVE,
        DNS_CACHE_NODATA,
        DNS_CACHE_NXDOMAIN,
        DNS_CACHE_RCODE,      /* "strange" RCODE (effective only SERVFAIL for now) */
};

struct DnsCacheItem {
        DnsCacheItemType type;
        int rcode;
        DnsResourceKey *key;     /* The key for this item, i.e. the lookup key */
        DnsResourceRecord *rr;   /* The RR for this item, i.e. the lookup value for positive queries */
        DnsAnswer *answer;       /* The full validated answer, if this is an RRset acquired via a "primary" lookup */
        DnsPacket *full_packet;  /* The full packet this information was acquired with */

        usec_t until;
        uint64_t query_flags;    /* SD_RESOLVED_AUTHENTICATED and/or SD_RESOLVED_CONFIDENTIAL */
        DnssecResult dnssec_result;

        int ifindex;
        int owner_family;
        union in_addr_union owner_address;

        unsigned prioq_idx;
        LIST_FIELDS(DnsCacheItem, by_key);

        bool shared_owner;
};

/* Returns true if this is a cache item created as result of an explicit lookup, or created as "side-effect"
 * of another request. "Primary" entries will carry the full answer data (with NSEC, …) that can aso prove
 * wildcard expansion, non-existance and such, while entries that were created as "side-effect" just contain
 * immediate RR data for the specified RR key, but nothing else. */
#define DNS_CACHE_ITEM_IS_PRIMARY(item) (!!(item)->answer)

static const char *dns_cache_item_type_to_string(DnsCacheItem *item) {
        assert(item);

        switch (item->type) {

        case DNS_CACHE_POSITIVE:
                return "POSITIVE";

        case DNS_CACHE_NODATA:
                return "NODATA";

        case DNS_CACHE_NXDOMAIN:
                return "NXDOMAIN";

        case DNS_CACHE_RCODE:
                return dns_rcode_to_string(item->rcode);
        }

        return NULL;
}

static DnsCacheItem* dns_cache_item_free(DnsCacheItem *i) {
        if (!i)
                return NULL;

        dns_resource_record_unref(i->rr);
        dns_resource_key_unref(i->key);
        dns_answer_unref(i->answer);
        dns_packet_unref(i->full_packet);
        return mfree(i);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsCacheItem*, dns_cache_item_free);

static void dns_cache_item_unlink_and_free(DnsCache *c, DnsCacheItem *i) {
        DnsCacheItem *first;

        assert(c);

        if (!i)
                return;

        first = hashmap_get(c->by_key, i->key);
        LIST_REMOVE(by_key, first, i);

        if (first)
                assert_se(hashmap_replace(c->by_key, first->key, first) >= 0);
        else
                hashmap_remove(c->by_key, i->key);

        prioq_remove(c->by_expiry, i, &i->prioq_idx);

        dns_cache_item_free(i);
}

static bool dns_cache_remove_by_rr(DnsCache *c, DnsResourceRecord *rr) {
        DnsCacheItem *first, *i;
        int r;

        first = hashmap_get(c->by_key, rr->key);
        LIST_FOREACH(by_key, i, first) {
                r = dns_resource_record_equal(i->rr, rr);
                if (r < 0)
                        return r;
                if (r > 0) {
                        dns_cache_item_unlink_and_free(c, i);
                        return true;
                }
        }

        return false;
}

static bool dns_cache_remove_by_key(DnsCache *c, DnsResourceKey *key) {
        DnsCacheItem *first, *i, *n;

        assert(c);
        assert(key);

        first = hashmap_remove(c->by_key, key);
        if (!first)
                return false;

        LIST_FOREACH_SAFE(by_key, i, n, first) {
                prioq_remove(c->by_expiry, i, &i->prioq_idx);
                dns_cache_item_free(i);
        }

        return true;
}

void dns_cache_flush(DnsCache *c) {
        DnsResourceKey *key;

        assert(c);

        while ((key = hashmap_first_key(c->by_key)))
                dns_cache_remove_by_key(c, key);

        assert(hashmap_size(c->by_key) == 0);
        assert(prioq_size(c->by_expiry) == 0);

        c->by_key = hashmap_free(c->by_key);
        c->by_expiry = prioq_free(c->by_expiry);
}

static void dns_cache_make_space(DnsCache *c, unsigned add) {
        assert(c);

        if (add <= 0)
                return;

        /* Makes space for n new entries. Note that we actually allow
         * the cache to grow beyond CACHE_MAX, but only when we shall
         * add more RRs to the cache than CACHE_MAX at once. In that
         * case the cache will be emptied completely otherwise. */

        for (;;) {
                _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
                DnsCacheItem *i;

                if (prioq_size(c->by_expiry) <= 0)
                        break;

                if (prioq_size(c->by_expiry) + add < CACHE_MAX)
                        break;

                i = prioq_peek(c->by_expiry);
                assert(i);

                /* Take an extra reference to the key so that it
                 * doesn't go away in the middle of the remove call */
                key = dns_resource_key_ref(i->key);
                dns_cache_remove_by_key(c, key);
        }
}

void dns_cache_prune(DnsCache *c) {
        usec_t t = 0;

        assert(c);

        /* Remove all entries that are past their TTL */

        for (;;) {
                DnsCacheItem *i;
                char key_str[DNS_RESOURCE_KEY_STRING_MAX];

                i = prioq_peek(c->by_expiry);
                if (!i)
                        break;

                if (t <= 0)
                        t = now(clock_boottime_or_monotonic());

                if (i->until > t)
                        break;

                /* Depending whether this is an mDNS shared entry
                 * either remove only this one RR or the whole RRset */
                log_debug("Removing %scache entry for %s (expired "USEC_FMT"s ago)",
                          i->shared_owner ? "shared " : "",
                          dns_resource_key_to_string(i->key, key_str, sizeof key_str),
                          (t - i->until) / USEC_PER_SEC);

                if (i->shared_owner)
                        dns_cache_item_unlink_and_free(c, i);
                else {
                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;

                        /* Take an extra reference to the key so that it
                         * doesn't go away in the middle of the remove call */
                        key = dns_resource_key_ref(i->key);
                        dns_cache_remove_by_key(c, key);
                }
        }
}

static int dns_cache_item_prioq_compare_func(const void *a, const void *b) {
        const DnsCacheItem *x = a, *y = b;

        return CMP(x->until, y->until);
}

static int dns_cache_init(DnsCache *c) {
        int r;

        assert(c);

        r = prioq_ensure_allocated(&c->by_expiry, dns_cache_item_prioq_compare_func);
        if (r < 0)
                return r;

        r = hashmap_ensure_allocated(&c->by_key, &dns_resource_key_hash_ops);
        if (r < 0)
                return r;

        return r;
}

static int dns_cache_link_item(DnsCache *c, DnsCacheItem *i) {
        DnsCacheItem *first;
        int r;

        assert(c);
        assert(i);

        r = prioq_put(c->by_expiry, i, &i->prioq_idx);
        if (r < 0)
                return r;

        first = hashmap_get(c->by_key, i->key);
        if (first) {
                _unused_ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;

                /* Keep a reference to the original key, while we manipulate the list. */
                k = dns_resource_key_ref(first->key);

                /* Now, try to reduce the number of keys we keep */
                dns_resource_key_reduce(&first->key, &i->key);

                if (first->rr)
                        dns_resource_key_reduce(&first->rr->key, &i->key);
                if (i->rr)
                        dns_resource_key_reduce(&i->rr->key, &i->key);

                LIST_PREPEND(by_key, first, i);
                assert_se(hashmap_replace(c->by_key, first->key, first) >= 0);
        } else {
                r = hashmap_put(c->by_key, i->key, i);
                if (r < 0) {
                        prioq_remove(c->by_expiry, i, &i->prioq_idx);
                        return r;
                }
        }

        return 0;
}

static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
        DnsCacheItem *i;

        assert(c);
        assert(rr);

        LIST_FOREACH(by_key, i, hashmap_get(c->by_key, rr->key))
                if (i->rr && dns_resource_record_equal(i->rr, rr) > 0)
                        return i;

        return NULL;
}

static usec_t calculate_until(
                DnsResourceRecord *rr,
                uint32_t min_ttl,
                uint32_t nsec_ttl,
                usec_t timestamp,
                bool use_soa_minimum) {

        uint32_t ttl;
        usec_t u;

        assert(rr);

        ttl = MIN(min_ttl, nsec_ttl);
        if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
                /* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
                 * when we do negative caching, to determine the TTL for the negative caching entry. See RFC
                 * 2308, Section 5. */

                if (ttl > rr->soa.minimum)
                        ttl = rr->soa.minimum;
        }

        u = ttl * USEC_PER_SEC;
        if (u > CACHE_TTL_MAX_USEC)
                u = CACHE_TTL_MAX_USEC;

        if (rr->expiry != USEC_INFINITY) {
                usec_t left;

                /* Make use of the DNSSEC RRSIG expiry info, if we have it */

                left = LESS_BY(rr->expiry, now(CLOCK_REALTIME));
                if (u > left)
                        u = left;
        }

        return timestamp + u;
}

static void dns_cache_item_update_positive(
                DnsCache *c,
                DnsCacheItem *i,
                DnsResourceRecord *rr,
                DnsAnswer *answer,
                DnsPacket *full_packet,
                uint32_t min_ttl,
                uint64_t query_flags,
                bool shared_owner,
                DnssecResult dnssec_result,
                usec_t timestamp,
                int ifindex,
                int owner_family,
                const union in_addr_union *owner_address) {

        assert(c);
        assert(i);
        assert(rr);
        assert(owner_address);

        i->type = DNS_CACHE_POSITIVE;

        if (!i->by_key_prev)
                /* We are the first item in the list, we need to
                 * update the key used in the hashmap */

                assert_se(hashmap_replace(c->by_key, rr->key, i) >= 0);

        dns_resource_record_ref(rr);
        dns_resource_record_unref(i->rr);
        i->rr = rr;

        dns_resource_key_unref(i->key);
        i->key = dns_resource_key_ref(rr->key);

        dns_answer_ref(answer);
        dns_answer_unref(i->answer);
        i->answer = answer;

        dns_packet_ref(full_packet);
        dns_packet_unref(i->full_packet);
        i->full_packet = full_packet;

        i->until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false);
        i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS;
        i->shared_owner = shared_owner;
        i->dnssec_result = dnssec_result;

        i->ifindex = ifindex;

        i->owner_family = owner_family;
        i->owner_address = *owner_address;

        prioq_reshuffle(c->by_expiry, i, &i->prioq_idx);
}

static int dns_cache_put_positive(
                DnsCache *c,
                DnsResourceRecord *rr,
                DnsAnswer *answer,
                DnsPacket *full_packet,
                uint64_t query_flags,
                bool shared_owner,
                DnssecResult dnssec_result,
                usec_t timestamp,
                int ifindex,
                int owner_family,
                const union in_addr_union *owner_address) {

        _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
        char key_str[DNS_RESOURCE_KEY_STRING_MAX];
        DnsCacheItem *existing;
        uint32_t min_ttl;
        int r;

        assert(c);
        assert(rr);
        assert(owner_address);

        /* Never cache pseudo RRs */
        if (dns_class_is_pseudo(rr->key->class))
                return 0;
        if (dns_type_is_pseudo(rr->key->type))
                return 0;

        /* Determine the minimal TTL of all RRs in the answer plus the one by the main RR we are supposed to
         * cache. Since we cache whole answers to questions we should never return answers where only some
         * RRs are still valid, hence find the lowest here */
        min_ttl = MIN(dns_answer_min_ttl(answer), rr->ttl);

        /* New TTL is 0? Delete this specific entry... */
        if (min_ttl <= 0) {
                r = dns_cache_remove_by_rr(c, rr);
                log_debug("%s: %s",
                          r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
                          dns_resource_key_to_string(rr->key, key_str, sizeof key_str));
                return 0;
        }

        /* Entry exists already? Update TTL, timestamp and owner */
        existing = dns_cache_get(c, rr);
        if (existing) {
                dns_cache_item_update_positive(
                                c,
                                existing,
                                rr,
                                answer,
                                full_packet,
                                min_ttl,
                                query_flags,
                                shared_owner,
                                dnssec_result,
                                timestamp,
                                ifindex,
                                owner_family,
                                owner_address);
                return 0;
        }

        /* Otherwise, add the new RR */
        r = dns_cache_init(c);
        if (r < 0)
                return r;

        dns_cache_make_space(c, 1);

        i = new(DnsCacheItem, 1);
        if (!i)
                return -ENOMEM;

        *i = (DnsCacheItem) {
                .type = DNS_CACHE_POSITIVE,
                .key = dns_resource_key_ref(rr->key),
                .rr = dns_resource_record_ref(rr),
                .answer = dns_answer_ref(answer),
                .full_packet = dns_packet_ref(full_packet),
                .until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false),
                .query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
                .shared_owner = shared_owner,
                .dnssec_result = dnssec_result,
                .ifindex = ifindex,
                .owner_family = owner_family,
                .owner_address = *owner_address,
                .prioq_idx = PRIOQ_IDX_NULL,
        };

        r = dns_cache_link_item(c, i);
        if (r < 0)
                return r;

        if (DEBUG_LOGGING) {
                _cleanup_free_ char *t = NULL;
                char ifname[IF_NAMESIZE + 1];

                (void) in_addr_to_string(i->owner_family, &i->owner_address, &t);

                log_debug("Added positive %s %s%s cache entry for %s "USEC_FMT"s on %s/%s/%s",
                          FLAGS_SET(i->query_flags, SD_RESOLVED_AUTHENTICATED) ? "authenticated" : "unauthenticated",
                          FLAGS_SET(i->query_flags, SD_RESOLVED_CONFIDENTIAL) ? "confidential" : "non-confidential",
                          i->shared_owner ? " shared" : "",
                          dns_resource_key_to_string(i->key, key_str, sizeof key_str),
                          (i->until - timestamp) / USEC_PER_SEC,
                          i->ifindex == 0 ? "*" : strna(format_ifname(i->ifindex, ifname)),
                          af_to_name_short(i->owner_family),
                          strna(t));
        }

        i = NULL;
        return 0;
}

static int dns_cache_put_negative(
                DnsCache *c,
                DnsResourceKey *key,
                int rcode,
                DnsAnswer *answer,
                DnsPacket *full_packet,
                uint64_t query_flags,
                DnssecResult dnssec_result,
                uint32_t nsec_ttl,
                usec_t timestamp,
                DnsResourceRecord *soa,
                int owner_family,
                const union in_addr_union *owner_address) {

        _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
        char key_str[DNS_RESOURCE_KEY_STRING_MAX];
        int r;

        assert(c);
        assert(key);
        assert(owner_address);

        /* Never cache pseudo RR keys. DNS_TYPE_ANY is particularly
         * important to filter out as we use this as a pseudo-type for
         * NXDOMAIN entries */
        if (dns_class_is_pseudo(key->class))
                return 0;
        if (dns_type_is_pseudo(key->type))
                return 0;

        if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
                if (!soa)
                        return 0;

                /* For negative replies, check if we have a TTL of a SOA */
                if (nsec_ttl <= 0 || soa->soa.minimum <= 0 || soa->ttl <= 0) {
                        log_debug("Not caching negative entry with zero SOA/NSEC/NSEC3 TTL: %s",
                                  dns_resource_key_to_string(key, key_str, sizeof key_str));
                        return 0;
                }
        } else if (rcode != DNS_RCODE_SERVFAIL)
                return 0;

        r = dns_cache_init(c);
        if (r < 0)
                return r;

        dns_cache_make_space(c, 1);

        i = new(DnsCacheItem, 1);
        if (!i)
                return -ENOMEM;

        *i = (DnsCacheItem) {
                .type =
                        rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA :
                        rcode == DNS_RCODE_NXDOMAIN ? DNS_CACHE_NXDOMAIN : DNS_CACHE_RCODE,
                .query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
                .dnssec_result = dnssec_result,
                .owner_family = owner_family,
                .owner_address = *owner_address,
                .prioq_idx = PRIOQ_IDX_NULL,
                .rcode = rcode,
                .answer = dns_answer_ref(answer),
                .full_packet = dns_packet_ref(full_packet),
        };

        /* Determine how long to cache this entry. In case we have some RRs in the answer use the lowest TTL
         * of any of them. Typically that's the SOA's TTL, which is OK, but could possibly be lower because
         * of some other RR. Let's better take the lowest option here than a needlessly high one */
        i->until =
                i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
                calculate_until(soa, dns_answer_min_ttl(answer), nsec_ttl, timestamp, true);

        if (i->type == DNS_CACHE_NXDOMAIN) {
                /* NXDOMAIN entries should apply equally to all types, so we use ANY as
                 * a pseudo type for this purpose here. */
                i->key = dns_resource_key_new(key->class, DNS_TYPE_ANY, dns_resource_key_name(key));
                if (!i->key)
                        return -ENOMEM;

                /* Make sure to remove any previous entry for this
                 * specific ANY key. (For non-ANY keys the cache data
                 * is already cleared by the caller.) Note that we
                 * don't bother removing positive or NODATA cache
                 * items in this case, because it would either be slow
                 * or require explicit indexing by name */
                dns_cache_remove_by_key(c, key);
        } else
                i->key = dns_resource_key_ref(key);

        r = dns_cache_link_item(c, i);
        if (r < 0)
                return r;

        log_debug("Added %s cache entry for %s "USEC_FMT"s",
                  dns_cache_item_type_to_string(i),
                  dns_resource_key_to_string(i->key, key_str, sizeof key_str),
                  (i->until - timestamp) / USEC_PER_SEC);

        i = NULL;
        return 0;
}

static void dns_cache_remove_previous(
                DnsCache *c,
                DnsResourceKey *key,
                DnsAnswer *answer) {

        DnsResourceRecord *rr;
        DnsAnswerFlags flags;

        assert(c);

        /* First, if we were passed a key (i.e. on LLMNR/DNS, but
         * not on mDNS), delete all matching old RRs, so that we only
         * keep complete by_key in place. */
        if (key)
                dns_cache_remove_by_key(c, key);

        /* Second, flush all entries matching the answer, unless this
         * is an RR that is explicitly marked to be "shared" between
         * peers (i.e. mDNS RRs without the flush-cache bit set). */
        DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
                if ((flags & DNS_ANSWER_CACHEABLE) == 0)
                        continue;

                if (flags & DNS_ANSWER_SHARED_OWNER)
                        continue;

                dns_cache_remove_by_key(c, rr->key);
        }
}

static bool rr_eligible(DnsResourceRecord *rr) {
        assert(rr);

        /* When we see an NSEC/NSEC3 RR, we'll only cache it if it is from the lower zone, not the upper zone, since
         * that's where the interesting bits are (with exception of DS RRs). Of course, this way we cannot derive DS
         * existence from any cached NSEC/NSEC3, but that should be fine. */

        switch (rr->key->type) {

        case DNS_TYPE_NSEC:
                return !systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_NS) ||
                        systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_SOA);

        case DNS_TYPE_NSEC3:
                return !systemd_bitmap_isset(rr->nsec3.types, DNS_TYPE_NS) ||
                        systemd_bitmap_isset(rr->nsec3.types, DNS_TYPE_SOA);

        default:
                return true;
        }
}

int dns_cache_put(
                DnsCache *c,
                DnsCacheMode cache_mode,
                DnsResourceKey *key,
                int rcode,
                DnsAnswer *answer,
                DnsPacket *full_packet,
                uint64_t query_flags,
                DnssecResult dnssec_result,
                uint32_t nsec_ttl,
                int owner_family,
                const union in_addr_union *owner_address) {

        DnsResourceRecord *soa = NULL;
        bool weird_rcode = false;
        DnsAnswerItem *item;
        DnsAnswerFlags flags;
        unsigned cache_keys;
        usec_t timestamp;
        int r;

        assert(c);
        assert(owner_address);

        dns_cache_remove_previous(c, key, answer);

        /* We only care for positive replies and NXDOMAINs, on all other replies we will simply flush the respective
         * entries, and that's it. (Well, with one further exception: since some DNS zones (akamai!) return SERVFAIL
         * consistently for some lookups, and forwarders tend to propagate that we'll cache that too, but only for a
         * short time.) */

        if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
                if (dns_answer_isempty(answer)) {
                        if (key) {
                                char key_str[DNS_RESOURCE_KEY_STRING_MAX];

                                log_debug("Not caching negative entry without a SOA record: %s",
                                          dns_resource_key_to_string(key, key_str, sizeof key_str));
                        }

                        return 0;
                }

        } else {
                /* Only cache SERVFAIL as "weird" rcode for now. We can add more later, should that turn out to be
                 * beneficial. */
                if (rcode != DNS_RCODE_SERVFAIL)
                        return 0;

                weird_rcode = true;
        }

        cache_keys = dns_answer_size(answer);
        if (key)
                cache_keys++;

        /* Make some space for our new entries */
        dns_cache_make_space(c, cache_keys);

        timestamp = now(clock_boottime_or_monotonic());

        /* Second, add in positive entries for all contained RRs */
        DNS_ANSWER_FOREACH_ITEM(item, answer) {
                int primary = false;

                if (!FLAGS_SET(item->flags, DNS_ANSWER_CACHEABLE) ||
                    !rr_eligible(item->rr))
                        continue;

                if (key) {
                        /* We store the auxiliary RRs and packet data in the cache only if they were in
                         * direct response to the original query. If we cache an RR we also received, and
                         * that is just auxiliary information we can't use the data, hence don't. */

                        primary = dns_resource_key_match_rr(key, item->rr, NULL);
                        if (primary < 0)
                                return primary;
                        if (primary == 0) {
                                primary = dns_resource_key_match_cname_or_dname(key, item->rr->key, NULL);
                                if (primary < 0)
                                        return primary;
                        }
                }

                if (!primary) {
                        DnsCacheItem *first;

                        /* Do not replace existing cache items for primary lookups with non-primary
                         * data. After all the primary lookup data is a lot more useful. */
                        first = hashmap_get(c->by_key, item->rr->key);
                        if (first && DNS_CACHE_ITEM_IS_PRIMARY(first))
                                return 0;
                }

                r = dns_cache_put_positive(
                                c,
                                item->rr,
                                primary ? answer : NULL,
                                primary ? full_packet : NULL,
                                ((item->flags & DNS_ANSWER_AUTHENTICATED) ? SD_RESOLVED_AUTHENTICATED : 0) |
                                (query_flags & SD_RESOLVED_CONFIDENTIAL),
                                item->flags & DNS_ANSWER_SHARED_OWNER,
                                dnssec_result,
                                timestamp,
                                item->ifindex,
                                owner_family,
                                owner_address);
                if (r < 0)
                        goto fail;
        }

        if (!key) /* mDNS doesn't know negative caching, really */
                return 0;

        /* Third, add in negative entries if the key has no RR */
        r = dns_answer_match_key(answer, key, NULL);
        if (r < 0)
                goto fail;
        if (r > 0)
                return 0;

        /* But not if it has a matching CNAME/DNAME (the negative caching will be done on the canonical name,
         * not on the alias) */
        r = dns_answer_find_cname_or_dname(answer, key, NULL, NULL);
        if (r < 0)
                goto fail;
        if (r > 0)
                return 0;

        /* See https://tools.ietf.org/html/rfc2308, which say that a matching SOA record in the packet is used to
         * enable negative caching. We apply one exception though: if we are about to cache a weird rcode we do so
         * regardless of a SOA. */
        r = dns_answer_find_soa(answer, key, &soa, &flags);
        if (r < 0)
                goto fail;
        if (r == 0 && !weird_rcode)
                return 0;
        if (r > 0) {
                /* Refuse using the SOA data if it is unsigned, but the key is signed */
                if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) &&
                    (flags & DNS_ANSWER_AUTHENTICATED) == 0)
                        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,
                        rcode,
                        answer,
                        full_packet,
                        query_flags,
                        dnssec_result,
                        nsec_ttl,
                        timestamp,
                        soa,
                        owner_family, owner_address);
        if (r < 0)
                goto fail;

        return 0;

fail:
        /* Adding all RRs failed. Let's clean up what we already
         * added, just in case */

        if (key)
                dns_cache_remove_by_key(c, key);

        DNS_ANSWER_FOREACH_ITEM(item, answer) {
                if ((item->flags & DNS_ANSWER_CACHEABLE) == 0)
                        continue;

                dns_cache_remove_by_key(c, item->rr->key);
        }

        return r;
}

static DnsCacheItem *dns_cache_get_by_key_follow_cname_dname_nsec(DnsCache *c, DnsResourceKey *k) {
        DnsCacheItem *i;
        const char *n;
        int r;

        assert(c);
        assert(k);

        /* If we hit some OOM error, or suchlike, we don't care too
         * much, after all this is just a cache */

        i = hashmap_get(c->by_key, k);
        if (i)
                return i;

        n = dns_resource_key_name(k);

        /* Check if we have an NXDOMAIN cache item for the name, notice that we use
         * the pseudo-type ANY for NXDOMAIN cache items. */
        i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_ANY, n));
        if (i && i->type == DNS_CACHE_NXDOMAIN)
                return i;

        if (dns_type_may_redirect(k->type)) {
                /* Check if we have a CNAME record instead */
                i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_CNAME, n));
                if (i && i->type != DNS_CACHE_NODATA)
                        return i;

                /* OK, let's look for cached DNAME records. */
                for (;;) {
                        if (isempty(n))
                                return NULL;

                        i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_DNAME, n));
                        if (i && i->type != DNS_CACHE_NODATA)
                                return i;

                        /* Jump one label ahead */
                        r = dns_name_parent(&n);
                        if (r <= 0)
                                return NULL;
                }
        }

        if (k->type != DNS_TYPE_NSEC) {
                /* Check if we have an NSEC record instead for the name. */
                i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_NSEC, n));
                if (i)
                        return i;
        }

        return NULL;
}

static int answer_add_clamp_ttl(
                DnsAnswer **answer,
                DnsResourceRecord *rr,
                int ifindex,
                DnsAnswerFlags answer_flags,
                DnsResourceRecord *rrsig,
                uint64_t query_flags,
                usec_t until,
                usec_t current) {

        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *patched = NULL, *patched_rrsig = NULL;
        int r;

        assert(answer);
        assert(rr);

        if (FLAGS_SET(query_flags, SD_RESOLVED_CLAMP_TTL)) {
                uint32_t left_ttl;

                assert(current > 0);

                /* Let's determine how much time is left for this cache entry. Note that we round down, but
                 * clamp this to be 1s at minimum, since we usually want records to remain cached better too
                 * short a time than too long a time, but otoh don't want to return 0 ever, since that has
                 * special semantics in various contexts — in particular in mDNS */

                left_ttl = MAX(1U, LESS_BY(until, current) / USEC_PER_SEC);

                patched = dns_resource_record_ref(rr);

                r = dns_resource_record_clamp_ttl(&patched, left_ttl);
                if (r < 0)
                        return r;

                rr = patched;

                if (rrsig) {
                        patched_rrsig = dns_resource_record_ref(rrsig);
                        r = dns_resource_record_clamp_ttl(&patched_rrsig, left_ttl);
                        if (r < 0)
                                return r;

                        rrsig = patched_rrsig;
                }
        }

        r = dns_answer_add_extend(answer, rr, ifindex, answer_flags, rrsig);
        if (r < 0)
                return r;

        return 0;
}

int dns_cache_lookup(
                DnsCache *c,
                DnsResourceKey *key,
                uint64_t query_flags,
                int *ret_rcode,
                DnsAnswer **ret_answer,
                DnsPacket **ret_full_packet,
                uint64_t *ret_query_flags,
                DnssecResult *ret_dnssec_result) {

        _cleanup_(dns_packet_unrefp) DnsPacket *full_packet = NULL;
        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
        char key_str[DNS_RESOURCE_KEY_STRING_MAX];
        unsigned n = 0;
        int r;
        bool nxdomain = false;
        DnsCacheItem *j, *first, *nsec = NULL;
        bool have_authenticated = false, have_non_authenticated = false, have_confidential = false, have_non_confidential = false;
        usec_t current = 0;
        int found_rcode = -1;
        DnssecResult dnssec_result = -1;
        int have_dnssec_result = -1;

        assert(c);
        assert(key);

        if (key->type == DNS_TYPE_ANY || key->class == DNS_CLASS_ANY) {
                /* If we have ANY lookups we don't use the cache, so that the caller refreshes via the
                 * network. */

                log_debug("Ignoring cache for ANY lookup: %s",
                          dns_resource_key_to_string(key, key_str, sizeof key_str));
                goto miss;
        }

        first = dns_cache_get_by_key_follow_cname_dname_nsec(c, key);
        if (!first) {
                /* If one question cannot be answered we need to refresh */

                log_debug("Cache miss for %s",
                          dns_resource_key_to_string(key, key_str, sizeof key_str));
                goto miss;
        }

        if (FLAGS_SET(query_flags, SD_RESOLVED_CLAMP_TTL)) {
                /* 'current' is always passed to answer_add_clamp_ttl(), but is only used conditionally.
                 * We'll do the same assert there to make sure that it was initialized properly. */
                current = now(clock_boottime_or_monotonic());
                assert(current > 0);
        }

        LIST_FOREACH(by_key, j, first) {
                /* If the caller doesn't allow us to answer questions from cache data learned from
                 * "side-effect", skip this entry. */
                if (FLAGS_SET(query_flags, SD_RESOLVED_REQUIRE_PRIMARY) &&
                    !DNS_CACHE_ITEM_IS_PRIMARY(j)) {
                        log_debug("Primary answer was requested for cache lookup for %s, which we don't have.",
                                  dns_resource_key_to_string(key, key_str, sizeof key_str));

                        goto miss;
                }

                if (j->type == DNS_CACHE_NXDOMAIN)
                        nxdomain = true;
                else if (j->type == DNS_CACHE_RCODE)
                        found_rcode = j->rcode;
                else if (j->rr) {
                        if (j->rr->key->type == DNS_TYPE_NSEC)
                                nsec = j;

                        n++;
                }

                if (FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED))
                        have_authenticated = true;
                else
                        have_non_authenticated = true;

                if (FLAGS_SET(j->query_flags, SD_RESOLVED_CONFIDENTIAL))
                        have_confidential = true;
                else
                        have_non_confidential = true;

                if (j->dnssec_result < 0) {
                        have_dnssec_result = false; /* an entry without dnssec result? then invalidate things for good */
                        dnssec_result = _DNSSEC_RESULT_INVALID;
                } else if (have_dnssec_result < 0) {
                        have_dnssec_result = true; /* So far no result seen, let's pick this one up */
                        dnssec_result = j->dnssec_result;
                } else if (have_dnssec_result > 0 && j->dnssec_result != dnssec_result) {
                        have_dnssec_result = false; /* conflicting result seen? then invalidate for good */
                        dnssec_result = _DNSSEC_RESULT_INVALID;
                }

                /* Append the answer RRs to our answer. Ideally we have the answer object, which we
                 * preferably use. But if the cached entry was generated as "side-effect" of a reply,
                 * i.e. from validated auxiliary records rather than from the main reply, then we use the
                 * individual RRs only instead. */
                if (j->answer) {

                        /* Minor optimization, if the full answer object of this and the previous RR is the
                         * same, don't bother adding it again. Typically we store a full RRset here, hence
                         * that should be the case. */
                        if (!j->by_key_prev || j->answer != j->by_key_prev->answer) {
                                DnsAnswerItem *item;

                                DNS_ANSWER_FOREACH_ITEM(item, j->answer) {
                                        r = answer_add_clamp_ttl(
                                                        &answer,
                                                        item->rr,
                                                        item->ifindex,
                                                        item->flags,
                                                        item->rrsig,
                                                        query_flags,
                                                        j->until,
                                                        current);
                                        if (r < 0)
                                                return r;
                                }
                        }

                } else if (j->rr) {
                        r = answer_add_clamp_ttl(
                                        &answer,
                                        j->rr,
                                        j->ifindex,
                                        FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
                                        NULL,
                                        query_flags,
                                        j->until,
                                        current);
                        if (r < 0)
                                return r;
                }

                /* We'll return any packet we have for this. Typically all cache entries for the same key
                 * should come from the same packet anyway, hence it doesn't really matter which packet we
                 * return here, they should all resolve to the same anyway. */
                if (!full_packet && j->full_packet)
                        full_packet = dns_packet_ref(j->full_packet);
        }

        if (found_rcode >= 0) {
                log_debug("RCODE %s cache hit for %s",
                          dns_rcode_to_string(found_rcode),
                          dns_resource_key_to_string(key, key_str, sizeof(key_str)));

                if (ret_rcode)
                        *ret_rcode = found_rcode;
                if (ret_answer)
                        *ret_answer = TAKE_PTR(answer);
                if (ret_full_packet)
                        *ret_full_packet = TAKE_PTR(full_packet);
                if (ret_query_flags)
                        *ret_query_flags = 0;
                if (ret_dnssec_result)
                        *ret_dnssec_result = dnssec_result;

                c->n_hit++;
                return 1;
        }

        if (nsec && !IN_SET(key->type, DNS_TYPE_NSEC, DNS_TYPE_DS)) {
                /* Note that we won't derive information for DS RRs from an NSEC, because we only cache NSEC
                 * RRs from the lower-zone of a zone cut, but the DS RRs are on the upper zone. */

                log_debug("NSEC NODATA cache hit for %s",
                          dns_resource_key_to_string(key, key_str, sizeof key_str));

                /* We only found an NSEC record that matches our name.  If it says the type doesn't exist
                 * report NODATA. Otherwise report a cache miss. */

                if (ret_rcode)
                        *ret_rcode = DNS_RCODE_SUCCESS;
                if (ret_answer)
                        *ret_answer = TAKE_PTR(answer);
                if (ret_full_packet)
                        *ret_full_packet = TAKE_PTR(full_packet);
                if (ret_query_flags)
                        *ret_query_flags = nsec->query_flags;
                if (ret_dnssec_result)
                        *ret_dnssec_result = nsec->dnssec_result;

                if (!systemd_bitmap_isset(nsec->rr->nsec.types, key->type) &&
                    !systemd_bitmap_isset(nsec->rr->nsec.types, DNS_TYPE_CNAME) &&
                    !systemd_bitmap_isset(nsec->rr->nsec.types, DNS_TYPE_DNAME)) {
                        c->n_hit++;
                        return 1;
                }

                c->n_miss++;
                return 0;
        }

        log_debug("%s cache hit for %s",
                  n > 0    ? "Positive" :
                  nxdomain ? "NXDOMAIN" : "NODATA",
                  dns_resource_key_to_string(key, key_str, sizeof key_str));

        if (n <= 0) {
                c->n_hit++;

                if (ret_rcode)
                        *ret_rcode = nxdomain ? DNS_RCODE_NXDOMAIN : DNS_RCODE_SUCCESS;
                if (ret_answer)
                        *ret_answer = TAKE_PTR(answer);
                if (ret_full_packet)
                        *ret_full_packet = TAKE_PTR(full_packet);
                if (ret_query_flags)
                        *ret_query_flags =
                                ((have_authenticated && !have_non_authenticated) ? SD_RESOLVED_AUTHENTICATED : 0) |
                                ((have_confidential && !have_non_confidential) ? SD_RESOLVED_CONFIDENTIAL : 0);
                if (ret_dnssec_result)
                        *ret_dnssec_result = dnssec_result;

                return 1;
        }

        c->n_hit++;

        if (ret_rcode)
                *ret_rcode = DNS_RCODE_SUCCESS;
        if (ret_answer)
                *ret_answer = TAKE_PTR(answer);
        if (ret_full_packet)
                *ret_full_packet = TAKE_PTR(full_packet);
        if (ret_query_flags)
                *ret_query_flags =
                        ((have_authenticated && !have_non_authenticated) ? SD_RESOLVED_AUTHENTICATED : 0) |
                        ((have_confidential && !have_non_confidential) ? SD_RESOLVED_CONFIDENTIAL : 0);
        if (ret_dnssec_result)
                *ret_dnssec_result = dnssec_result;

        return n;

miss:
        if (ret_rcode)
                *ret_rcode = DNS_RCODE_SUCCESS;
        if (ret_answer)
                *ret_answer = NULL;
        if (ret_full_packet)
                *ret_full_packet = NULL;
        if (ret_query_flags)
                *ret_query_flags = 0;
        if (ret_dnssec_result)
                *ret_dnssec_result = _DNSSEC_RESULT_INVALID;

        c->n_miss++;
        return 0;
}

int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address) {
        DnsCacheItem *i, *first;
        bool same_owner = true;

        assert(cache);
        assert(rr);

        dns_cache_prune(cache);

        /* See if there's a cache entry for the same key. If there
         * isn't there's no conflict */
        first = hashmap_get(cache->by_key, rr->key);
        if (!first)
                return 0;

        /* See if the RR key is owned by the same owner, if so, there
         * isn't a conflict either */
        LIST_FOREACH(by_key, i, first) {
                if (i->owner_family != owner_family ||
                    !in_addr_equal(owner_family, &i->owner_address, owner_address)) {
                        same_owner = false;
                        break;
                }
        }
        if (same_owner)
                return 0;

        /* See if there's the exact same RR in the cache. If yes, then
         * there's no conflict. */
        if (dns_cache_get(cache, rr))
                return 0;

        /* There's a conflict */
        return 1;
}

int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
        unsigned ancount = 0;
        DnsCacheItem *i;
        int r;

        assert(cache);
        assert(p);

        HASHMAP_FOREACH(i, cache->by_key) {
                DnsCacheItem *j;

                LIST_FOREACH(by_key, j, i) {
                        if (!j->rr)
                                continue;

                        if (!j->shared_owner)
                                continue;

                        r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
                        if (r == -EMSGSIZE && p->protocol == DNS_PROTOCOL_MDNS) {
                                /* For mDNS, if we're unable to stuff all known answers into the given packet,
                                 * allocate a new one, push the RR into that one and link it to the current one.
                                 */

                                DNS_PACKET_HEADER(p)->ancount = htobe16(ancount);
                                ancount = 0;

                                r = dns_packet_new_query(&p->more, p->protocol, 0, true);
                                if (r < 0)
                                        return r;

                                /* continue with new packet */
                                p = p->more;
                                r = dns_packet_append_rr(p, j->rr, 0, NULL, NULL);
                        }

                        if (r < 0)
                                return r;

                        ancount++;
                }
        }

        DNS_PACKET_HEADER(p)->ancount = htobe16(ancount);

        return 0;
}

void dns_cache_dump(DnsCache *cache, FILE *f) {
        DnsCacheItem *i;

        if (!cache)
                return;

        if (!f)
                f = stdout;

        HASHMAP_FOREACH(i, cache->by_key) {
                DnsCacheItem *j;

                LIST_FOREACH(by_key, j, i) {

                        fputc('\t', f);

                        if (j->rr) {
                                const char *t;
                                t = dns_resource_record_to_string(j->rr);
                                if (!t) {
                                        log_oom();
                                        continue;
                                }

                                fputs(t, f);
                                fputc('\n', f);
                        } else {
                                char key_str[DNS_RESOURCE_KEY_STRING_MAX];

                                fputs(dns_resource_key_to_string(j->key, key_str, sizeof key_str), f);
                                fputs(" -- ", f);
                                fputs(dns_cache_item_type_to_string(j), f);
                                fputc('\n', f);
                        }
                }
        }
}

bool dns_cache_is_empty(DnsCache *cache) {
        if (!cache)
                return true;

        return hashmap_isempty(cache->by_key);
}

unsigned dns_cache_size(DnsCache *cache) {
        if (!cache)
                return 0;

        return hashmap_size(cache->by_key);
}
