diff --git a/lib/layer/pktcache.c b/lib/layer/pktcache.c index 1b1057c1d519a9c6196d0924bef65b88428c475d..c4a50d0797a4a80c1ca2dbd052f6deb0f9484c9f 100644 --- a/lib/layer/pktcache.c +++ b/lib/layer/pktcache.c @@ -26,9 +26,9 @@ #define DEFAULT_MAXTTL (15 * 60) #define DEFAULT_NOTTL (5) /* Short-time "no data" retention to avoid bursts */ -static inline uint8_t get_tag(struct kr_request *req) +static inline uint8_t get_tag(struct kr_query *qry) { - return (req->options & QUERY_DNSSEC_WANT) ? KR_CACHE_SEC : KR_CACHE_PKT; + return (qry->flags & QUERY_DNSSEC_WANT) ? KR_CACHE_SEC : KR_CACHE_PKT; } static uint32_t limit_ttl(uint32_t ttl) @@ -115,7 +115,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) } /* Fetch either answer to original or minimized query */ - uint8_t tag = get_tag(req); + uint8_t tag = get_tag(qry); int ret = loot_cache(&txn, pkt, tag, qry); kr_cache_txn_abort(&txn); if (ret == 0) { @@ -197,7 +197,7 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt) }; /* Stash answer in the cache */ - int ret = kr_cache_insert(&txn, get_tag(req), qname, qtype, &header, data); + int ret = kr_cache_insert(&txn, get_tag(qry), qname, qtype, &header, data); if (ret != 0) { kr_cache_txn_abort(&txn); } else { diff --git a/lib/layer/rrcache.c b/lib/layer/rrcache.c index 2a3e6a150f139cbd8ff2ea1b316741f7147a64ae..f72dbf3f34852b0497db89c0cc5da8fcfc649a4c 100644 --- a/lib/layer/rrcache.c +++ b/lib/layer/rrcache.c @@ -125,7 +125,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) * Only one step of the chain is resolved at a time. */ struct kr_cache *cache = &req->ctx->cache; - int ret = loot_cache(cache, pkt, qry, req->options & QUERY_DNSSEC_WANT); + int ret = loot_cache(cache, pkt, qry, (qry->flags & QUERY_DNSSEC_WANT)); if (ret == 0) { DEBUG_MSG("=> satisfied from cache\n"); qry->flags |= QUERY_CACHED|QUERY_NO_MINIMIZE; @@ -141,6 +141,7 @@ static int peek(knot_layer_t *ctx, knot_pkt_t *pkt) struct stash_baton { struct kr_request *req; + struct kr_query *qry; struct kr_cache_txn *txn; unsigned timestamp; uint32_t min_ttl; @@ -149,7 +150,7 @@ struct stash_baton static int commit_rrsig(struct stash_baton *baton, knot_rrset_t *rr) { /* If not doing secure resolution, ignore (unvalidated) RRSIGs. */ - if (!(baton->req->options & QUERY_DNSSEC_WANT)) { + if (!(baton->qry->flags & QUERY_DNSSEC_WANT)) { return kr_ok(); } /* Commit covering RRSIG to a separate cache namespace. */ @@ -197,12 +198,13 @@ static int commit_rr(const char *key, void *val, void *data) return kr_cache_insert_rr(baton->txn, rr, baton->timestamp); } -static int stash_commit(map_t *stash, unsigned timestamp, struct kr_cache_txn *txn, struct kr_request *req) +static int stash_commit(map_t *stash, struct kr_query *qry, struct kr_cache_txn *txn, struct kr_request *req) { struct stash_baton baton = { .req = req, + .qry = qry, .txn = txn, - .timestamp = timestamp, + .timestamp = qry->timestamp.tv_sec, .min_ttl = DEFAULT_MINTTL }; return map_walk(stash, &commit_rr, &baton); @@ -339,7 +341,7 @@ static int stash(knot_layer_t *ctx, knot_pkt_t *pkt) struct kr_cache *cache = &req->ctx->cache; struct kr_cache_txn txn; if (kr_cache_txn_begin(cache, &txn, 0) == 0) { - ret = stash_commit(&stash, qry->timestamp.tv_sec, &txn, req); + ret = stash_commit(&stash, qry, &txn, req); if (ret == 0) { kr_cache_txn_commit(&txn); } else { diff --git a/lib/resolve.c b/lib/resolve.c index 94084ce1730d26940d214cbb0806ae6ba871d6b6..c77b40cec9f3d6363d3ffbb441aa2ad2c0169bdf 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -154,10 +154,6 @@ static int edns_put(knot_pkt_t *pkt) static int edns_create(knot_pkt_t *pkt, knot_pkt_t *template, struct kr_request *req) { pkt->opt_rr = knot_rrset_copy(req->ctx->opt_rr, &pkt->mm); - /* Set DO bit if set (DNSSEC requested). */ - if (knot_pkt_has_dnssec(template) || (req->options & QUERY_DNSSEC_WANT)) { - knot_edns_set_do(pkt->opt_rr); - } return knot_pkt_reserve(pkt, knot_edns_wire_size(pkt->opt_rr)); } @@ -175,6 +171,10 @@ static int answer_prepare(knot_pkt_t *answer, knot_pkt_t *query, struct kr_reque if (ret != 0){ return ret; } + /* Set DO bit if set (DNSSEC requested). */ + if (knot_pkt_has_dnssec(query)) { + knot_edns_set_do(answer->opt_rr); + } } return kr_ok(); } @@ -197,10 +197,9 @@ static int answer_finalize(struct kr_request *request, int state) return kr_ok(); } -static int query_finalize(struct kr_request *request, knot_pkt_t *pkt) +static int query_finalize(struct kr_request *request, struct kr_query *qry, knot_pkt_t *pkt) { /* Randomize query case (if not in safemode) */ - struct kr_query *qry = kr_rplan_current(&request->rplan); qry->secret = (qry->flags & QUERY_SAFEMODE) ? 0 : kr_rand_uint(UINT32_MAX); knot_dname_t *qname_raw = (knot_dname_t *)knot_pkt_qname(pkt); randomized_qname_case(qname_raw, qry->secret); @@ -209,7 +208,10 @@ static int query_finalize(struct kr_request *request, knot_pkt_t *pkt) knot_pkt_begin(pkt, KNOT_ADDITIONAL); if (!(qry->flags & QUERY_SAFEMODE)) { ret = edns_create(pkt, request->answer, request); - if (ret == 0) { + if (ret == 0) { /* Enable DNSSEC for query. */ + if (qry->flags & QUERY_DNSSEC_WANT) { + knot_edns_set_do(pkt->opt_rr); + } ret = edns_put(pkt); } } @@ -229,9 +231,12 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pk return KNOT_STATE_CONSUME; } -int kr_resolve_query(struct kr_request *request, const knot_dname_t *qname, uint16_t qclass, uint16_t qtype) +static int resolve_query(struct kr_request *request, const knot_pkt_t *packet) { struct kr_rplan *rplan = &request->rplan; + const knot_dname_t *qname = knot_pkt_qname(packet); + uint16_t qclass = knot_pkt_qclass(packet); + uint16_t qtype = knot_pkt_qtype(packet); struct kr_query *qry = kr_rplan_push(rplan, NULL, qname, qclass, qtype); if (!qry) { return KNOT_STATE_FAIL; @@ -239,6 +244,9 @@ int kr_resolve_query(struct kr_request *request, const knot_dname_t *qname, uint /* Deferred zone cut lookup for this query. */ qry->flags |= QUERY_AWAIT_CUT; + if (knot_pkt_has_dnssec(packet)) { + qry->flags |= QUERY_DNSSEC_WANT; + } /* Initialize answer packet */ knot_pkt_t *answer = request->answer; @@ -266,11 +274,7 @@ int kr_resolve_consume(struct kr_request *request, knot_pkt_t *packet) if (answer_prepare(request->answer, packet, request) != 0) { return KNOT_STATE_FAIL; } - /* Start query resolution */ - const knot_dname_t *qname = knot_pkt_qname(packet); - uint16_t qclass = knot_pkt_qclass(packet); - uint16_t qtype = knot_pkt_qtype(packet); - return kr_resolve_query(request, qname, qclass, qtype); + return resolve_query(request, packet); } /* Different processing for network error */ @@ -336,6 +340,9 @@ static int zone_cut_subreq(struct kr_rplan *rplan, struct kr_query *parent, return kr_error(ENOMEM); } next->flags |= QUERY_NO_MINIMIZE; + if (parent->flags & QUERY_DNSSEC_WANT) { + next->flags |= QUERY_DNSSEC_WANT; + } return kr_ok(); } @@ -472,7 +479,7 @@ ns_election: } /* Prepare additional query */ - int ret = query_finalize(request, packet); + int ret = query_finalize(request, qry, packet); if (ret != 0) { return KNOT_STATE_FAIL; } diff --git a/lib/resolve.h b/lib/resolve.h index a6afb2ba65b65415c71573c858c3dcd99675bb1a..c373819b7d9fa25c2e8ab7c2227bf3405487a3f9 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -42,8 +42,10 @@ * .alloc = (mm_alloc_t) mp_alloc * } * }; - * kr_resolve_begin(&req, ctx, answer); - * int state = kr_resolve_query(&req, qname, qclass, qtype); + * + * // Setup and provide input query + * int state = kr_resolve_begin(&req, ctx, final_answer); + * state = kr_resolve_consume(&req, query); * * // Generate answer * while (state == KNOT_STATE_PRODUCE) { @@ -126,16 +128,6 @@ struct kr_request { */ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pkt_t *answer); -/** - * Push new query for resolution to the state. - * @param request request state (if already has a question, this will be resolved first) - * @param qname - * @param qclass - * @param qtype - * @return PRODUCE|FAIL - */ -int kr_resolve_query(struct kr_request *request, const knot_dname_t *qname, uint16_t qclass, uint16_t qtype); - /** * Consume input packet (may be either first query or answer to query originated from kr_resolve_produce()) * diff --git a/modules/stats/stats.c b/modules/stats/stats.c index 3b449a9edad30bec43e86fa1fd7c62a54c9d66e6..7941bb5f0a6107602c2d078a82dc3f316e295bf4 100644 --- a/modules/stats/stats.c +++ b/modules/stats/stats.c @@ -162,7 +162,7 @@ static int collect(knot_layer_t *ctx) /* Query parameters and transport mode */ if (knot_pkt_has_edns(param->answer)) { stat_const_add(data, metric_query_edns, 1); - if (param->options & QUERY_DNSSEC_WANT) { + if (knot_pkt_has_dnssec(param->answer)) { stat_const_add(data, metric_query_dnssec, 1); } }