From: Vladimír Čunát Date: Mon, 12 Jun 2017 13:40:02 +0000 (+0200) Subject: iterate: be more precise when detecting CNAME loops X-Git-Tag: v1.3.0~1^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac92745d611d11f4eed12ae278eb90cf3cc422c8;p=thirdparty%2Fknot-resolver.git iterate: be more precise when detecting CNAME loops 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. --- diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index a3152f813..ef853df0b 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -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"); diff --git a/lib/rplan.h b/lib/rplan.h index 8dcf83287..e66e4348e 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -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; };