diff --git a/daemon/lua/kres-gen.lua b/daemon/lua/kres-gen.lua index 20bd48d0de3f866f261cc5d4013d58559f8fff69..7d06d2003f9208aa159c0cde6724210f692d2a0b 100644 --- a/daemon/lua/kres-gen.lua +++ b/daemon/lua/kres-gen.lua @@ -322,7 +322,7 @@ _Bool kr_dnssec_key_ksk(const uint8_t *); _Bool kr_dnssec_key_revoked(const uint8_t *); int kr_dnssec_key_tag(uint16_t, const uint8_t *, size_t); int kr_dnssec_key_match(const uint8_t *, size_t, const uint8_t *, size_t); -int kr_cache_closest_apex(struct kr_cache *, const knot_dname_t *, _Bool); +int kr_cache_closest_apex(struct kr_cache *, const knot_dname_t *, _Bool, knot_dname_t **); int kr_cache_insert_rr(struct kr_cache *, const knot_rrset_t *, const knot_rrset_t *, uint8_t, uint32_t); 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); diff --git a/daemon/lua/sandbox.lua b/daemon/lua/sandbox.lua index e76bc54a4d5481ac6c6821cc03d01971d955bd27..af5b10dc4281a0a32a2ab251f85258b3cfa044b4 100644 --- a/daemon/lua/sandbox.lua +++ b/daemon/lua/sandbox.lua @@ -173,11 +173,16 @@ cache.clear = function (name, exact_name, rr_type, maxcount, callback) -- we assume they are advanced enough not to need the check. -- The point is to avoid repeating the check in each callback iteration. if callback == nil then - local apex_dist = ffi.C.kr_cache_closest_apex(cach, dname, false) - if apex_dist < 0 then error(ffi.string(ffi.C.knot_strerror(apex_dist))) end - if apex_dist > 0 then - errors.not_apex = 'Negative proofs not cleared, call clear again ' - .. tostring(apex_dist) .. ' label(s) higher.' + local names = ffi.new('knot_dname_t *[1]') -- C: dname **names + local ret = ffi.C.kr_cache_closest_apex(cach, dname, false, names) + if ret < 0 then + error(ffi.string(ffi.C.knot_strerror(ret))) end + ffi.gc(names[0], ffi.C.free) + local apex = kres.dname2str(names[0]) + if apex ~= name then + errors.not_apex = 'to clear proofs of non-existence call ' + .. 'cache.clear(\'' .. tostring(apex) ..'\')' + errors.subtree = apex end end @@ -340,7 +345,7 @@ function table_print (tt, indent, done) if c >= 0x20 and c < 0x7f then table.insert(bytes, string.char(c)) else table.insert(bytes, '\\'..tostring(c)) end - if i > 70 then table.insert(bytes, '...') break end + if i > 80 then table.insert(bytes, '...') break end end return table.concat(bytes) end diff --git a/lib/cache/api.h b/lib/cache/api.h index 9034fa182e4dd232d6ca36b669c092a1151cf945..84d0f07dbe0a0cbc5656f16f42ee09e59b590a84 100644 --- a/lib/cache/api.h +++ b/lib/cache/api.h @@ -179,7 +179,8 @@ int kr_cache_remove_subtree(struct kr_cache *cache, const knot_dname_t *name, * @note timestamp is found by a syscall, and stale-serving is not considered */ KR_EXPORT -int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS); +int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS, + knot_dname_t **apex); /** * Unpack dname and type from db key diff --git a/lib/cache/peek.c b/lib/cache/peek.c index cdb5c81c054ba2f92b090c861c3c4a55923244e5..1c8749776f0fc9bf01256621be5d58be0eb56073 100644 --- a/lib/cache/peek.c +++ b/lib/cache/peek.c @@ -553,20 +553,26 @@ static int try_wild(struct key *k, struct answer *ans, const knot_dname_t *clenc return kr_ok(); } -int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS) +int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS, + knot_dname_t ** apex) { - if (!cache || !name) { + if (!cache || !cache->db || !name || !apex || *apex) { assert(!EINVAL); return kr_error(EINVAL); } struct key k_storage, *k = &k_storage; int ret = kr_dname_lf(k->buf, name, false); - if (ret) return kr_error(ret); + if (ret) + return kr_error(ret); entry_list_t el_; k->zname = name; ret = closest_NS(cache, k, el_, NULL, true, is_DS); - if (ret && ret != -abs(ENOENT)) return ret; - return knot_dname_labels(name, NULL) - knot_dname_labels(k->zname, NULL); + if (ret && ret != -abs(ENOENT)) + return ret; + *apex = knot_dname_copy(k->zname, NULL); + if (!*apex) + return kr_error(ENOMEM); + return kr_ok(); } /** \internal for closest_NS. Check suitability of a single entry, setting k->type if OK.