From: Marek Vavrusa Date: Tue, 23 Aug 2016 02:56:11 +0000 (-0700) Subject: lib/resolve: fixed pass through for stub mode X-Git-Tag: v1.1.1~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aecffe74ee5e8b73d8a23c83c66f6d6d05a5624f;p=thirdparty%2Fknot-resolver.git lib/resolve: fixed pass through for stub mode REFUSED response no longer causes retry in iterator when operating in stub mode --- diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index 194111307..9e3523f81 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -396,14 +396,14 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req) const knot_dname_t *pending_cname = query->sname; unsigned cname_chain_len = 0; bool can_follow = false; - bool strict_mode = (query->flags & QUERY_STRICT); + bool strict_mode = (query->flags & QUERY_STRICT) && !(query->flags & QUERY_STUB); do { /* CNAME was found at previous iteration, but records may not follow the correct order. * Try to find records for pending_cname owner from section start. */ cname = pending_cname; pending_cname = NULL; /* If not secure, always follow cname chain. */ - can_follow = !(query->flags & QUERY_DNSSEC_WANT); + can_follow = !(query->flags & QUERY_DNSSEC_WANT) || (query->flags & QUERY_STUB); for (unsigned i = 0; i < an->count; ++i) { const knot_rrset_t *rr = knot_pkt_rr(an, i); if (!knot_dname_is_equal(rr->owner, cname)) { @@ -629,6 +629,7 @@ static int resolve(knot_layer_t *ctx, knot_pkt_t *pkt) case KNOT_RCODE_REFUSED: case KNOT_RCODE_SERVFAIL: { DEBUG_MSG("<= rcode: %s\n", rcode ? rcode->name : "??"); + if (query->flags & QUERY_STUB) { break; } /* Pass through in stub mode */ query->fails += 1; if (query->fails >= KR_QUERY_NSRETRY_LIMIT) { query->fails = 0; /* Reset per-query counter. */ diff --git a/lib/resolve.c b/lib/resolve.c index 235c066d4..99343d5dc 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -773,6 +773,7 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t 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)) { @@ -781,11 +782,13 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t } /* Update zone cut, spawn new subrequests. */ - int state = zone_cut_check(request, qry, packet); - switch(state) { - case KNOT_STATE_FAIL: return KNOT_STATE_FAIL; - case KNOT_STATE_DONE: return KNOT_STATE_PRODUCE; - default: break; + if (!(qry->flags & QUERY_STUB)) { + int state = zone_cut_check(request, qry, packet); + switch(state) { + case KNOT_STATE_FAIL: return KNOT_STATE_FAIL; + case KNOT_STATE_DONE: return KNOT_STATE_PRODUCE; + default: break; + } } ns_election: @@ -799,9 +802,10 @@ ns_election: return KNOT_STATE_FAIL; } + const bool retry = (qry->flags & (QUERY_TCP|QUERY_STUB|QUERY_BADCOOKIE_AGAIN)); if (qry->flags & (QUERY_AWAIT_IPV4|QUERY_AWAIT_IPV6)) { kr_nsrep_elect_addr(qry, request->ctx); - } else if (!qry->ns.name || !(qry->flags & (QUERY_TCP|QUERY_STUB|QUERY_BADCOOKIE_AGAIN))) { /* Keep NS when requerying/stub/badcookie. */ + } else if (!qry->ns.name || !retry) { /* Keep NS when requerying/stub/badcookie. */ /* Root DNSKEY must be fetched from the hints to avoid chicken and egg problem. */ if (qry->sname[0] == '\0' && qry->stype == KNOT_RRTYPE_DNSKEY) { kr_zonecut_set_sbelt(request->ctx, &qry->zone_cut);