lua_error(L);
}
uint8_t dname[KNOT_DNAME_MAXLEN];
- knot_dname_from_str(dname, lua_tostring(L, 1), sizeof(dname));
+ if (!knot_dname_from_str(dname, lua_tostring(L, 1), sizeof(dname))) {
+ lua_pushstring(L, "invalid qname");
+ lua_error(L);
+ };
/* Check class and type */
uint16_t rrtype = lua_tointeger(L, 2);
if (!lua_isnumber(L, 2)) {
return kr_error(ENOENT);
}
- /* Mark as expiring if it has less than 1% TTL (or less than 5s) */
if (is_expiring(&cache_rr, drift)) {
qry->flags |= QUERY_EXPIRING;
}
* This way they would have to hit the first answer (whenever TTL expires). */
if (cached_rank >= 0) {
VERBOSE_MSG(baton->qry, "=> orig. rank: 0%0.2o\n", cached_rank);
- if (cached_rank >= rank) {
+ bool accept = rank > cached_rank;
+ /* Additionally accept equal rank if the cached RR is expiring.
+ * This is primarily for prefetching from predict module. */
+ if (rank == cached_rank) {
+ uint32_t drift = baton->timestamp;
+ knot_rrset_t cache_rr;
+ knot_rrset_init(&cache_rr, rr->owner, rr->type, rr->rclass);
+ int ret = kr_cache_peek_rr(baton->cache, &cache_rr, NULL, NULL, &drift);
+ if (ret != kr_ok() || is_expiring(&cache_rr, drift)) {
+ accept = true;
+ }
+ }
+ if (!accept) {
return kr_ok();
}
}
local deleted = 0
for key, val in pairs(predict.queue) do
local qtype, qname = key:match('(%S*)%s(.*)')
- worker.resolve(qname, kres.type[qtype], 1, kres.query.NO_CACHE)
+ worker.resolve(qname, kres.type[qtype], kres.class.IN, kres.query.NO_CACHE)
predict.queue[key] = nil
deleted = deleted + 1
if deleted >= predict.batch then