]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib: new state 'YIELD', layers can interrupt processing with it
authorMarek Vavruša <marek.vavrusa@nic.cz>
Tue, 13 Oct 2015 17:02:21 +0000 (19:02 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Tue, 13 Oct 2015 17:02:21 +0000 (19:02 +0200)
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

daemon/lua/kres.lua
lib/layer.h
lib/layer/iterate.c
lib/resolve.c

index 225341059d8c44ec3e993f13b373425d4461aeda..5441a49fbe64bda171bac5b82f47e6307e1151b1 100644 (file)
@@ -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,
index 827118dfe58241080020f140be4cc5c72c285f5b..2ad9a71da6f6a2150e762254be7bec0c5115383d 100644 (file)
@@ -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
index 2518e249fae7b52b1c3343fe7a6820a290760ad3..df74229d8c613f746ff0c8205576c6ec69367eef 100644 (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
        };
index b2e3e0a1f14b4075e18aa11c3b390e6060653120..c4e7ec89844929c9d2c177337e77418c6b80ddaf 100644 (file)
     (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. */