]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/resolve: fixed good cached ns expired, only bad remain
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 10 May 2015 19:38:00 +0000 (21:38 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 10 May 2015 19:38:00 +0000 (21:38 +0200)
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

lib/layer/iterate.c
lib/resolve.c
lib/rplan.c

index fbe45bfc32e7e905c07a8b19f62e00cd8e74fe90..11cd46638ba2199f472f237d4ad86a1387e33b90 100644 (file)
@@ -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);
index 8dbc0c6edf394be1373ef6daab529a7691a3c19c..23d4744408cb142e77b279ae83c521066e04738b 100644 (file)
@@ -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);
index c02e61a4f8ffb05ca21501cd9a105fd0d2ffcdc7..d98b6e5bcb55124bd9f968e0198d33d6d90aa747 100644 (file)
@@ -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];