From: Marek Vavrusa Date: Tue, 21 Jun 2016 07:02:07 +0000 (-0700) Subject: lib/pktcache: stricter using TTL for pktcache X-Git-Tag: v1.1.0~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=86f75f066fc11d07aba2c804d277dd2a9def31c7;p=thirdparty%2Fknot-resolver.git lib/pktcache: stricter using TTL for pktcache * SOA MINTTL always preferred for negative answers * only SOA used for negative answers refs #75 --- diff --git a/lib/layer/pktcache.c b/lib/layer/pktcache.c index b16b8f0df..95fcff6c7 100644 --- a/lib/layer/pktcache.c +++ b/lib/layer/pktcache.c @@ -18,6 +18,7 @@ #include #include +#include #include "lib/layer/iterate.h" #include "lib/cache.h" #include "lib/module.h" @@ -130,23 +131,31 @@ static int pktcache_peek(knot_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; } -static uint32_t packet_ttl(knot_pkt_t *pkt) +static uint32_t packet_ttl(knot_pkt_t *pkt, bool is_negative) { bool has_ttl = false; uint32_t ttl = UINT32_MAX; - /* Get minimum entry TTL in the packet */ + /* 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); - /* Skip OPT and TSIG */ - if (rr->type == KNOT_RRTYPE_OPT || rr->type == KNOT_RRTYPE_TSIG) { - continue; + if (is_negative) { + /* Use SOA minimum TTL for negative answers. */ + if (rr->type == KNOT_RRTYPE_SOA) { + return limit_ttl(MIN(knot_rrset_ttl(rr), knot_soa_minimum(&rr->rrs))); + } else { + continue; /* Use SOA only for negative answers. */ + } + } + if (knot_rrtype_is_metatype(rr->type)) { + continue; /* Skip metatypes. */ } + /* Find minimum TTL in the record set */ knot_rdata_t *rd = rr->rrs.data; for (uint16_t j = 0; j < rr->rrs.rr_count; ++j) { if (knot_rdata_ttl(rd) < ttl) { - ttl = knot_rdata_ttl(rd); + ttl = limit_ttl(knot_rdata_ttl(rd)); has_ttl = true; } rd = kr_rdataset_next(rd); @@ -173,16 +182,14 @@ static int pktcache_stash(knot_layer_t *ctx, knot_pkt_t *pkt) if (!knot_wire_get_aa(pkt->wire) || knot_pkt_qclass(pkt) != KNOT_CLASS_IN) { return ctx->state; } - /* Cache only NODATA/NXDOMAIN or metatype/RRSIG or - * wildcard expanded answers. */ + /* Cache only NODATA/NXDOMAIN or metatype/RRSIG or wildcard expanded answers. */ const uint16_t qtype = knot_pkt_qtype(pkt); const bool is_eligible = (knot_rrtype_is_metatype(qtype) || qtype == KNOT_RRTYPE_RRSIG); - int pkt_class = kr_response_classify(pkt); - if (!(is_eligible || (pkt_class & (PKT_NODATA|PKT_NXDOMAIN)) || - (qry->flags & QUERY_DNSSEC_WEXPAND))) { + const bool is_negative = kr_response_classify(pkt) & (PKT_NODATA|PKT_NXDOMAIN); + if (!(is_eligible || is_negative || (qry->flags & QUERY_DNSSEC_WEXPAND))) { return ctx->state; } - uint32_t ttl = packet_ttl(pkt); + uint32_t ttl = packet_ttl(pkt, is_negative); if (ttl == 0) { return ctx->state; /* No useable TTL, can't cache this. */ }