From: Marek VavruĊĦa Date: Tue, 13 Oct 2015 17:02:21 +0000 (+0200) Subject: lib: new state 'YIELD', layers can interrupt processing with it X-Git-Tag: v1.0.0-beta2~86 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe63ea5b29b72d0b9a34311c324d040560b202bb;p=thirdparty%2Fknot-resolver.git 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 --- diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index 225341059..5441a49fb 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -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, diff --git a/lib/layer.h b/lib/layer.h index 827118dfe..2ad9a71da 100644 --- a/lib/layer.h +++ b/lib/layer.h @@ -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 diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index 2518e249f..df74229d8 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -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 }; diff --git a/lib/resolve.c b/lib/resolve.c index b2e3e0a1f..c4e7ec898 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -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. */