From: Vladimír Čunát Date: Mon, 16 Oct 2017 14:16:14 +0000 (+0200) Subject: . X-Git-Tag: v2.0.0~6^2~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8632e31fb0d415fe7e089d9714cd9ea6d63db9c;p=thirdparty%2Fknot-resolver.git . --- diff --git a/lib/cache.c b/lib/cache.c index c4006269c..3a64a8ad1 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -849,6 +849,7 @@ int cache_lmdb_peek(kr_layer_t *ctx, knot_pkt_t *pkt) /** 1b. otherwise, find the longest prefix NS/xNAME (with OK time+rank). [...] */ k->dname = qry->sname; const struct entry_h *eh = closest_NS(ctx, k); +#if 0 if (!eh) { /* fall back to root hints? */ ret = kr_zonecut_set_sbelt(req->ctx, &qry->zone_cut); if (ret) return KR_STATE_FAIL; @@ -858,6 +859,7 @@ int cache_lmdb_peek(kr_layer_t *ctx, knot_pkt_t *pkt) //qry->flags.AWAIT_CUT = false; return ctx->state; } +#endif switch (k->type) { // FIXME xNAME: return/generate whatever is required case KNOT_RRTYPE_NS: @@ -867,12 +869,14 @@ int cache_lmdb_peek(kr_layer_t *ctx, knot_pkt_t *pkt) return ctx->state; } +#if 0 /* Now `eh` points to the closest NS record that we've found, * and that's the only place to start - we may either find * a negative proof or we may query upstream from that point. */ kr_zonecut_set(&qry->zone_cut, k->dname); ret = kr_make_query(qry, pkt); // FIXME: probably not yet - qname minimization if (ret) return KR_STATE_FAIL; +#endif /* Note: up to here we can run on any cache backend, @@ -959,9 +963,9 @@ int cache_lmdb_stash(kr_layer_t *ctx, knot_pkt_t *pkt) */ const uint32_t min_ttl = MAX(DEFAULT_MINTTL, req->ctx->cache.ttl_min); + ranked_rr_array_t *selected[] = kr_request_selected(req); for (int psec = KNOT_ANSWER; psec <= KNOT_AUTHORITY; ++psec) { - const ranked_rr_array_t *arr = psec == KNOT_ANSWER - ? &req->answ_selected : &req->auth_selected; + const ranked_rr_array_t *arr = selected[psec]; /* uncached entries are located at the end */ for (ssize_t i = arr->len - 1; i >= 0; --i) { ranked_rr_array_entry_t *entry = arr->at[i]; @@ -1217,8 +1221,16 @@ int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16 struct kr_cache_p *peek) { struct key k_storage, *k = &k_storage; + + WITH_VERBOSE { + VERBOSE_MSG(NULL, "_peek_exact: "); + kr_rrtype_print(type, "", " "); + kr_dname_print(name, "", " "); + } + int ret = knot_dname_lf(k->buf, name, NULL); if (ret) { + kr_log_verbose("ERROR!\n"); return KR_STATE_FAIL; } k->name_len = k->buf[0]; @@ -1232,10 +1244,12 @@ int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16 knot_db_val_t val = { }; ret = cache_op(cache, read, &key, &val, 1); if (ret) { + kr_log_verbose("miss\n"); return ret; } const struct entry_h *eh = entry_h_consistent(val, ktype); if (!eh || (type == KNOT_RRTYPE_NS && !eh->has_ns)) { + kr_log_verbose("miss\n"); return kr_error(ENOENT); } *peek = (struct kr_cache_p){ @@ -1245,6 +1259,7 @@ int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16 .data = val.data, .data_bound = val.data + val.len, }; + kr_log_verbose("hit\n"); return kr_ok(); } @@ -1275,11 +1290,12 @@ static const struct entry_h *closest_NS(kr_layer_t *ctx, struct key *k) if (new_ttl < 0) break; // FIXME: xNAME //uint16_t ktype = exact_match ? KNOT_RRTYPE_CNAME : KNOT_RRTYPE_DNAME; - if (eh->has_ns && !eh->is_negative) { - /* any kr_rank is accepted, as insecure or even nonauth is OK */ - k->type = KNOT_RRTYPE_NS; - return eh; + if (!eh->has_ns || eh->is_negative) { + break; } + /* any kr_rank is accepted, as insecure or even nonauth is OK */ + k->type = KNOT_RRTYPE_NS; + return eh; } case (-abs(ENOENT)): break; diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index 52e0cec90..bf1208cc9 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -178,8 +178,10 @@ static int update_nsaddr(const knot_rrset_t *rr, struct kr_query *query) } /** @internal From \a pkt, fetch glue records for name \a ns, and update the cut etc. */ -static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, struct kr_request *req) +static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, bool in_bailiwick, + struct kr_request *req, const struct kr_query *qry) { + ranked_rr_array_t *selected[] = kr_request_selected(req); for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) { const knot_pktsection_t *sec = knot_pkt_section(pkt, i); for (unsigned k = 0; k < sec->count; ++k) { @@ -191,6 +193,12 @@ static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, struct kr_reques (rr->type != KNOT_RRTYPE_AAAA)) { continue; } + + uint8_t rank = (in_bailiwick && i == KNOT_ANSWER) + ? (KR_RANK_INITIAL | KR_RANK_AUTH) : KR_RANK_OMIT; + (void) kr_ranked_rrarray_add(selected[i], rr, rank, + false, qry->uid, &req->pool); + if ((rr->type == KNOT_RRTYPE_A) && (req->ctx->options.NO_IPV4)) { continue; @@ -205,7 +213,7 @@ static void fetch_glue(knot_pkt_t *pkt, const knot_dname_t *ns, struct kr_reques } /** Attempt to find glue for given nameserver name (best effort). */ -static int has_glue(knot_pkt_t *pkt, const knot_dname_t *ns) +static bool has_glue(knot_pkt_t *pkt, const knot_dname_t *ns) { for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) { const knot_pktsection_t *sec = knot_pkt_section(pkt, i); @@ -213,11 +221,11 @@ static int has_glue(knot_pkt_t *pkt, const knot_dname_t *ns) const knot_rrset_t *rr = knot_pkt_rr(sec, k); if (knot_dname_is_equal(ns, rr->owner) && (rr->type == KNOT_RRTYPE_A || rr->type == KNOT_RRTYPE_AAAA)) { - return 1; + return true; } } } - return 0; + return false; } /** @internal Update the cut with another NS(+glue) record. @@ -267,24 +275,31 @@ static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, /* Fetch glue for each NS */ for (unsigned i = 0; i < rr->rrs.rr_count; ++i) { const knot_dname_t *ns_name = knot_ns_name(&rr->rrs, i); - int glue_records = has_glue(pkt, ns_name); /* Glue is mandatory for NS below zone */ - if (!glue_records && knot_dname_in(rr->owner, ns_name)) { - VERBOSE_MSG("<= authority: missing mandatory glue, rejecting\n"); + if (knot_dname_in(rr->owner, ns_name) && !has_glue(pkt, ns_name)) { + VERBOSE_MSG("<= authority: missing mandatory glue, skipping NS "); + WITH_VERBOSE { + kr_dname_print(ns_name, "", "\n"); + } continue; } - kr_zonecut_add(cut, ns_name, NULL); + int ret = kr_zonecut_add(cut, ns_name, NULL); + assert(!ret); + /* Choose when to use glue records. */ + bool in_bailiwick = knot_dname_in(current_cut, ns_name); + bool do_fetch; if (qry->flags.PERMISSIVE) { - fetch_glue(pkt, ns_name, req); + do_fetch = true; } else if (qry->flags.STRICT) { /* Strict mode uses only mandatory glue. */ - if (knot_dname_in(cut->name, ns_name)) - fetch_glue(pkt, ns_name, req); + do_fetch = knot_dname_in(cut->name, ns_name); } else { /* Normal mode uses in-bailiwick glue. */ - if (knot_dname_in(current_cut, ns_name)) - fetch_glue(pkt, ns_name, req); + do_fetch = in_bailiwick; + } + if (do_fetch) { + fetch_glue(pkt, ns_name, in_bailiwick, req, qry); } } diff --git a/lib/resolve.c b/lib/resolve.c index 1a506fa79..ced2cd150 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -718,6 +718,7 @@ int kr_resolve_begin(struct kr_request *request, struct kr_context *ctx, knot_pk array_init(request->additional); array_init(request->answ_selected); array_init(request->auth_selected); + array_init(request->add_selected); request->answ_validated = false; request->auth_validated = false; @@ -1419,7 +1420,11 @@ ns_election: } kr_nsrep_elect(qry, request->ctx); if (qry->ns.score > KR_NS_MAX_SCORE) { - VERBOSE_MSG(qry, "=> no valid NS left\n"); + if (!qry->zone_cut.nsset.root) { + VERBOSE_MSG(qry, "=> no NS with an address\n"); + } else { + VERBOSE_MSG(qry, "=> no valid NS left\n"); + } ITERATE_LAYERS(request, qry, reset); kr_rplan_pop(rplan, qry); return KR_STATE_PRODUCE; diff --git a/lib/resolve.h b/lib/resolve.h index 43b5f9f3d..69624c04f 100644 --- a/lib/resolve.h +++ b/lib/resolve.h @@ -194,6 +194,7 @@ struct kr_request { int state; ranked_rr_array_t answ_selected; ranked_rr_array_t auth_selected; + ranked_rr_array_t add_selected; rr_array_t additional; bool answ_validated; /**< internal to validator; beware of caching, etc. */ bool auth_validated; /**< see answ_validated ^^ ; TODO */ @@ -202,6 +203,13 @@ struct kr_request { knot_mm_t pool; }; +/** Initializer for an array of *_selected. */ +#define kr_request_selected(req) { \ + [KNOT_ANSWER] = &(req)->answ_selected, \ + [KNOT_AUTHORITY] = &(req)->auth_selected, \ + [KNOT_ADDITIONAL] = &(req)->add_selected, \ + } + /** * Begin name resolution. *