summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemon/ffimodule.c12
-rw-r--r--daemon/lua/kres.lua2
-rw-r--r--lib/README.rst16
-rw-r--r--lib/layer.h36
-rw-r--r--lib/layer/iterate.c10
-rw-r--r--lib/layer/pktcache.c10
-rw-r--r--lib/layer/rrcache.c7
-rw-r--r--lib/layer/validate.c2
-rw-r--r--lib/module.h2
-rw-r--r--lib/resolve.c22
-rw-r--r--modules/cookies/cookiemonster.c6
-rw-r--r--modules/cookies/cookiemonster.h16
-rw-r--r--modules/hints/hints.c10
-rw-r--r--modules/stats/stats.c4
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 = &param->rplan;
struct stat_data *data = module->data;