]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/resolve: overlay is not copied on startup
authorMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 20 Jul 2015 22:42:48 +0000 (00:42 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 20 Jul 2015 22:42:48 +0000 (00:42 +0200)
this fixes a problem when a module was removed, but pending
queries referenced it, causing a crash. usually when the
server was busy and a module was unloaded.
as we don’t need to copy layers at all, they’re just iterated
from the array of modules using a macro

daemon/worker.c
lib/resolve.c
lib/resolve.h

index 31586bd290c30c1f04f23111c447e07435e6efed..7208c87ec97ee8a8f3b5bcf5ae823fbfaa47459b 100644 (file)
@@ -192,7 +192,7 @@ static void qr_task_timeout(uv_timer_t *req)
 
 static int qr_task_on_send(struct qr_task *task, uv_handle_t *handle, int status)
 {
-       if (task->req.overlay.state != KNOT_STATE_NOOP) {
+       if (task->req.state != KNOT_STATE_NOOP) {
                if (status == 0 && handle) {
                        io_start_read(handle); /* Start reading answer */
                }
index 84ef95baf96477959ded7c23c0ffd08cd2e105c6..2a30c1b8d89f9dade1e425a09d98196f16f0b02a 100644 (file)
 
 #define DEBUG_MSG(fmt...) QRDEBUG(kr_rplan_current(rplan), "resl",  fmt)
 
+/** @internal Macro for iterating module layers. */
+#define ITERATE_LAYERS(req, func, ...) \
+       for (unsigned i = 0; i < (req)->ctx->modules->len; ++i) { \
+               struct kr_module *mod = (req)->ctx->modules->at[i]; \
+               if (mod->layer) { \
+                       struct knot_layer layer = {.state = (req)->state, .api = mod->layer(mod), .data = (req)}; \
+                       (req)->state = (func)(&layer, ##__VA_ARGS__); \
+               } \
+       }
+
 /* Randomize QNAME letter case.
  * This adds 32 bits of randomness at maximum, but that's more than an average domain name length.
  * https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00
@@ -132,17 +142,6 @@ static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param)
        return kr_ok();
 }
 
-static void prepare_layers(struct kr_request *param)
-{
-       struct kr_context *ctx = param->ctx;
-       for (size_t i = 0; i < ctx->modules->len; ++i) {
-               struct kr_module *mod = ctx->modules->at[i];
-               if (mod->layer) {
-                       knot_overlay_add(&param->overlay, mod->layer(mod), param);
-               }
-       }
-}
-
 static int connected(struct sockaddr *addr, int proto, struct timeval *timeout)
 {
        unsigned flags = (proto == SOCK_STREAM) ? O_NONBLOCK : 0;
@@ -345,11 +344,10 @@ int kr_resolve(struct kr_context* ctx, knot_pkt_t *answer,
 int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pkt_t *answer)
 {
        /* Initialize request */
-       knot_overlay_init(&request->overlay, &request->pool);
        request->ctx = ctx;
        request->answer = answer;
        request->options = ctx->options;
-       prepare_layers(request);
+       request->state = KNOT_STATE_CONSUME;
 
        /* Expect first query */
        kr_rplan_init(&request->rplan, request, &request->pool);
@@ -397,7 +395,6 @@ int kr_resolve_consume(struct kr_request *request, knot_pkt_t *packet)
        }
 
        /* Different processing for network error */
-       int state = KNOT_STATE_FAIL;
        if (!packet || packet->size == 0) {
                /* Network error, retry over TCP. */
                if (!(qry->flags & QUERY_TCP)) {
@@ -405,17 +402,18 @@ int kr_resolve_consume(struct kr_request *request, knot_pkt_t *packet)
                        qry->flags |= QUERY_TCP;
                        return KNOT_STATE_PRODUCE;
                }
+               request->state = KNOT_STATE_FAIL;
        } else {
                /* Packet cleared, derandomize QNAME. */
                knot_dname_t *qname_raw = (knot_dname_t *)knot_pkt_qname(packet);
                if (qname_raw && qry->secret != 0) {
                        randomized_qname_case(qname_raw, qry->secret);
                }
-               state = knot_overlay_consume(&request->overlay, packet);
+               ITERATE_LAYERS(request, knot_layer_consume, packet);
        }
 
        /* Resolution failed, invalidate current NS. */
-       if (state == KNOT_STATE_FAIL) {
+       if (request->state == KNOT_STATE_FAIL) {
                kr_nsrep_update_rtt(&qry->ns, KR_NS_TIMEOUT, ctx->cache_rtt);
                invalidate_ns(rplan, qry);
        /* Track RTT for iterative answers */
@@ -434,7 +432,7 @@ int kr_resolve_consume(struct kr_request *request, knot_pkt_t *packet)
                qry->flags &= ~(QUERY_CACHED|QUERY_TCP);
        }
 
-       knot_overlay_reset(&request->overlay);
+       ITERATE_LAYERS(request, knot_layer_reset);
        return kr_rplan_empty(&request->rplan) ? KNOT_STATE_DONE : KNOT_STATE_PRODUCE;
 }
 
@@ -457,22 +455,22 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t
 #endif
 
        /* Resolve current query and produce dependent or finish */
-       int state = knot_overlay_produce(&request->overlay, packet);
-       if (state != KNOT_STATE_FAIL && knot_wire_get_qr(packet->wire)) {
+       ITERATE_LAYERS(request, knot_layer_produce, packet);
+       if (request->state != KNOT_STATE_FAIL && knot_wire_get_qr(packet->wire)) {
                /* Produced an answer, consume it. */
                qry->secret = 0;
-               request->overlay.state = KNOT_STATE_CONSUME;
-               state = knot_overlay_consume(&request->overlay, packet);
+               request->state = KNOT_STATE_CONSUME;
+               ITERATE_LAYERS(request, knot_layer_consume, packet);
        }
-       switch(state) {
-       case KNOT_STATE_FAIL: return state; break;
+       switch(request->state) {
+       case KNOT_STATE_FAIL: return request->state; break;
        case KNOT_STATE_CONSUME: break;
        case KNOT_STATE_DONE:
        default: /* Current query is done */
                if (qry->flags & QUERY_RESOLVED) {
                        kr_rplan_pop(rplan, qry);
                }
-               knot_overlay_reset(&request->overlay);
+               ITERATE_LAYERS(request, knot_layer_reset);
                return kr_rplan_empty(rplan) ? KNOT_STATE_DONE : KNOT_STATE_PRODUCE;
        }
 
@@ -505,7 +503,7 @@ ns_election:
                kr_nsrep_elect(qry, request->ctx);
                if (qry->ns.score > KR_NS_MAX_SCORE) {
                        DEBUG_MSG("=> no valid NS left\n");
-                       knot_overlay_reset(&request->overlay);
+                       ITERATE_LAYERS(request, knot_layer_reset);
                        kr_rplan_pop(rplan, qry);
                        return KNOT_STATE_PRODUCE;
                }
@@ -517,7 +515,7 @@ ns_election:
                        qry->flags &= ~(QUERY_AWAIT_IPV6|QUERY_AWAIT_IPV4);
                        goto ns_election; /* Must try different NS */
                }
-               knot_overlay_reset(&request->overlay);
+               ITERATE_LAYERS(request, knot_layer_reset);
                return KNOT_STATE_PRODUCE;
        }
 
@@ -539,7 +537,7 @@ ns_election:
        gettimeofday(&qry->timestamp, NULL);
        *dst = &qry->ns.addr.ip;
        *type = (qry->flags & QUERY_TCP) ? SOCK_STREAM : SOCK_DGRAM;
-       return state;
+       return request->state;
 }
 
 int kr_resolve_finish(struct kr_request *request, int state)
@@ -559,10 +557,8 @@ int kr_resolve_finish(struct kr_request *request, int state)
                        knot_wire_set_rcode(answer->wire, KNOT_RCODE_SERVFAIL);
                }
        }
-       knot_overlay_finish(&request->overlay);
+       ITERATE_LAYERS(request, knot_layer_finish);
        /* Clean up. */
-       knot_overlay_deinit(&request->overlay);
-       request->overlay.state = KNOT_STATE_NOOP;
        kr_rplan_deinit(&request->rplan);
        return KNOT_STATE_DONE;
 }
index fbc207b8673f556d71b862e1aa654959e5f5b8c1..3f1ddb7ac2dcfa72eb8cd375a1ae8758897fa697 100644 (file)
@@ -17,7 +17,7 @@
 #pragma once
 
 #include <netinet/in.h>
-#include <libknot/processing/overlay.h>
+#include <libknot/processing/layer.h>
 #include <libknot/packet/pkt.h>
 
 #include "lib/generic/array.h"
@@ -125,10 +125,10 @@ struct kr_context
 struct kr_request {
     struct kr_context *ctx;
     struct kr_rplan rplan;
-    struct knot_overlay overlay;
     knot_pkt_t *answer;
     mm_ctx_t pool;
     uint32_t options;
+    int state;
 };
 
 /**