diff --git a/daemon/lua/kres.lua b/daemon/lua/kres.lua index 9645e89bbb0a2a9afb2121ca80b72a0969a968b1..225341059d8c44ec3e993f13b373425d4461aeda 100644 --- a/daemon/lua/kres.lua +++ b/daemon/lua/kres.lua @@ -175,6 +175,7 @@ struct kr_rplan { struct kr_request { struct kr_context *ctx; knot_pkt_t *answer; + struct kr_query *current_query; struct { const knot_rrset_t *key; const struct sockaddr *addr; @@ -223,7 +224,6 @@ const knot_rrset_t *knot_pkt_rr(const knot_pktsection_t *section, uint16_t i); /* Resolution request */ struct kr_rplan *kr_resolve_plan(struct kr_request *request); /* Resolution plan */ -struct kr_query *kr_rplan_current(struct kr_rplan *rplan); /* Query */ /* Utils */ unsigned kr_rand_uint(unsigned max); @@ -322,7 +322,7 @@ ffi.metatype( kr_request_t, { __index = { current = function(req) assert(req) - return C.kr_rplan_current(C.kr_resolve_plan(req)) + return req.current_query end, }, }) diff --git a/lib/README.rst b/lib/README.rst index a52637037b3d7980cfead74a4f6fb769b57d3318..af3983dc808b006e31509956d098a45ca8bb7ac7 100644 --- a/lib/README.rst +++ b/lib/README.rst @@ -31,7 +31,7 @@ These we call as *driver*. The driver is not meant to know *"how"* the query is .. image:: ../doc/resolution.png :align: center -On the other side are *layers*. They are responsible for dissecting the packets and informing the driver about the results. For example, a produce layer can generate a sub-request, a consume layer can satisfy an outstanding query or simply log something, but they should **never** alter resolution plan directly, as it would change "current query" for next-in-line layers (appending to the resolution plan is fine). They also must not block, and may not be paused. +On the other side are *layers*. They are responsible for dissecting the packets and informing the driver about the results. For example, a produce layer can generate a sub-request, a consume layer can satisfy an outstanding query or simply log something. They also must not block, and may not be paused. .. tip:: Layers are executed asynchronously by the driver. If you need some asset beforehand, you can signalize the driver using returning state or current query flags. For example, setting a flag ``QUERY_AWAIT_CUT`` forces driver to fetch zone cut information before the packet is consumed; setting a ``QUERY_RESOLVED`` flag makes it pop a query after the current set of layers is finished; returning ``FAIL`` state makes it fail current query. The important thing is, these actions happen **after** current set of layers is done. @@ -57,7 +57,7 @@ This structure contains pointers to resolution context, resolution plan and also int consume(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *request = ctx->data; - struct kr_query *query = kr_rplan_current(request->rplan); + struct kr_query *query = request->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). @@ -69,7 +69,7 @@ This is only passive processing of the incoming answer. If you want to change th int produce(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *request = ctx->data; - struct kr_query *cur = kr_rplan_current(request->rplan); + struct kr_query *cur = request->current_query; /* Query can be satisfied locally. */ if (can_satisfy(cur)) { diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index 79d2a405f3d53d117901370f03688d39154a5ca1..2518e249fae7b52b1c3343fe7a6820a290760ad3 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -28,7 +28,7 @@ #include "lib/module.h" #include "lib/dnssec/ta.h" -#define DEBUG_MSG(fmt...) QRDEBUG(kr_rplan_current(&req->rplan), "iter", fmt) +#define DEBUG_MSG(fmt...) QRDEBUG(req->current_query, "iter", fmt) /* Iterator often walks through packet section, this is an abstraction. */ typedef int (*rr_callback_t)(const knot_rrset_t *, unsigned, struct kr_request *); @@ -158,16 +158,14 @@ static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query) return KNOT_STATE_CONSUME; } -static int update_parent(const knot_rrset_t *rr, struct kr_request *req) +static int update_parent(const knot_rrset_t *rr, struct kr_query *qry) { - struct kr_query *qry = kr_rplan_current(&req->rplan); return update_nsaddr(rr, qry->parent); } -static int update_answer(const knot_rrset_t *rr, unsigned hint, struct kr_request *req) +static int update_answer(const knot_rrset_t *rr, unsigned hint, knot_pkt_t *answer) { /* Scrub DNSSEC records when not requested. */ - knot_pkt_t *answer = req->answer; if (!knot_pkt_has_dnssec(answer)) { if (rr->type != knot_pkt_qtype(answer) && knot_rrtype_is_dnssec(rr->type)) { return KNOT_STATE_DONE; /* Scrub */ @@ -214,7 +212,7 @@ static int has_glue(knot_pkt_t *pkt, const knot_dname_t *ns) static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, struct kr_request *req) { - struct kr_query *qry = kr_rplan_current(&req->rplan); + struct kr_query *qry = req->current_query; struct kr_zonecut *cut = &qry->zone_cut; int state = KNOT_STATE_CONSUME; @@ -278,7 +276,7 @@ static const knot_dname_t *signature_authority(knot_pkt_t *pkt) static int process_authority(knot_pkt_t *pkt, struct kr_request *req) { int result = KNOT_STATE_CONSUME; - struct kr_query *qry = kr_rplan_current(&req->rplan); + struct kr_query *qry = req->current_query; const knot_pktsection_t *ns = knot_pkt_section(pkt, KNOT_AUTHORITY); #ifdef STRICT_MODE @@ -360,7 +358,7 @@ static void finalize_answer(knot_pkt_t *pkt, struct kr_query *qry, struct kr_req for (unsigned i = 0; i < ns->count; ++i) { const knot_rrset_t *rr = knot_pkt_rr(ns, i); if (knot_dname_in(cut->name, rr->owner)) { - update_answer(rr, 0, req); + update_answer(rr, 0, answer); } } } @@ -368,7 +366,7 @@ static void finalize_answer(knot_pkt_t *pkt, struct kr_query *qry, struct kr_req static int process_answer(knot_pkt_t *pkt, struct kr_request *req) { - struct kr_query *query = kr_rplan_current(&req->rplan); + struct kr_query *query = req->current_query; /* Response for minimized QNAME. * NODATA => may be empty non-terminal, retry (found zone cut) @@ -407,7 +405,7 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req) if(knot_dname_is_equal(cname, knot_pkt_qname(req->answer))) { hint = KNOT_COMPR_HINT_QNAME; } - int state = is_final ? update_answer(rr, hint, req) : update_parent(rr, req); + int state = is_final ? update_answer(rr, hint, req->answer) : update_parent(rr, query); if (state == KNOT_STATE_FAIL) { return state; } @@ -431,8 +429,6 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req) if (!next) { return KNOT_STATE_FAIL; } - rem_node(&query->node); /* *MUST* keep current query at tail */ - insert_node(&query->node, &next->node); next->flags |= QUERY_AWAIT_CUT; /* Want DNSSEC if it's posible to secure this name (e.g. is covered by any TA) */ if (kr_ta_covers(&req->ctx->trust_anchors, cname) && @@ -488,7 +484,7 @@ static int prepare_query(knot_layer_t *ctx, knot_pkt_t *pkt) { assert(pkt && ctx); struct kr_request *req = ctx->data; - struct kr_query *query = kr_rplan_current(&req->rplan); + struct kr_query *query = req->current_query; if (!query || ctx->state & (KNOT_STATE_DONE|KNOT_STATE_FAIL)) { return ctx->state; } @@ -525,7 +521,7 @@ static int resolve(knot_layer_t *ctx, knot_pkt_t *pkt) { assert(pkt && ctx); struct kr_request *req = ctx->data; - struct kr_query *query = kr_rplan_current(&req->rplan); + struct kr_query *query = req->current_query; if (!query || (query->flags & QUERY_RESOLVED)) { return ctx->state; } diff --git a/lib/layer/pktcache.c b/lib/layer/pktcache.c index d917a6427bd32069af8b989dc2dfc78ce45d7123..57c2114924e3ee4a81fa937eee30548b7d4d0a0e 100644 --- a/lib/layer/pktcache.c +++ b/lib/layer/pktcache.c @@ -22,7 +22,7 @@ #include "lib/cache.h" #include "lib/module.h" -#define DEBUG_MSG(fmt...) QRDEBUG(kr_rplan_current(rplan), " pc ", fmt) +#define DEBUG_MSG(qry, fmt...) QRDEBUG((qry), " pc ", fmt) #define DEFAULT_MAXTTL (15 * 60) #define DEFAULT_NOTTL (5) /* Short-time "no data" retention to avoid bursts */ @@ -96,8 +96,7 @@ static int loot_cache(struct kr_cache_txn *txn, knot_pkt_t *pkt, struct kr_query static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *req = ctx->data; - struct kr_rplan *rplan = &req->rplan; - struct kr_query *qry = kr_rplan_current(rplan); + struct kr_query *qry = req->current_query; if (ctx->state & (KNOT_STATE_FAIL|KNOT_STATE_DONE) || (qry->flags & QUERY_NO_CACHE)) { return ctx->state; /* Already resolved/failed */ } @@ -119,7 +118,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) int ret = loot_cache(&txn, pkt, qry); kr_cache_txn_abort(&txn); if (ret == 0) { - DEBUG_MSG("=> satisfied from cache\n"); + DEBUG_MSG(qry, "=> satisfied from cache\n"); qry->flags |= QUERY_CACHED|QUERY_NO_MINIMIZE; pkt->parsed = pkt->size; knot_wire_set_qr(pkt->wire); @@ -162,8 +161,7 @@ static uint32_t packet_ttl(knot_pkt_t *pkt) static int stash(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *req = ctx->data; - struct kr_rplan *rplan = &req->rplan; - struct kr_query *qry = kr_rplan_current(rplan); + struct kr_query *qry = 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 & KNOT_STATE_FAIL) { @@ -211,7 +209,7 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt) if (ret != 0) { kr_cache_txn_abort(&txn); } else { - DEBUG_MSG("=> answer cached for TTL=%u\n", ttl); + DEBUG_MSG(qry, "=> answer cached for TTL=%u\n", ttl); kr_cache_txn_commit(&txn); } return ctx->state; diff --git a/lib/layer/rrcache.c b/lib/layer/rrcache.c index 5c2473df5704b246c493e9fc29bdcdbd51b3b012..909b62190f42482d4500b28448d1583e9f5fb484 100644 --- a/lib/layer/rrcache.c +++ b/lib/layer/rrcache.c @@ -27,7 +27,7 @@ #include "lib/module.h" #include "lib/utils.h" -#define DEBUG_MSG(fmt...) QRDEBUG(kr_rplan_current(rplan), " rc ", fmt) +#define DEBUG_MSG(qry, fmt...) QRDEBUG((qry), " rc ", fmt) #define DEFAULT_MINTTL (5) /* Short-time "no data" retention to avoid bursts */ /** Record is expiring if it has less than 1% TTL (or less than 5s) */ @@ -105,8 +105,7 @@ static int loot_cache(struct kr_cache *cache, knot_pkt_t *pkt, struct kr_query * static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *req = ctx->data; - struct kr_rplan *rplan = &req->rplan; - struct kr_query *qry = kr_rplan_current(rplan); + struct kr_query *qry = req->current_query; if (ctx->state & (KNOT_STATE_FAIL|KNOT_STATE_DONE) || (qry->flags & QUERY_NO_CACHE)) { return ctx->state; /* Already resolved/failed */ } @@ -133,7 +132,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) } } if (ret == 0) { - DEBUG_MSG("=> satisfied from cache\n"); + DEBUG_MSG(qry, "=> satisfied from cache\n"); qry->flags |= QUERY_CACHED|QUERY_NO_MINIMIZE; pkt->parsed = pkt->size; knot_wire_set_qr(pkt->wire); @@ -277,8 +276,7 @@ static int stash_answer(struct kr_query *qry, knot_pkt_t *pkt, map_t *stash, mm_ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt) { struct kr_request *req = ctx->data; - struct kr_rplan *rplan = &req->rplan; - struct kr_query *qry = kr_rplan_current(rplan); + struct kr_query *qry = req->current_query; if (!qry || ctx->state & KNOT_STATE_FAIL) { return ctx->state; } @@ -296,19 +294,19 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt) map_t stash = map_make(); stash.malloc = (map_alloc_f) mm_alloc; stash.free = (map_free_f) mm_free; - stash.baton = rplan->pool; + stash.baton = &req->pool; int ret = 0; bool is_auth = knot_wire_get_aa(pkt->wire); if (is_auth) { - ret = stash_answer(qry, pkt, &stash, rplan->pool); + ret = stash_answer(qry, pkt, &stash, &req->pool); } /* Cache authority only if chasing referral/cname chain */ - if (!is_auth || qry != HEAD(rplan->pending)) { - ret = stash_authority(qry, pkt, &stash, rplan->pool); + if (!is_auth || qry != TAIL(req->rplan.pending)) { + ret = stash_authority(qry, pkt, &stash, &req->pool); } /* Cache DS records in referrals */ if (!is_auth && knot_pkt_has_dnssec(pkt)) { - stash_ds(qry, pkt, &stash, rplan->pool); + stash_ds(qry, pkt, &stash, &req->pool); } /* Cache stashed records */ if (ret == 0 && stash.root != NULL) { diff --git a/lib/layer/validate.c b/lib/layer/validate.c index cedda57b805bf74ca77560ec43f588cf4d00fe67..09d3fcd884e5d4115e06ffaa3ee7e4905f3070e8 100644 --- a/lib/layer/validate.c +++ b/lib/layer/validate.c @@ -276,7 +276,7 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt) { int ret = 0; struct kr_request *req = ctx->data; - struct kr_query *qry = kr_rplan_current(&req->rplan); + struct kr_query *qry = req->current_query; /* Ignore faulty or unprocessed responses. */ if (ctx->state & (KNOT_STATE_FAIL|KNOT_STATE_CONSUME)) { return ctx->state; diff --git a/lib/resolve.c b/lib/resolve.c index f2c3166862123f341889ac8bc70b51b503752597..b2e3e0a1f14b4075e18aa11c3b390e6060653120 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -26,10 +26,11 @@ #include "lib/layer/iterate.h" #include "lib/dnssec/ta.h" -#define DEBUG_MSG(fmt...) QRDEBUG(kr_rplan_current(rplan), "resl", fmt) +#define DEBUG_MSG(qry, fmt...) QRDEBUG((qry), "resl", fmt) /** @internal Macro for iterating module layers. */ -#define ITERATE_LAYERS(req, func, ...) \ +#define ITERATE_LAYERS(req, qry, func, ...) \ + (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 ) { \ @@ -38,7 +39,8 @@ (req)->state = layer.api->func(&layer, ##__VA_ARGS__); \ } \ } \ - } + } /* Invalidate current query. */ \ + (req)->current_query = NULL /* Randomize QNAME letter case. * This adds 32 bits of randomness at maximum, but that's more than an average domain name length. @@ -124,13 +126,13 @@ static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param) if (!next_type || kr_rplan_satisfies(qry->parent, qry->ns.name, KNOT_CLASS_IN, next_type)) { /* Fall back to SBELT if root server query fails. */ if (!next_type && qry->zone_cut.name[0] == '\0') { - DEBUG_MSG("=> fallback to root hints\n"); + DEBUG_MSG(qry, "=> fallback to root hints\n"); kr_zonecut_set_sbelt(ctx, &qry->zone_cut); qry->flags |= QUERY_NO_THROTTLE; /* Pick even bad SBELT servers */ return kr_error(EAGAIN); } /* No IPv4 nor IPv6, flag server as unuseable. */ - DEBUG_MSG("=> unresolvable NS address, bailing out\n"); + DEBUG_MSG(qry, "=> unresolvable NS address, bailing out\n"); qry->ns.reputation |= KR_NS_NOIP4 | KR_NS_NOIP6; kr_nsrep_update_rep(&qry->ns, qry->ns.reputation, ctx->cache_rep); invalidate_ns(rplan, qry); @@ -249,6 +251,7 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pk request->answer = answer; request->options = ctx->options; request->state = KNOT_STATE_CONSUME; + request->current_query = NULL; /* Expect first query */ kr_rplan_init(&request->rplan, request, &request->pool); @@ -284,7 +287,7 @@ static int resolve_query(struct kr_request *request, const knot_pkt_t *packet) knot_wire_set_rcode(answer->wire, KNOT_RCODE_NOERROR); /* Expect answer, pop if satisfied immediately */ - ITERATE_LAYERS(request, begin, request); + ITERATE_LAYERS(request, qry, begin, request); if (request->state == KNOT_STATE_DONE) { kr_rplan_pop(rplan, qry); } @@ -295,7 +298,6 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k { struct kr_rplan *rplan = &request->rplan; struct kr_context *ctx = request->ctx; - struct kr_query *qry = kr_rplan_current(rplan); /* Empty resolution plan, push packet as the new query */ if (packet && kr_rplan_empty(rplan)) { @@ -306,11 +308,12 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k } /* Different processing for network error */ + struct kr_query *qry = TAIL(rplan->pending); bool tried_tcp = (qry->flags & QUERY_TCP); if (!packet || packet->size == 0) { /* Network error, retry over TCP. */ if (!tried_tcp) { - DEBUG_MSG("=> NS unreachable, retrying over TCP\n"); + DEBUG_MSG(qry, "=> NS unreachable, retrying over TCP\n"); qry->flags |= QUERY_TCP; return KNOT_STATE_PRODUCE; } @@ -321,7 +324,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); } - ITERATE_LAYERS(request, consume, packet); + ITERATE_LAYERS(request, qry, consume, packet); } /* Resolution failed, invalidate current NS. */ @@ -347,7 +350,7 @@ int kr_resolve_consume(struct kr_request *request, const struct sockaddr *src, k qry->flags &= ~(QUERY_CACHED|QUERY_TCP); } - ITERATE_LAYERS(request, reset); + ITERATE_LAYERS(request, qry, reset); /* Do not finish with bogus answer. */ if (qry->flags & QUERY_DNSSEC_BOGUS) { @@ -403,10 +406,10 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot return KNOT_STATE_FAIL; } if (qry->sname[0] != '\0') { - DEBUG_MSG("=> root priming query\n"); + DEBUG_MSG(qry, "=> root priming query\n"); zone_cut_subreq(rplan, qry, qry->zone_cut.name, KNOT_RRTYPE_NS); } else { - DEBUG_MSG("=> using root hints\n"); + DEBUG_MSG(qry, "=> using root hints\n"); } qry->flags &= ~QUERY_AWAIT_CUT; return KNOT_STATE_DONE; @@ -424,7 +427,7 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot } /* Disable DNSSEC if it enters NTA. */ if (kr_ta_get(negative_anchors, qry->zone_cut.name)){ - DEBUG_MSG(">< negative TA, going insecure\n"); + DEBUG_MSG(qry, ">< negative TA, going insecure\n"); qry->flags &= ~QUERY_DNSSEC_WANT; } /* Enable DNSSEC if enters a new island of trust. */ @@ -435,7 +438,7 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot WITH_DEBUG { char qname_str[KNOT_DNAME_MAXLEN]; knot_dname_to_str(qname_str, qry->zone_cut.name, sizeof(qname_str)); - DEBUG_MSG(">< TA: '%s'\n", qname_str); + DEBUG_MSG(qry, ">< TA: '%s'\n", qname_str); } } if (want_secured && !qry->zone_cut.trust_anchor) { @@ -473,21 +476,21 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *type, knot_pkt_t *packet) { struct kr_rplan *rplan = &request->rplan; - struct kr_query *qry = kr_rplan_current(rplan); unsigned ns_election_iter = 0; - + /* No query left for resolution */ if (kr_rplan_empty(rplan)) { return KNOT_STATE_FAIL; } /* Resolve current query and produce dependent or finish */ - ITERATE_LAYERS(request, produce, packet); + struct kr_query *qry = TAIL(rplan->pending); + ITERATE_LAYERS(request, qry, produce, packet); if (request->state != KNOT_STATE_FAIL && knot_wire_get_qr(packet->wire)) { /* Produced an answer, consume it. */ qry->secret = 0; request->state = KNOT_STATE_CONSUME; - ITERATE_LAYERS(request, consume, packet); + ITERATE_LAYERS(request, qry, consume, packet); } switch(request->state) { case KNOT_STATE_FAIL: return request->state; @@ -497,13 +500,13 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t if (qry->flags & QUERY_RESOLVED) { kr_rplan_pop(rplan, qry); } - ITERATE_LAYERS(request, reset); + ITERATE_LAYERS(request, qry, reset); return kr_rplan_empty(rplan) ? KNOT_STATE_DONE : KNOT_STATE_PRODUCE; } /* This query has RD=0 or is ANY, stop here. */ if (qry->stype == KNOT_RRTYPE_ANY || !knot_wire_get_rd(request->answer->wire)) { - DEBUG_MSG("=> qtype is ANY or RD=0, bail out\n"); + DEBUG_MSG(qry, "=> qtype is ANY or RD=0, bail out\n"); return KNOT_STATE_FAIL; } @@ -521,7 +524,7 @@ ns_election: * elect best address only, otherwise elect a completely new NS. */ if(++ns_election_iter >= KR_ITER_LIMIT) { - DEBUG_MSG("=> couldn't converge NS selection, bail out\n"); + DEBUG_MSG(qry, "=> couldn't converge NS selection, bail out\n"); return KNOT_STATE_FAIL; } if (qry->flags & (QUERY_AWAIT_IPV4|QUERY_AWAIT_IPV6)) { @@ -529,14 +532,14 @@ ns_election: } else if (!qry->ns.name || !(qry->flags & QUERY_TCP)) { /* Keep address when TCP retransmit. */ /* Root DNSKEY must be fetched from the hints to avoid chicken and egg problem. */ if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) { - DEBUG_MSG("=> priming root DNSKEY\n"); + DEBUG_MSG(qry, "=> priming root DNSKEY\n"); kr_zonecut_set_sbelt(request->ctx, &qry->zone_cut); qry->flags |= QUERY_NO_THROTTLE; /* Pick even bad SBELT servers */ } kr_nsrep_elect(qry, request->ctx); if (qry->ns.score > KR_NS_MAX_SCORE) { - DEBUG_MSG("=> no valid NS left\n"); - ITERATE_LAYERS(request, reset); + DEBUG_MSG(qry, "=> no valid NS left\n"); + ITERATE_LAYERS(request, qry, reset); kr_rplan_pop(rplan, qry); return KNOT_STATE_PRODUCE; } @@ -549,7 +552,7 @@ ns_election: qry->flags &= ~(QUERY_AWAIT_IPV6|QUERY_AWAIT_IPV4|QUERY_TCP); goto ns_election; /* Must try different NS */ } - ITERATE_LAYERS(request, reset); + ITERATE_LAYERS(request, qry, reset); return KNOT_STATE_PRODUCE; } @@ -570,7 +573,7 @@ ns_election: break; } inet_ntop(addr->sa_family, kr_nsrep_inaddr(qry->ns.addr[i]), ns_str, sizeof(ns_str)); - DEBUG_MSG("%s: '%s' score: %u zone cut: '%s' m12n: '%s' type: '%s'\n", + DEBUG_MSG(qry, "%s: '%s' score: %u zone cut: '%s' m12n: '%s' type: '%s'\n", i == 0 ? "=> querying" : " optional", ns_str, qry->ns.score, zonecut_str, qname_str, type_str); } @@ -599,8 +602,8 @@ int kr_resolve_finish(struct kr_request *request, int state) } } - ITERATE_LAYERS(request, finish); - DEBUG_MSG("finished: %d, queries: %zu, mempool: %zu B\n", + ITERATE_LAYERS(request, NULL, finish); + DEBUG_MSG(NULL, "finished: %d, queries: %zu, mempool: %zu B\n", state, list_size(&rplan->resolved), (size_t) mp_total_size(request->pool.ctx)); return KNOT_STATE_DONE; } diff --git a/lib/resolve.h b/lib/resolve.h index e8db746b2d66be82b45a3787d58bb2e04e4fd2e3..e5665f3e55ae6459cee0be205150b53552fa4654 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -108,6 +108,7 @@ struct kr_context struct kr_request { struct kr_context *ctx; knot_pkt_t *answer; + struct kr_query *current_query; /**< Current evaluated query. */ struct { const knot_rrset_t *key; const struct sockaddr *addr; diff --git a/lib/rplan.c b/lib/rplan.c index 85361108c3b4187e19cd73624a671a2e7bb258c7..744384e84a1fc18bade32830d3f268f3d08540a4 100644 --- a/lib/rplan.c +++ b/lib/rplan.c @@ -144,15 +144,6 @@ int kr_rplan_pop(struct kr_rplan *rplan, struct kr_query *qry) return KNOT_EOK; } -struct kr_query *kr_rplan_current(struct kr_rplan *rplan) -{ - if (kr_rplan_empty(rplan)) { - return NULL; - } - - return TAIL(rplan->pending); -} - bool kr_rplan_satisfies(struct kr_query *closure, const knot_dname_t *name, uint16_t cls, uint16_t type) { while (closure != NULL) { diff --git a/lib/rplan.h b/lib/rplan.h index 768ecce651210c0d96408df211b115c64b481841..97847ffeb48bf006857d2943f2a7bb661fc3a61d 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -129,13 +129,6 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent, */ int kr_rplan_pop(struct kr_rplan *rplan, struct kr_query *qry); -/** - * Currently resolved query (at the top). - * @param rplan plan instance - * @return query instance or NULL if empty - */ -struct kr_query *kr_rplan_current(struct kr_rplan *rplan); - /** * Return true if resolution chain satisfies given query. */ diff --git a/modules/hints/hints.c b/modules/hints/hints.c index c65ca7abac84e214e61a5f49e1701a79b3141e44..5b2c90ea8362baf4b74111a337ca3b012bf0ac97 100644 --- a/modules/hints/hints.c +++ b/modules/hints/hints.c @@ -90,8 +90,8 @@ static int answer_query(knot_pkt_t *pkt, pack_t *addr_set, struct kr_query *qry) static int query(knot_layer_t *ctx, knot_pkt_t *pkt) { - struct kr_request *param = ctx->data; - struct kr_query *qry = kr_rplan_current(¶m->rplan); + struct kr_request *req = ctx->data; + struct kr_query *qry = req->current_query; if (!qry || ctx->state & (KNOT_STATE_DONE|KNOT_STATE_FAIL)) { return ctx->state; } diff --git a/tests/test_rplan.c b/tests/test_rplan.c index 6db70b430572bf6cefab2aff11181c588a9eaec7..53d22f92bd43e536fe1e10b24e4a488f9bb6b586 100644 --- a/tests/test_rplan.c +++ b/tests/test_rplan.c @@ -26,7 +26,6 @@ static void test_rplan_params(void **state) assert_null((void *)kr_rplan_push(NULL, NULL, NULL, 0, 0)); assert_int_equal(kr_rplan_pop(NULL, NULL), KNOT_EINVAL); assert_true(kr_rplan_empty(NULL) == true); - assert_null((void *)kr_rplan_current(NULL)); kr_rplan_deinit(NULL); /* NULL mandatory parameters */ @@ -36,7 +35,6 @@ static void test_rplan_params(void **state) assert_null((void *)kr_rplan_push(&rplan, NULL, NULL, 0, 0)); assert_int_equal(kr_rplan_pop(&rplan, NULL), KNOT_EINVAL); assert_true(kr_rplan_empty(&rplan) == true); - assert_null((void *)kr_rplan_current(&rplan)); kr_rplan_deinit(&rplan); }