]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache: tweak TTL computation for packets
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 28 Feb 2022 18:10:16 +0000 (19:10 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Tue, 13 Dec 2022 09:58:33 +0000 (10:58 +0100)
When a whole packet is cached (instead of individual RRs),
let's simplify the way the packet's TTL gets computed.

The previous mechanism came from commit 5b383a2bb7,
probably a misunderstanding of:
https://datatracker.ietf.org/doc/html/rfc2308#section-5
Anyway, I see no motivation to do it, and this way we should
get rid of some weird cases where we might extend TTL of some records,
except if they were below the cache.min_ttl() setting (5s default).

daemon/http.c
daemon/lua/kres-gen-30.lua
daemon/lua/kres-gen-31.lua
daemon/lua/kres-gen-32.lua
lib/cache/entry_pkt.c
lib/cache/util.h
modules/http/http_doh.lua

index af387d818cb2027a3623f094452d1757f47a4914..ebc05f8f29a2a9d887ce9829c77d265c266e33fe 100644 (file)
@@ -876,7 +876,6 @@ static int http_write_pkt(struct http_ctx *ctx, knot_pkt_t *pkt, int32_t stream_
 {
        struct http_data *data;
        nghttp2_data_provider prov;
-       const bool is_negative = kr_response_classify(pkt) & (PKT_NODATA|PKT_NXDOMAIN);
 
        data = malloc(sizeof(struct http_data));
        if (!data)
@@ -887,7 +886,7 @@ static int http_write_pkt(struct http_ctx *ctx, knot_pkt_t *pkt, int32_t stream_
        data->pos = 0;
        data->on_write = on_write;
        data->req = req;
-       data->ttl = packet_ttl(pkt, is_negative);
+       data->ttl = packet_ttl(pkt);
 
        prov.source.ptr = data;
        prov.read_callback = read_callback;
index 76659b7f1e264df5c54f9a393253f0c3fdc11f93..4353c5ce00ad7b620a1128982194c296ac1caf1b 100644 (file)
@@ -456,7 +456,7 @@ int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset
 int kr_cache_remove(struct kr_cache *, const knot_dname_t *, uint16_t);
 int kr_cache_remove_subtree(struct kr_cache *, const knot_dname_t *, _Bool, int);
 int kr_cache_commit(struct kr_cache *);
-uint32_t packet_ttl(const knot_pkt_t *, _Bool);
+uint32_t packet_ttl(const knot_pkt_t *);
 typedef struct {
        int sock_type;
        _Bool tls;
index b009868db9f9be12438192d72e300b6e620b8ec0..a68dd653f3198b973c7df9ff1d908db29ac3bdd7 100644 (file)
@@ -456,7 +456,7 @@ int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset
 int kr_cache_remove(struct kr_cache *, const knot_dname_t *, uint16_t);
 int kr_cache_remove_subtree(struct kr_cache *, const knot_dname_t *, _Bool, int);
 int kr_cache_commit(struct kr_cache *);
-uint32_t packet_ttl(const knot_pkt_t *, _Bool);
+uint32_t packet_ttl(const knot_pkt_t *);
 typedef struct {
        int sock_type;
        _Bool tls;
index 7686419f164dea0dadd10e425b7d1d29f4613c66..222891e3fb6b7e67ab2cea01f4140f4a11e936d6 100644 (file)
@@ -457,7 +457,7 @@ int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset
 int kr_cache_remove(struct kr_cache *, const knot_dname_t *, uint16_t);
 int kr_cache_remove_subtree(struct kr_cache *, const knot_dname_t *, _Bool, int);
 int kr_cache_commit(struct kr_cache *);
-uint32_t packet_ttl(const knot_pkt_t *, _Bool);
+uint32_t packet_ttl(const knot_pkt_t *);
 typedef struct {
        int sock_type;
        _Bool tls;
index fa59380d38424f0221e2d5cbe7a9b96a1bc95fb7..778c0f4d8cd97ac2d26bb809ae62228b2fb42280 100644 (file)
 #include "lib/cache/impl.h"
 
 
-/** Compute TTL for a packet.  Generally it's minimum TTL, with extra conditions. */
+/** Compute TTL for a packet.  It's minimum TTL or zero.  (You can apply limits.) */
 KR_EXPORT
-uint32_t packet_ttl(const knot_pkt_t *pkt, bool is_negative)
+uint32_t packet_ttl(const knot_pkt_t *pkt)
 {
        bool has_ttl = false;
        uint32_t ttl = TTL_MAX_MAX;
-       /* Find minimum entry TTL in the packet or SOA minimum TTL. */
        for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) {
                const knot_pktsection_t *sec = knot_pkt_section(pkt, i);
                for (unsigned k = 0; k < sec->count; ++k) {
                        const knot_rrset_t *rr = knot_pkt_rr(sec, k);
-                       if (is_negative) {
-                               /* Use SOA minimum TTL for negative answers. */
-                               if (rr->type == KNOT_RRTYPE_SOA) {
-                                       return MIN(rr->ttl, knot_soa_minimum(rr->rrs.rdata));
-                               } else {
-                                       continue; /* Use SOA only for negative answers. */
-                               }
-                       }
-                       if (knot_rrtype_is_metatype(rr->type)) {
-                               continue; /* Skip metatypes. */
-                       }
                        ttl = MIN(ttl, rr->ttl);
                        has_ttl = true;
                }
        }
-       /* If no valid TTL present, go with zero (will get clamped to minimum). */
        return has_ttl ? ttl : 0;
 }
 
@@ -120,7 +107,7 @@ void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry,
        struct entry_h *eh = val_new_entry.data;
        memset(eh, 0, offsetof(struct entry_h, data));
        eh->time = qry->timestamp.tv_sec;
-       eh->ttl  = MAX(MIN(packet_ttl(pkt, is_negative), cache->ttl_max), cache->ttl_min);
+       eh->ttl  = MAX(MIN(packet_ttl(pkt), cache->ttl_max), cache->ttl_min);
        eh->rank = rank;
        eh->is_packet = true;
        eh->has_optout = qf->DNSSEC_OPTOUT;
index 0a2f329c8004b23b461f7337f948374538267ec6..3f818300981ab9fb29a41d9b3be190b1c709cf66 100644 (file)
@@ -1,4 +1,4 @@
 /* SPDX-License-Identifier: GPL-3.0-or-later */
 #include <libknot/packet/pkt.h>
 
-uint32_t packet_ttl(const knot_pkt_t *pkt, bool is_negative);
+uint32_t packet_ttl(const knot_pkt_t *pkt);
index 8625c12d950fcdc69dce3a016f1ba732401f322e..33815f7b19045bbf29d24a89743f79784da56ac2 100644 (file)
@@ -3,12 +3,6 @@ local basexx = require('basexx')
 local ffi = require('ffi')
 local condition = require('cqueues.condition')
 
-local function get_http_ttl(pkt)
-       local an_records = pkt:section(kres.section.ANSWER)
-       local is_negative = #an_records <= 0
-       return ffi.C.packet_ttl(pkt, is_negative)
-end
-
 -- Trace execution of DNS queries
 local function serve_doh(h, stream)
        local input
@@ -68,7 +62,7 @@ local function serve_doh(h, stream)
        local cond = condition.new()
        local waiting, done = false, false
        local finish_cb = function (answer, _)
-               output_ttl = get_http_ttl(answer)
+               output_ttl = ffi.C.packet_ttl(answer)
                -- binary output
                output = ffi.string(answer.wire, answer.size)
                if waiting then