Commit fe63ea5b authored by Marek Vavruša's avatar Marek Vavruša

lib: new state 'YIELD', layers can interrupt processing with it

this is useful when you need to issue several subrequests before
continuing with the current query, resuming is not supported yet, so it
will requery after the subrequests complete
parent fc55eb69
......@@ -165,7 +165,7 @@ struct kr_query {
uint16_t type;
uint16_t class;
uint16_t id;
uint16_t flags;
uint32_t flags;
unsigned secret;
uint8_t _stub[]; /* Do not touch */
};
......@@ -353,7 +353,7 @@ local kres = {
section = ffi.new('struct pkt_section'),
rcode = ffi.new('struct pkt_rcode'),
query = ffi.new('struct query_flag'),
NOOP = 0, CONSUME = 1, PRODUCE = 2, DONE = 4, FAIL = 8,
NOOP = 0, YIELD = 0, CONSUME = 1, PRODUCE = 2, DONE = 4, FAIL = 8,
-- 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,
......
......@@ -29,4 +29,7 @@
} while (0)
#else
#define QRDEBUG(query, cls, fmt, ...)
#endif
\ No newline at end of file
#endif
/* Repurpose layer states. */
#define KNOT_STATE_YIELD KNOT_STATE_NOOP
\ No newline at end of file
......@@ -333,13 +333,12 @@ static int process_authority(knot_pkt_t *pkt, struct kr_request *req)
}
qry->zone_cut.name = knot_dname_copy(signer, &req->pool);
} /* else zone cut matches, but DS/DNSKEY doesn't => refetch. */
knot_wire_set_tc(pkt->wire);
result = KNOT_STATE_NOOP;
result = KNOT_STATE_YIELD;
}
/* CONSUME => Unhelpful referral.
* DONE => Zone cut updated.
* NOOP => Ignore this answer. */
* YIELD => Bail out. */
return result;
}
......@@ -449,7 +448,6 @@ static int resolve_error(knot_pkt_t *pkt, struct kr_request *req)
/* State-less single resolution iteration step, not needed. */
static int reset(knot_layer_t *ctx) { return KNOT_STATE_PRODUCE; }
static int finish(knot_layer_t *ctx) { return KNOT_STATE_NOOP; }
/* Set resolution context and parameters. */
static int begin(knot_layer_t *ctx, void *module_param)
......@@ -581,9 +579,6 @@ static int resolve(knot_layer_t *ctx, knot_pkt_t *pkt)
case KNOT_STATE_DONE: /* Referral */
DEBUG_MSG("<= referral response, follow\n");
break;
case KNOT_STATE_NOOP: /* Deferred, bail out. */
state = KNOT_STATE_CONSUME;
break;
default:
break;
}
......@@ -597,7 +592,6 @@ const knot_layer_api_t *iterate_layer(struct kr_module *module)
static const knot_layer_api_t _layer = {
.begin = &begin,
.reset = &reset,
.finish = &finish,
.consume = &resolve,
.produce = &prepare_query
};
......
......@@ -33,10 +33,12 @@
(req)->current_query = (qry); \
for (unsigned i = 0; i < (req)->ctx->modules->len; ++i) { \
struct kr_module *mod = (req)->ctx->modules->at[i]; \
if (mod->layer ) { \
if (mod->layer) { \
struct knot_layer layer = {.state = (req)->state, .api = mod->layer(mod), .data = (req)}; \
if (layer.api && layer.api->func) { \
(req)->state = layer.api->func(&layer, ##__VA_ARGS__); \
if ((req)->state == KNOT_STATE_YIELD) \
break; \
} \
} \
} /* Invalidate current query. */ \
......@@ -324,6 +326,7 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k
if (qname_raw && qry->secret != 0) {
randomized_qname_case(qname_raw, qry->secret);
}
request->state = KNOT_STATE_CONSUME;
ITERATE_LAYERS(request, qry, consume, packet);
}
......@@ -485,6 +488,7 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
/* Resolve current query and produce dependent or finish */
struct kr_query *qry = TAIL(rplan->pending);
request->state = KNOT_STATE_PRODUCE;
ITERATE_LAYERS(request, qry, produce, packet);
if (request->state != KNOT_STATE_FAIL && knot_wire_get_qr(packet->wire)) {
/* Produced an answer, consume it. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment