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.
}
}
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");
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;
};