_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);
-- 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
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
* @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
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.