From: Vladimír Čunát Date: Wed, 1 Mar 2017 16:04:25 +0000 (+0100) Subject: WIP X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbad3d20b1e47a96d0656bdd61e11a04628a4c59;p=thirdparty%2Fknot-resolver.git WIP --- diff --git a/daemon/lua/kres-gen.lua b/daemon/lua/kres-gen.lua index ff1fcfd9b..4b3221742 100644 --- a/daemon/lua/kres-gen.lua +++ b/daemon/lua/kres-gen.lua @@ -124,6 +124,19 @@ struct kr_request { int has_tls; knot_mm_t pool; }; +typedef void knot_db_t; +struct kr_cache { + knot_db_t *db; + const struct kr_cdb_api *api; + struct { + uint32_t hit; + uint32_t miss; + uint32_t insert; + uint32_t delete; + } stats; + uint32_t ttl_min; + uint32_t ttl_max; +}; struct knot_rrset { knot_dname_t *_owner; uint16_t type; @@ -160,6 +173,7 @@ struct kr_context { map_t trust_anchors; map_t negative_anchors; struct kr_zonecut root_hints; + struct kr_cache cache; char _stub[]; }; struct query_flag {static const int NO_MINIMIZE = 1; static const int NO_THROTTLE = 2; static const int NO_IPV6 = 4; static const int NO_IPV4 = 8; static const int TCP = 16; static const int RESOLVED = 32; static const int AWAIT_IPV4 = 64; static const int AWAIT_IPV6 = 128; static const int AWAIT_CUT = 256; static const int SAFEMODE = 512; static const int CACHED = 1024; static const int NO_CACHE = 2048; static const int EXPIRING = 4096; static const int ALLOW_LOCAL = 8192; static const int DNSSEC_WANT = 16384; static const int DNSSEC_BOGUS = 32768; static const int DNSSEC_INSECURE = 65536; static const int STUB = 131072; static const int ALWAYS_CUT = 262144; static const int DNSSEC_WEXPAND = 524288; static const int PERMISSIVE = 1048576; static const int STRICT = 2097152; static const int BADCOOKIE_AGAIN = 4194304; static const int CNAME = 8388608; static const int REORDER_RR = 16777216; static const int TRACE = 33554432; static const int NO_0X20 = 67108864; static const int DNSSEC_NODS = 134217728; static const int DNSSEC_OPTOUT = 268435456; static const int NONAUTH = 536870912;}; @@ -171,6 +185,8 @@ uint8_t *knot_rdata_data(const knot_rdata_t *); knot_rdata_t *knot_rdataset_at(const knot_rdataset_t *, size_t); int knot_rrset_add_rdata(knot_rrset_t *, const uint8_t *, const uint16_t, const uint32_t, knot_mm_t *); void knot_rrset_init_empty(knot_rrset_t *); +knot_rrset_t *knot_rrset_new(const knot_dname_t *, uint16_t, uint16_t, knot_mm_t *); +void knot_rrset_clear(knot_rrset_t *, knot_mm_t *); uint32_t knot_rrset_ttl(const knot_rrset_t *); int knot_rrset_txt_dump(const knot_rrset_t *, char **, size_t *, const knot_dump_style_t *); int knot_rrset_txt_dump_data(const knot_rrset_t *, const size_t, char *, const size_t, const knot_dump_style_t *); @@ -200,6 +216,7 @@ int kr_bitcmp(const char *, const char *, int); int kr_family_len(int); struct sockaddr *kr_straddr_socket(const char *, int); int kr_rrarray_add(rr_array_t *, const knot_rrset_t *, knot_mm_t *); +void kr_rrset_print(const knot_rrset_t *, const char *); knot_rrset_t *kr_ta_get(map_t *, const knot_dname_t *); int kr_ta_add(map_t *, const knot_dname_t *, uint16_t, uint32_t, const uint8_t *, uint16_t); int kr_ta_del(map_t *, const knot_dname_t *); @@ -208,4 +225,5 @@ _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_peek_rr(struct kr_cache *, knot_rrset_t *, uint8_t *, uint8_t *, uint32_t *); ]] diff --git a/daemon/lua/kres-gen.sh b/daemon/lua/kres-gen.sh index e769583b1..5b7da8312 100755 --- a/daemon/lua/kres-gen.sh +++ b/daemon/lua/kres-gen.sh @@ -41,6 +41,8 @@ typedef void (*map_free_f)(void *baton, void *ptr); kr_qarray_t struct kr_rplan struct kr_request + knot_db_t + struct kr_cache EOF genResType() { @@ -58,7 +60,7 @@ printf "\t/* beware: hidden stub */\n};\n" genResType "struct kr_query" | sed '/struct kr_layer_pickle/,$ d' printf "\t/* ^hidden stub^ */\n\tchar _stub[];\n};\n" -genResType "struct kr_context" | sed '/struct kr_cache/,$ d' +genResType "struct kr_context" | sed '/cache_rtt/,$ d' printf "\tchar _stub[];\n};\n" # Getting struct query_flag is a bit complex. @@ -79,6 +81,8 @@ genResType "enum kr_query_flag" | sed -e 's/enum kr_query_flag/struct query_flag knot_rdataset_at knot_rrset_add_rdata knot_rrset_init_empty + knot_rrset_new + knot_rrset_clear knot_rrset_ttl knot_rrset_txt_dump knot_rrset_txt_dump_data @@ -117,6 +121,7 @@ EOF kr_family_len kr_straddr_socket kr_rrarray_add + kr_rrset_print # Trust anchors kr_ta_get kr_ta_add @@ -127,6 +132,8 @@ EOF kr_dnssec_key_revoked kr_dnssec_key_tag kr_dnssec_key_match +# Cache + kr_cache_peek_rr EOF printf "]]\n" diff --git a/daemon/lua/kres.lua.in b/daemon/lua/kres.lua.in index 540c7f99f..1a5613d53 100644 --- a/daemon/lua/kres.lua.in +++ b/daemon/lua/kres.lua.in @@ -133,6 +133,7 @@ ffi.metatype( sockaddr_t, { -- Metatype for RR set. Beware, the indexing is 0-based (rdata, get, tostring). local rrset_buflen = (64 + 1) * 1024 local rrset_buf = ffi.new('char[?]', rrset_buflen) + local knot_rrset_t = ffi.typeof('knot_rrset_t') ffi.metatype( knot_rrset_t, { __index = { @@ -196,7 +197,20 @@ ffi.metatype( knot_rrset_t, { return result end end, + + tolist = function(rr) + if not rr then return {} end + assert(ffi.istype(knot_rrset_t, rr)) + local res = {} + local i = 0 + while i < #rr do + table.insert(res, rr:get(i)) + i = i + 1 + end + return res + end, }, + __len = function(rr) return rr.rrs.rr_count end, }) -- Metatype for packet @@ -337,6 +351,7 @@ local function rr2str(rr, style) return ret end + -- Module API kres = { -- Constants @@ -365,4 +380,21 @@ kres = { context = function () return ffi.cast('struct kr_context *', __engine) end, } +local function rrset_free(rrset) + if rrset then + --C.knot_rrset_clear(rrset, nil) FIXME: memory leak? + C.free(rrset) + end +end + +-- Global! +-- Get a cached RRset as knot_rrset_t, ignoring current time, its rank, etc. +cache.peek_rr = function(name, rrtype) + local rrset = ffi.gc( + C.knot_rrset_new(kres.str2dname(name), rrtype or kres.type.A, kres.class.IN, nil), + rrset_free) + local err = C.kr_cache_peek_rr(kres.context().cache, rrset, nil, nil, nil) + if err == 0 then return rrset else return nil end +end + return kres diff --git a/lib/cache.c b/lib/cache.c index c3d793d40..d0dadc047 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -188,9 +188,9 @@ int kr_cache_peek(struct kr_cache *cache, uint8_t tag, const knot_dname_t *name, return kr_error(ENOENT); } - /* Check entry lifetime */ + /* Check entry lifetime, optionally. */ *entry = found; - int ret = check_lifetime(found, timestamp); + int ret = timestamp ? check_lifetime(found, timestamp) : 0; if (ret == 0) { cache->stats.hit += 1; } else { @@ -299,7 +299,7 @@ int kr_cache_match(struct kr_cache *cache, uint8_t tag, const knot_dname_t *name int kr_cache_peek_rr(struct kr_cache *cache, knot_rrset_t *rr, uint8_t *rank, uint8_t *flags, uint32_t *timestamp) { - if (!cache_isvalid(cache) || !rr || !timestamp) { + if (!cache_isvalid(cache) || !rr) { return kr_error(EINVAL); } diff --git a/lib/cache.h b/lib/cache.h index 75d97bd35..5ce37f094 100644 --- a/lib/cache.h +++ b/lib/cache.h @@ -194,7 +194,8 @@ int kr_cache_peek_rank(struct kr_cache *cache, uint8_t tag, const knot_dname_t * * @param rr query RRSet (its rdataset may be changed depending on the result) * @param rank entry rank will be stored in this variable * @param flags entry flags - * @param timestamp current time (will be replaced with drift if successful) + * @param timestamp current time (will be replaced with drift if successful). + * Pass NULL to avoid checking the TTL. * @return 0 or an errcode */ KR_EXPORT