From: Marek VavruĊĦa Date: Sun, 10 May 2015 19:38:00 +0000 (+0200) Subject: lib/resolve: fixed good cached ns expired, only bad remain X-Git-Tag: v1.0.0-beta1~185 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a2406b5f0878199f0042bc86d41a8184516539d8;p=thirdparty%2Fknot-resolver.git lib/resolve: fixed good cached ns expired, only bad remain the resolution has to start from the root for zonecut resolution, otherwise it might stall resolution if the only good NS drops out of cache and only the bad remain --- diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index fbe45bfc3..11cd46638 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -307,7 +307,8 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req) /* Follow canonical name as next SNAME. */ if (cname != query->sname) { DEBUG_MSG("<= cname chain, following\n"); - (void) kr_rplan_push(&req->rplan, query->parent, cname, query->sclass, query->stype); + struct kr_query *next = kr_rplan_push(&req->rplan, query->parent, cname, query->sclass, query->stype); + kr_zonecut_set_sbelt(&next->zone_cut); } else { if (query->parent == NULL) { finalize_answer(pkt, query, req); diff --git a/lib/resolve.c b/lib/resolve.c index 8dbc0c6ed..23d474440 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -49,8 +49,14 @@ static int ns_resolve_addr(struct kr_query *qry, struct kr_request *param) return KNOT_STATE_PRODUCE; } - (void) kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_AAAA); - (void) kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_A); + /* Start NS queries from root, to avoid certain cases + * where a NS drops out of cache and the rest is unavailable, + * this would lead to dependency loop in current zone cut. + */ + struct kr_query *next = kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_AAAA); + kr_zonecut_set_sbelt(&next->zone_cut); + next = kr_rplan_push(rplan, qry, qry->ns.name, KNOT_CLASS_IN, KNOT_RRTYPE_A); + kr_zonecut_set_sbelt(&next->zone_cut); qry->flags |= QUERY_AWAIT_ADDR; return KNOT_STATE_PRODUCE; } @@ -279,6 +285,15 @@ int kr_resolve_query(struct kr_request *request, const knot_dname_t *qname, uint return KNOT_STATE_FAIL; } + /* Find closest zone cut for this query. */ + namedb_txn_t txn; + if (kr_cache_txn_begin(rplan->context->cache, &txn, NAMEDB_RDONLY) != 0) { + kr_zonecut_set_sbelt(&qry->zone_cut); + } else { + kr_zonecut_find_cached(&qry->zone_cut, &txn, qry->timestamp.tv_sec); + kr_cache_txn_abort(&txn); + } + /* Initialize answer packet */ knot_pkt_t *answer = request->answer; knot_wire_set_qr(answer->wire); diff --git a/lib/rplan.c b/lib/rplan.c index c02e61a4f..d98b6e5bc 100644 --- a/lib/rplan.c +++ b/lib/rplan.c @@ -112,16 +112,7 @@ struct kr_query *kr_rplan_push(struct kr_rplan *rplan, struct kr_query *parent, qry->parent = parent; gettimeofday(&qry->timestamp, NULL); add_tail(&rplan->pending, &qry->node); - - /* Find closest zone cut for this query. */ - namedb_txn_t txn; kr_zonecut_init(&qry->zone_cut, name, rplan->pool); - if (kr_cache_txn_begin(rplan->context->cache, &txn, NAMEDB_RDONLY) != 0) { - kr_zonecut_set_sbelt(&qry->zone_cut); - } else { - kr_zonecut_find_cached(&qry->zone_cut, &txn, qry->timestamp.tv_sec); - kr_cache_txn_abort(&txn); - } #ifndef NDEBUG char name_str[KNOT_DNAME_MAXLEN], type_str[16];