From ccf2790e9c471ea361603a6f55d4f64bf83372c8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Thu, 12 Oct 2017 18:45:37 +0200 Subject: [PATCH] . --- daemon/bindings.c | 6 ++++-- daemon/engine.c | 3 +-- lib/cache.c | 38 ++++++++++++++++++++++++-------------- lib/cache.h | 11 +++++++++++ lib/layer/cache_lmdb.c | 17 +++++++++++++++++ lib/lib.mk | 3 +-- lib/module.c | 6 ++---- lib/resolve.c | 4 ++++ 8 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 lib/layer/cache_lmdb.c diff --git a/daemon/bindings.c b/daemon/bindings.c index ebcd799fa..ce75fb276 100644 --- a/daemon/bindings.c +++ b/daemon/bindings.c @@ -708,6 +708,7 @@ static int cache_close(lua_State *L) return 1; } +#if 0 /** @internal Prefix walk. */ static int cache_prefixed(struct kr_cache *cache, const char *args, knot_db_val_t *results, int maxresults) { @@ -761,6 +762,7 @@ static int cache_remove_prefix(struct kr_cache *cache, const char *args) } return ret; } +#endif /** Prune expired/invalid records. */ static int cache_prune(lua_State *L) @@ -810,7 +812,7 @@ static int cache_clear(lua_State *L) /* Clear a sub-tree in cache. */ if (args && strlen(args) > 0) { - int ret = cache_remove_prefix(cache, args); + int ret = kr_error(ENOSYS); // FIXME cache_remove_prefix(cache, args); if (ret < 0) { format_error(L, kr_strerror(ret)); lua_error(L); @@ -892,7 +894,7 @@ static int cache_get(lua_State *L) const char *args = lua_tostring(L, 1); /* Retrieve set of keys */ static knot_db_val_t result_set[100]; - int ret = cache_prefixed(cache, args, result_set, 100); + int ret = kr_error(ENOSYS); // FIXME cache_prefixed(cache, args, result_set, 100); if (ret < 0) { format_error(L, kr_strerror(ret)); lua_error(L); diff --git a/daemon/engine.c b/daemon/engine.c index 81c44f7f1..2c2e00796 100644 --- a/daemon/engine.c +++ b/daemon/engine.c @@ -599,8 +599,7 @@ static int init_resolver(struct engine *engine) /* Load basic modules */ engine_register(engine, "iterate", NULL, NULL); engine_register(engine, "validate", NULL, NULL); - engine_register(engine, "rrcache", NULL, NULL); - engine_register(engine, "pktcache", NULL, NULL); + engine_register(engine, "cache_lmdb", NULL, NULL); return array_push(engine->backends, kr_cdb_lmdb()); } diff --git a/lib/cache.c b/lib/cache.c index 3fb50b573..c8862df4c 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -36,7 +36,7 @@ #define VERBOSE_MSG(qry, fmt...) QRVERBOSE((qry), "cach", fmt) /* Cache version */ -#define KEY_VERSION "V\x04" +static const uint16_t CACHE_VERSION = 1; /* Key size */ #define KEY_HSIZE (sizeof(uint8_t) + sizeof(uint16_t)) #define KEY_SIZE (KEY_HSIZE + KNOT_DNAME_MAXLEN) @@ -46,7 +46,7 @@ #define cache_op(cache, op, ...) (cache)->api->op((cache)->db, ## __VA_ARGS__) /** @internal Removes all records from cache. */ -static inline int cache_purge(struct kr_cache *cache) +static inline int cache_clear(struct kr_cache *cache) { cache->stats.delete += 1; return cache_op(cache, clear); @@ -56,24 +56,25 @@ static inline int cache_purge(struct kr_cache *cache) static int assert_right_version(struct kr_cache *cache) { /* Check cache ABI version */ - knot_db_val_t key = { KEY_VERSION, 2 }; - knot_db_val_t val = { KEY_VERSION, 2 }; + uint8_t key_str[] = "\x00\x00V"; /* CACHE_KEY */ + knot_db_val_t key = { .data = key_str, .len = sizeof(key) }; + knot_db_val_t val = { }; int ret = cache_op(cache, read, &key, &val, 1); - if (ret == 0) { + if (ret == 0 && val.len == sizeof(CACHE_VERSION) + && memcmp(val.data, &CACHE_VERSION, sizeof(CACHE_VERSION)) == 0) { ret = kr_error(EEXIST); } else { /* Version doesn't match. Recreate cache and write version key. */ ret = cache_op(cache, count); if (ret != 0) { /* Non-empty cache, purge it. */ kr_log_info("[cache] incompatible cache database detected, purging\n"); - ret = cache_purge(cache); + ret = cache_clear(cache); } /* Either purged or empty. */ if (ret == 0) { /* Key/Val is invalidated by cache purge, recreate it */ - key.data = KEY_VERSION; - key.len = 2; - val = key; + val.data = /*const-cast*/(void *)&CACHE_VERSION; + val.len = sizeof(CACHE_VERSION); ret = cache_op(cache, write, &key, &val, 1); } } @@ -275,7 +276,7 @@ int kr_cache_clear(struct kr_cache *cache) if (!cache_isvalid(cache)) { return kr_error(EINVAL); } - int ret = cache_purge(cache); + int ret = cache_clear(cache); if (ret == 0) { ret = assert_right_version(cache); } @@ -482,6 +483,7 @@ int kr_cache_insert_rrsig(struct kr_cache *cache, const knot_rrset_t *rr, uint8_ } #include "lib/dnssec/ta.h" +#include "lib/layer/iterate.h" #include "lib/resolve.h" #include "lib/rplan.h" @@ -701,7 +703,8 @@ int pkt_append(knot_pkt_t *pkt, const knot_rrset_t *rrset, uint8_t rank) -/** TODO */ +/** TODO + * CACHE_KEY */ static knot_db_val_t key_exact_type(struct key *k, uint16_t ktype) { k->buf[k->name_len + 1] = 0; /* make sure different names can never match */ @@ -732,7 +735,7 @@ static bool is_expiring(uint32_t orig_ttl, uint32_t new_ttl) /** function for .produce phase */ -int read_lmdb(kr_layer_t *ctx, knot_pkt_t *pkt) +int cache_lmdb_peek(kr_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *req = ctx->req; struct kr_query *qry = req->current_query; @@ -746,7 +749,7 @@ int read_lmdb(kr_layer_t *ctx, knot_pkt_t *pkt) struct key k_storage, *k = &k_storage; int ret = knot_dname_lf(k->buf, qry->sname, NULL); if (ret) { - return kr_error(ret); + return KR_STATE_FAIL; } k->name_len = k->buf[0]; @@ -787,8 +790,11 @@ int read_lmdb(kr_layer_t *ctx, knot_pkt_t *pkt) const struct entry_h *eh = closest_NS(ctx, k); if (!eh) { /* fall back to root hints? */ ret = kr_zonecut_set_sbelt(req->ctx, &qry->zone_cut); - if (ret) return kr_error(ret); + if (ret) return KR_STATE_FAIL; assert(!qry->zone_cut.parent); + + //VERBOSE_MSG(qry, "=> using root hints\n"); + //qry->flags.AWAIT_CUT = false; return kr_ok(); } switch (k->type) { @@ -804,6 +810,9 @@ int read_lmdb(kr_layer_t *ctx, knot_pkt_t *pkt) * and that's the only place to start - we may either find * a negative proof or we may query upstream from that point. */ kr_zonecut_set(&qry->zone_cut, k->dname); + ret = kr_make_query(qry, pkt); // FIXME: probably not yet - qname minimization + if (ret) return KR_STATE_FAIL; + /* Note: up to here we can run on any cache backend, * without touching the code. */ @@ -999,6 +1008,7 @@ static const struct entry_h *closest_NS(kr_layer_t *ctx, struct key *k) struct kr_query *qry = req->current_query; struct kr_cache *cache = &req->ctx->cache; + // FIXME: DS is parent-side record bool exact_match = true; // LATER(optim): if stype is NS, we check the same value again do { diff --git a/lib/cache.h b/lib/cache.h index 3c7ed74f0..cc9498dd5 100644 --- a/lib/cache.h +++ b/lib/cache.h @@ -83,6 +83,12 @@ struct kr_cache uint32_t ttl_min, ttl_max; /**< Maximum TTL of inserted entries */ }; + + +#include "lib/module.h" +int cache_lmdb_peek(kr_layer_t *ctx, knot_pkt_t *pkt); + + /** * Open/create cache with provided storage options. * @param cache cache structure to be initialized @@ -114,6 +120,7 @@ static inline bool kr_cache_is_open(struct kr_cache *cache) return cache->db != NULL; } +#if 0 /** * Peek the cache for asset (name, type, tag) * @note The 'drift' is the time passed between the inception time and now (in seconds). @@ -156,6 +163,7 @@ int kr_cache_insert(struct kr_cache *cache, uint8_t tag, const knot_dname_t *nam KR_EXPORT int kr_cache_remove(struct kr_cache *cache, uint8_t tag, const knot_dname_t *name, uint16_t type); +#endif /** * Clear all items from the cache. * @param cache cache structure @@ -163,6 +171,7 @@ int kr_cache_remove(struct kr_cache *cache, uint8_t tag, const knot_dname_t *nam */ KR_EXPORT int kr_cache_clear(struct kr_cache *cache); +#if 0 /** * Prefix scan on cached items. @@ -251,3 +260,5 @@ int kr_cache_peek_rrsig(struct kr_cache *cache, knot_rrset_t *rr, uint8_t *rank, */ KR_EXPORT int kr_cache_insert_rrsig(struct kr_cache *cache, const knot_rrset_t *rr, uint8_t rank, uint8_t flags, uint32_t timestamp); + +#endif diff --git a/lib/layer/cache_lmdb.c b/lib/layer/cache_lmdb.c new file mode 100644 index 000000000..75e6f7b5d --- /dev/null +++ b/lib/layer/cache_lmdb.c @@ -0,0 +1,17 @@ + +#include "lib/module.h" +#include "lib/cache.h" + + +/** Module implementation. */ +const kr_layer_api_t *cache_lmdb_layer(struct kr_module *module) +{ + static const kr_layer_api_t _layer = { + .produce = &cache_lmdb_peek, + //.consume = &cache_stash + }; + + return &_layer; +} + +KR_MODULE_EXPORT(cache_lmdb) diff --git a/lib/lib.mk b/lib/lib.mk index 98b2a4257..0cd9f6c00 100644 --- a/lib/lib.mk +++ b/lib/lib.mk @@ -3,8 +3,7 @@ libkres_SOURCES := \ lib/generic/map.c \ lib/layer/iterate.c \ lib/layer/validate.c \ - lib/layer/rrcache.c \ - lib/layer/pktcache.c \ + lib/layer/cache_lmdb.c \ lib/dnssec/nsec.c \ lib/dnssec/nsec3.c \ lib/dnssec/signature.c \ diff --git a/lib/module.c b/lib/module.c index 67b6aff15..4c3fae534 100644 --- a/lib/module.c +++ b/lib/module.c @@ -26,13 +26,11 @@ /* List of embedded modules */ const kr_layer_api_t *iterate_layer(struct kr_module *module); const kr_layer_api_t *validate_layer(struct kr_module *module); -const kr_layer_api_t *rrcache_layer(struct kr_module *module); -const kr_layer_api_t *pktcache_layer(struct kr_module *module); +const kr_layer_api_t *cache_lmdb_layer(struct kr_module *module); static const struct kr_module embedded_modules[] = { { "iterate", NULL, NULL, NULL, iterate_layer, NULL, NULL, NULL }, { "validate", NULL, NULL, NULL, validate_layer, NULL, NULL, NULL }, - { "rrcache", NULL, NULL, NULL, rrcache_layer, NULL, NULL, NULL }, - { "pktcache", NULL, NULL, NULL, pktcache_layer, NULL, NULL, NULL }, + { "cache_lmdb", NULL, NULL, NULL, cache_lmdb_layer, NULL, NULL, NULL }, }; /** Library extension. */ diff --git a/lib/resolve.c b/lib/resolve.c index 4bd652081..1a506fa79 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -165,6 +165,8 @@ static int invalidate_ns(struct kr_rplan *rplan, struct kr_query *qry) */ static void check_empty_nonterms(struct kr_query *qry, knot_pkt_t *pkt, struct kr_cache *cache, uint32_t timestamp) { + return; // FIXME cleanup, etc. +#if 0 if (qry->flags.NO_MINIMIZE) { return; } @@ -194,6 +196,7 @@ static void check_empty_nonterms(struct kr_query *qry, knot_pkt_t *pkt, struct k target = knot_wire_next_label(target, NULL); } kr_cache_sync(cache); +#endif } static int ns_fetch_cut(struct kr_query *qry, const knot_dname_t *requested_name, @@ -1239,6 +1242,7 @@ static int trust_chain_check(struct kr_request *request, struct kr_query *qry) /** @internal Check current zone cut status and credibility, spawn subrequests if needed. */ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot_pkt_t *packet) +/* TODO: using cache on this point in this way just isn't nice; remove in time */ { /* Stub mode, just forward and do not solve cut. */ if (qry->flags.STUB) { -- 2.47.2