knot_rrset_clear(dst, mm);
return kr_error(ENOMEM);
}
- /* Fixup TTL from absolute time */
+ /* Fixup TTL time drift */
rd_dst = knot_rdataset_at(&dst->rrs, dst->rrs.rr_count - 1);
knot_rdata_set_ttl(rd_dst, knot_rdata_ttl(rd) - drift);
}
#include <libknot/descriptor.h>
#include <libknot/errcode.h>
#include <libknot/rrset.h>
-#include <libknot/internal/mempool.h>
#include <libknot/rrtype/rdname.h>
+#include <ucw/config.h>
+#include <ucw/lib.h>
#include "lib/layer/iterate.h"
#include "lib/cache.h"
uint16_t rrclass, uint16_t rrtype, struct kr_query *qry)
{
/* Check if record exists in cache */
- uint32_t timestamp = qry->timestamp.tv_sec;
+ uint32_t drift = qry->timestamp.tv_sec;
knot_rrset_t cache_rr;
knot_rrset_init(&cache_rr, (knot_dname_t *)name, rrtype, rrclass);
- int ret = kr_cache_peek_rr(txn, &cache_rr, ×tamp);
+ int ret = kr_cache_peek_rr(txn, &cache_rr, &drift);
if (ret != 0) {
return ret;
}
knot_pkt_put_question(pkt, qry->sname, qry->sclass, qry->stype);
}
+ /* Mark as expiring if it has less than 5% TTL (or less than 5s) */
+ if (100 * (drift + 5) > 95 * knot_rrset_ttl(&cache_rr)) {
+ qry->flags |= QUERY_EXPIRING;
+ }
+
/* Update packet answer */
knot_rrset_t rr_copy;
- ret = kr_cache_materialize(&rr_copy, &cache_rr, timestamp, &pkt->mm);
+ ret = kr_cache_materialize(&rr_copy, &cache_rr, drift, &pkt->mm);
if (ret == 0) {
ret = knot_pkt_put(pkt, KNOT_COMPR_HINT_QNAME, &rr_copy, KNOT_PF_FREE);
if (ret != 0) {
X(AWAIT_IPV6 , 1 << 5) /**< Query is waiting for AAAA address. */ \
X(AWAIT_CUT , 1 << 6) /**< Query is waiting for zone cut lookup */ \
X(SAFEMODE , 1 << 7) /**< Don't use fancy stuff (EDNS...) */ \
- X(CACHED , 1 << 8) /**< Query response is cached. */
+ X(CACHED , 1 << 8) /**< Query response is cached. */ \
+ X(EXPIRING , 1 << 9) /**< Query response is cached, but expiring. */
/** Query flags */
enum kr_query_flag {