]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
iterate: be more precise when detecting CNAME loops
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 12 Jun 2017 13:40:02 +0000 (15:40 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 12 Jun 2017 14:11:35 +0000 (16:11 +0200)
Iterating over sibling sub-queries isn't precise enough,
and in particular in forwarding mode it reported non-existing loops.

Example ATM: www.dpo.cz - there forwarding spawns multiple sub-queries,
and one of those is a CNAME to another of them.  Due to them being siblings,
the old code misdetected that as a CNAME loop.  Now that we have these
cname_parent pointers, we can do a precise detection.

lib/layer/iterate.c
lib/rplan.h

index a3152f813685bccee79b99d54b308a6546c09ef0..ef853df0b8ae4e4132abcee41bc06148f798bcc7 100644 (file)
@@ -637,11 +637,10 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
                        }
                }
                VERBOSE_MSG("<= cname chain, following\n");
-               /* Check if the same query was already resolved */
-               for (int i = 0; i < req->rplan.resolved.len; ++i) {
-                       struct kr_query *q = req->rplan.resolved.at[i];
-                       if (q->parent == query->parent &&
-                           q->sclass == query->sclass &&
+               /* Check if the same query was followed in the same CNAME chain. */
+               for (const struct kr_query *q = query->cname_parent; q != NULL;
+                               q = q->cname_parent) {
+                       if (q->sclass == query->sclass &&
                            q->stype == query->stype   &&
                            knot_dname_is_equal(q->sname, cname)) {
                                VERBOSE_MSG("<= cname chain loop\n");
index 8dcf8328777f36cb40d3ee8c76233a4fbe9cabd0..e66e4348e19f102f1ea74a5b966ecc5b3cc52052 100644 (file)
@@ -90,6 +90,7 @@ struct kr_query {
        struct kr_layer_pickle *deferred;
        uint32_t uid; /**< Query iteration number, unique within the kr_rplan. */
        uint32_t forward_flags;
+       /** Pointer to the query that originated this one because of following a CNAME (or NULL). */
        struct kr_query *cname_parent;
 };