diff options
-rw-r--r-- | daemon/ffimodule.c | 12 | ||||
-rw-r--r-- | daemon/lua/kres.lua | 2 | ||||
-rw-r--r-- | lib/README.rst | 16 | ||||
-rw-r--r-- | lib/layer.h | 36 | ||||
-rw-r--r-- | lib/layer/iterate.c | 10 | ||||
-rw-r--r-- | lib/layer/pktcache.c | 10 | ||||
-rw-r--r-- | lib/layer/rrcache.c | 7 | ||||
-rw-r--r-- | lib/layer/validate.c | 2 | ||||
-rw-r--r-- | lib/module.h | 2 | ||||
-rw-r--r-- | lib/resolve.c | 22 | ||||
-rw-r--r-- | modules/cookies/cookiemonster.c | 6 | ||||
-rw-r--r-- | modules/cookies/cookiemonster.h | 16 | ||||
-rw-r--r-- | modules/hints/hints.c | 10 | ||||
-rw-r--r-- | modules/stats/stats.c | 4 |
14 files changed, 71 insertions, 84 deletions
diff --git a/daemon/ffimodule.c b/daemon/ffimodule.c index 65410a36..af7e46da 100644 --- a/daemon/ffimodule.c +++ b/daemon/ffimodule.c @@ -146,23 +146,23 @@ static int l_ffi_deinit(struct kr_module *module) lua_rawgeti(L, LUA_REGISTRYINDEX, cb_slot[SLOT_ ## slot]); \ lua_pushnumber(L, ctx->state) -static int l_ffi_layer_begin(kr_layer_t *ctx, void *module_param) +static int l_ffi_layer_begin(kr_layer_t *ctx) { LAYER_FFI_CALL(ctx, begin); - lua_pushlightuserdata(L, ctx->data); + lua_pushlightuserdata(L, ctx->req); return l_ffi_call(L, 2); } static int l_ffi_layer_reset(kr_layer_t *ctx) { LAYER_FFI_CALL(ctx, reset); - lua_pushlightuserdata(L, ctx->data); + lua_pushlightuserdata(L, ctx->req); return l_ffi_call(L, 2); } static int l_ffi_layer_finish(kr_layer_t *ctx) { - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; LAYER_FFI_CALL(ctx, finish); lua_pushlightuserdata(L, req); lua_pushlightuserdata(L, req->answer); @@ -175,7 +175,7 @@ static int l_ffi_layer_consume(kr_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; /* Already failed, skip */ } LAYER_FFI_CALL(ctx, consume); - lua_pushlightuserdata(L, ctx->data); + lua_pushlightuserdata(L, ctx->req); lua_pushlightuserdata(L, pkt); return l_ffi_call(L, 3); } @@ -186,7 +186,7 @@ static int l_ffi_layer_produce(kr_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; /* Already failed or done, skip */ } LAYER_FFI_CALL(ctx, produce); - lua_pushlightuserdata(L, ctx->data); + lua_pushlightuserdata(L, ctx->req); lua_pushlightuserdata(L, pkt); return l_ffi_call(L, 3); } diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index 96a34649..4a214e9f 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -489,7 +489,7 @@ local kres = { section = ffi.new('struct pkt_section'), rcode = ffi.new('struct pkt_rcode'), query = query_flag, - NOOP = 0, YIELD = 0, CONSUME = 1, PRODUCE = 2, DONE = 4, FAIL = 8, + CONSUME = 1, PRODUCE = 2, DONE = 4, FAIL = 8, YIELD = 16, -- Metatypes pkt_t = function (udata) return ffi.cast('knot_pkt_t *', udata) end, request_t = function (udata) return ffi.cast('struct kr_request *', udata) end, diff --git a/lib/README.rst b/lib/README.rst index d82b3066..198a667c 100644 --- a/lib/README.rst +++ b/lib/README.rst @@ -94,8 +94,8 @@ This structure contains pointers to resolution context, resolution plan and also int consume(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *request = ctx->data; - struct kr_query *query = request->current_query; + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; } This is only passive processing of the incoming answer. If you want to change the course of resolution, say satisfy a query from a local cache before the library issues a query to the nameserver, you can use states (see the :ref:`Static hints <mod-hints>` for example). @@ -104,14 +104,14 @@ This is only passive processing of the incoming answer. If you want to change th int produce(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *request = ctx->data; - struct kr_query *cur = request->current_query; + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; /* Query can be satisfied locally. */ - if (can_satisfy(cur)) { + if (can_satisfy(qry)) { /* This flag makes the resolver move the query * to the "resolved" list. */ - cur->flags |= QUERY_RESOLVED; + qry->flags |= QUERY_RESOLVED; return KR_STATE_DONE; } @@ -125,8 +125,8 @@ It is possible to not only act during the query resolution, but also to view the int finish(kr_layer_t *ctx) { - struct kr_request *request = ctx->data; - struct kr_rplan *rplan = request->rplan; + struct kr_request *req = ctx->req; + struct kr_rplan *rplan = req->rplan; /* Print the query sequence with start time. */ char qname_str[KNOT_DNAME_MAXLEN]; diff --git a/lib/layer.h b/lib/layer.h index 95892bd5..a4725092 100644 --- a/lib/layer.h +++ b/lib/layer.h @@ -30,37 +30,49 @@ #define QRDEBUG(query, cls, fmt, ...) #endif -/*! Layer processing states. +/** Layer processing states. Only one value at a time (but see TODO). + * * Each state represents the state machine transition, * and determines readiness for the next action. + * See struct kr_layer_api for the actions. + * + * TODO: the cookie module sometimes sets (_FAIL | _DONE) on purpose (!) */ enum kr_layer_state { - KR_STATE_NOOP = 0, /*!< N/A */ KR_STATE_CONSUME = 1 << 0, /*!< Consume data. */ KR_STATE_PRODUCE = 1 << 1, /*!< Produce data. */ - KR_STATE_DONE = 1 << 2, /*!< Finished. */ - KR_STATE_FAIL = 1 << 3 /*!< Error. */ + KR_STATE_DONE = 1 << 2, /*!< Finished successfully. */ + KR_STATE_FAIL = 1 << 3, /*!< Error. */ + KR_STATE_YIELD = 1 << 4, /*!< Paused, waiting for a sub-query. */ }; /* Forward declarations. */ struct kr_layer_api; -/*! \brief Packet processing context. */ +/** Packet processing context. */ typedef struct kr_layer { - knot_mm_t *mm; /* Processing memory context. */ - uint16_t state; /* Bitmap of enum kr_layer_state. */ - void *data; /* Module specific. */ + int state; /*!< The current state; bitmap of enum kr_layer_state. */ + struct kr_request *req; /*!< The corresponding request. */ const struct kr_layer_api *api; } kr_layer_t; -/*! \brief Packet processing module API. */ +/** Packet processing module API. All functions return the new kr_layer_state. */ struct kr_layer_api { - int (*begin)(kr_layer_t *ctx, void *module_param); + /** Start of processing the DNS request. */ + int (*begin)(kr_layer_t *ctx); + int (*reset)(kr_layer_t *ctx); + + /** Paired to begin, called both on successes and failures. */ int (*finish)(kr_layer_t *ctx); + + /** Processing an answer from upstream or the answer to the request. */ int (*consume)(kr_layer_t *ctx, knot_pkt_t *pkt); + + /** Produce either an answer to the request or a query for upstream (or fail). */ int (*produce)(kr_layer_t *ctx, knot_pkt_t *pkt); - int (*fail)(kr_layer_t *ctx, knot_pkt_t *pkt); + + /** The module can store anything in here. */ void *data; }; @@ -74,5 +86,3 @@ struct kr_layer_pickle { unsigned state; }; -/* Repurpose layer states. */ -#define KR_STATE_YIELD KR_STATE_NOOP diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index 37759041..c9089467 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -507,7 +507,7 @@ static int resolve_error(knot_pkt_t *pkt, struct kr_request *req) static int reset(kr_layer_t *ctx) { return KR_STATE_PRODUCE; } /* Set resolution context and parameters. */ -static int begin(kr_layer_t *ctx, void *module_param) +static int begin(kr_layer_t *ctx) { if (ctx->state & (KR_STATE_DONE|KR_STATE_FAIL)) { return ctx->state; @@ -519,8 +519,7 @@ static int begin(kr_layer_t *ctx, void *module_param) * Server cookie queries must be handled by the cookie module/layer * before this layer. */ - const struct kr_request *req = ctx->data; - const knot_pkt_t *pkt = req->qsource.packet; + const knot_pkt_t *pkt = ctx->req->qsource.packet; if (!pkt || knot_wire_get_qdcount(pkt->wire) == 0) { return KR_STATE_FAIL; } @@ -550,8 +549,7 @@ int kr_make_query(struct kr_query *query, knot_pkt_t *pkt) static int prepare_query(kr_layer_t *ctx, knot_pkt_t *pkt) { assert(pkt && ctx); - struct kr_request *req = ctx->data; - struct kr_query *query = req->current_query; + struct kr_query *query = ctx->req->current_query; if (!query || ctx->state & (KR_STATE_DONE|KR_STATE_FAIL)) { return ctx->state; } @@ -587,7 +585,7 @@ static int resolve_badmsg(knot_pkt_t *pkt, struct kr_request *req, struct kr_que static int resolve(kr_layer_t *ctx, knot_pkt_t *pkt) { assert(pkt && ctx); - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; struct kr_query *query = req->current_query; if (!query || (query->flags & (QUERY_RESOLVED|QUERY_BADCOOKIE_AGAIN))) { return ctx->state; diff --git a/lib/layer/pktcache.c b/lib/layer/pktcache.c index 0d0087ec..747d2e4d 100644 --- a/lib/layer/pktcache.c +++ b/lib/layer/pktcache.c @@ -102,8 +102,7 @@ static int loot_pktcache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_quer static int pktcache_peek(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; - struct kr_query *qry = req->current_query; + struct kr_query *qry = ctx->req->current_query; if (ctx->state & (KR_STATE_FAIL|KR_STATE_DONE) || (qry->flags & QUERY_NO_CACHE)) { return ctx->state; /* Already resolved/failed */ } @@ -116,7 +115,7 @@ static int pktcache_peek(kr_layer_t *ctx, knot_pkt_t *pkt) /* Fetch either answer to original or minimized query */ uint8_t flags = 0; - struct kr_cache *cache = &req->ctx->cache; + struct kr_cache *cache = &ctx->req->ctx->cache; int ret = loot_pktcache(cache, pkt, qry, &flags); if (ret == 0) { DEBUG_MSG(qry, "=> satisfied from cache\n"); @@ -172,8 +171,7 @@ static uint32_t packet_ttl(knot_pkt_t *pkt, bool is_negative) static int pktcache_stash(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; - struct kr_query *qry = req->current_query; + struct kr_query *qry = ctx->req->current_query; /* Cache only answers that make query resolved (i.e. authoritative) * that didn't fail during processing and are negative. */ if (qry->flags & QUERY_CACHED || ctx->state & KR_STATE_FAIL) { @@ -220,7 +218,7 @@ static int pktcache_stash(kr_layer_t *ctx, knot_pkt_t *pkt) } /* Check if we can replace (allow current or better rank, SECURE is always accepted). */ - struct kr_cache *cache = &req->ctx->cache; + struct kr_cache *cache = &ctx->req->ctx->cache; if (header.rank < KR_RANK_SECURE) { int cached_rank = kr_cache_peek_rank(cache, KR_CACHE_PKT, qname, qtype, header.timestamp); if (cached_rank > header.rank) { diff --git a/lib/layer/rrcache.c b/lib/layer/rrcache.c index 315337b3..d30c79e6 100644 --- a/lib/layer/rrcache.c +++ b/lib/layer/rrcache.c @@ -112,8 +112,7 @@ static int loot_rrcache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_query static int rrcache_peek(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; - struct kr_query *qry = req->current_query; + struct kr_query *qry = ctx->req->current_query; if (ctx->state & (KR_STATE_FAIL|KR_STATE_DONE) || (qry->flags & QUERY_NO_CACHE)) { return ctx->state; /* Already resolved/failed */ } @@ -125,7 +124,7 @@ static int rrcache_peek(kr_layer_t *ctx, knot_pkt_t *pkt) * it may either be a CNAME chain or direct answer. * Only one step of the chain is resolved at a time. */ - struct kr_cache *cache = &req->ctx->cache; + struct kr_cache *cache = &ctx->req->ctx->cache; int ret = -1; if (qry->stype != KNOT_RRTYPE_ANY) { ret = loot_rrcache(cache, pkt, qry, qry->stype, (qry->flags & QUERY_DNSSEC_WANT)); @@ -322,7 +321,7 @@ static int stash_answer(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, kno static int rrcache_stash(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; struct kr_query *qry = req->current_query; if (!qry || ctx->state & KR_STATE_FAIL) { return ctx->state; diff --git a/lib/layer/validate.c b/lib/layer/validate.c index 4174f49e..7a5887fb 100644 --- a/lib/layer/validate.c +++ b/lib/layer/validate.c @@ -372,7 +372,7 @@ static const knot_dname_t *signature_authority(knot_pkt_t *pkt) static int validate(kr_layer_t *ctx, knot_pkt_t *pkt) { int ret = 0; - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; struct kr_query *qry = req->current_query; /* Ignore faulty or unprocessed responses. */ if (ctx->state & (KR_STATE_FAIL|KR_STATE_CONSUME)) { diff --git a/lib/module.h b/lib/module.h index 70279e24..0a06bf86 100644 --- a/lib/module.h +++ b/lib/module.h @@ -37,7 +37,7 @@ typedef int (module_config_cb)(struct kr_module *, const char *); typedef const kr_layer_api_t* (module_layer_cb)(struct kr_module *); typedef struct kr_prop *(module_prop_cb)(void); typedef char *(kr_prop_cb)(void *, struct kr_module *, const char *); -#define KR_MODULE_API ((uint32_t) 0x20150402) +#define KR_MODULE_API ((uint32_t) 0x20161108) /* @endcond */ /** diff --git a/lib/resolve.c b/lib/resolve.c index 369236d9..7b115acd 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -43,7 +43,7 @@ */ static int consume_yield(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; knot_pkt_t *pkt_copy = knot_pkt_new(NULL, pkt->size, &req->pool); struct kr_layer_pickle *pickle = mm_alloc(&req->pool, sizeof(*pickle)); if (pickle && pkt_copy && knot_pkt_copy(pkt_copy, pkt) == 0) { @@ -57,28 +57,28 @@ static int consume_yield(kr_layer_t *ctx, knot_pkt_t *pkt) } return kr_error(ENOMEM); } -static int begin_yield(kr_layer_t *ctx, void *module) { return kr_ok(); } +static int begin_yield(kr_layer_t *ctx) { return kr_ok(); } static int reset_yield(kr_layer_t *ctx) { return kr_ok(); } static int finish_yield(kr_layer_t *ctx) { return kr_ok(); } static int produce_yield(kr_layer_t *ctx, knot_pkt_t *pkt) { return kr_ok(); } /** @internal Macro for iterating module layers. */ -#define RESUME_LAYERS(from, req, qry, func, ...) \ - (req)->current_query = (qry); \ - for (size_t i = (from); i < (req)->ctx->modules->len; ++i) { \ - struct kr_module *mod = (req)->ctx->modules->at[i]; \ +#define RESUME_LAYERS(from, r, qry, func, ...) \ + (r)->current_query = (qry); \ + for (size_t i = (from); i < (r)->ctx->modules->len; ++i) { \ + struct kr_module *mod = (r)->ctx->modules->at[i]; \ if (mod->layer) { \ - struct kr_layer layer = {.state = (req)->state, .api = mod->layer(mod), .data = (req)}; \ + struct kr_layer layer = {.state = (r)->state, .api = mod->layer(mod), .req = (r)}; \ if (layer.api && layer.api->func) { \ - (req)->state = layer.api->func(&layer, ##__VA_ARGS__); \ - if ((req)->state == KR_STATE_YIELD) { \ + (r)->state = layer.api->func(&layer, ##__VA_ARGS__); \ + if ((r)->state == KR_STATE_YIELD) { \ func ## _yield(&layer, ##__VA_ARGS__); \ break; \ } \ } \ } \ } /* Invalidate current query. */ \ - (req)->current_query = NULL + (r)->current_query = NULL /** @internal Macro for starting module iteration. */ #define ITERATE_LAYERS(req, qry, func, ...) RESUME_LAYERS(0, req, qry, func, ##__VA_ARGS__) @@ -480,7 +480,7 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet) /* Expect answer, pop if satisfied immediately */ request->qsource.packet = packet; - ITERATE_LAYERS(request, qry, begin, request); + ITERATE_LAYERS(request, qry, begin); request->qsource.packet = NULL; if (request->state == KR_STATE_DONE) { kr_rplan_pop(rplan, qry); diff --git a/modules/cookies/cookiemonster.c b/modules/cookies/cookiemonster.c index 414e1b7b..dbeb64c6 100644 --- a/modules/cookies/cookiemonster.c +++ b/modules/cookies/cookiemonster.c @@ -218,7 +218,7 @@ static bool check_cookie_content_and_cache(const struct kr_cookie_settings *clnt /** Process incoming response. */ int check_response(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; struct kr_query *qry = req->current_query; struct kr_cookie_ctx *cookie_ctx = &req->ctx->cookie_ctx; @@ -347,9 +347,9 @@ static int invalid_sc_status(int state, bool sc_present, bool ignore_badcookie, return state; } -int check_request(kr_layer_t *ctx, void *module_param) +int check_request(kr_layer_t *ctx) { - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; struct kr_cookie_settings *srvr_sett = &req->ctx->cookie_ctx.srvr; knot_pkt_t *answer = req->answer; diff --git a/modules/cookies/cookiemonster.h b/modules/cookies/cookiemonster.h index 480de903..62574c29 100644 --- a/modules/cookies/cookiemonster.h +++ b/modules/cookies/cookiemonster.h @@ -20,18 +20,8 @@ #include "lib/layer.h" -/** - * @brief Checks cookies of inbound requests. - * @param ctx layer context - * @param module_param module parameters - * @return layer state - */ -int check_request(kr_layer_t *ctx, void *module_param); +/** Checks cookies of inbound requests. It's for kr_layer_api_t::begin. */ +int check_request(kr_layer_t *ctx); -/** - * @brief Checks cookies of received responses. - * @param ctx layer context - * @param pkt response packet - * @return layer state - */ +/** Checks cookies of received responses. It's for kr_layer_api_t::consume. */ int check_response(kr_layer_t *ctx, knot_pkt_t *pkt); diff --git a/modules/hints/hints.c b/modules/hints/hints.c index 0cb936cd..f7348680 100644 --- a/modules/hints/hints.c +++ b/modules/hints/hints.c @@ -48,12 +48,6 @@ struct rev_search_baton { size_t addr_len; }; -static int begin(kr_layer_t *ctx, void *module_param) -{ - ctx->data = module_param; - return ctx->state; -} - static int put_answer(knot_pkt_t *pkt, knot_rrset_t *rr) { int ret = 0; @@ -181,8 +175,7 @@ static int satisfy_forward(struct kr_zonecut *hints, knot_pkt_t *pkt, struct kr_ static int query(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; - struct kr_query *qry = req->current_query; + struct kr_query *qry = ctx->req->current_query; if (!qry || ctx->state & (KR_STATE_FAIL)) { return ctx->state; } @@ -442,7 +435,6 @@ KR_EXPORT const kr_layer_api_t *hints_layer(struct kr_module *module) { static kr_layer_api_t _layer = { - .begin = &begin, .produce = &query, }; /* Store module reference */ diff --git a/modules/stats/stats.c b/modules/stats/stats.c index 55036e06..c0ede0b4 100644 --- a/modules/stats/stats.c +++ b/modules/stats/stats.c @@ -156,7 +156,7 @@ static void collect_sample(struct stat_data *data, struct kr_rplan *rplan, knot_ static int collect_rtt(kr_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *req = ctx->data; + struct kr_request *req = ctx->req; struct kr_query *qry = req->current_query; if (qry->flags & QUERY_CACHED || !req->upstream.addr) { return ctx->state; @@ -185,7 +185,7 @@ static int collect_rtt(kr_layer_t *ctx, knot_pkt_t *pkt) static int collect(kr_layer_t *ctx) { - struct kr_request *param = ctx->data; + struct kr_request *param = ctx->req; struct kr_module *module = ctx->api->data; struct kr_rplan *rplan = ¶m->rplan; struct stat_data *data = module->data; |