diff --git a/src/knot/nameserver/internet.c b/src/knot/nameserver/internet.c index 472291d6a9c1f19b58becdaa1c01b05fed27f2ab..1e08f82af9d455bdb757c922ee7e558de24730f6 100644 --- a/src/knot/nameserver/internet.c +++ b/src/knot/nameserver/internet.c @@ -39,6 +39,11 @@ static int wildcard_visit(struct query_data *qdata, const knot_node_t *node, con assert(qdata); assert(node); + /* Already in the list. */ + if (wildcard_has_visited(qdata, node)) { + return KNOT_EOK; + } + mm_ctx_t *mm = qdata->mm; struct wildcard_hit *item = mm->alloc(mm->ctx, sizeof(struct wildcard_hit)); item->node = node; @@ -439,12 +444,15 @@ static int name_not_found(knot_pkt_t *pkt, struct query_data *qdata) /* keep encloser */ qdata->previous = NULL; + /* Follow expanded wildcard. */ + int next_state = name_found(pkt, qdata); + /* Put to wildcard node list. */ - if (wildcard_visit(qdata, qdata->encloser, qdata->name) != KNOT_EOK) { - return ERROR; + if (wildcard_visit(qdata, wildcard_node, qdata->name) != KNOT_EOK) { + next_state = ERROR; } - return name_found(pkt, qdata); + return next_state; } /* Name is under DNAME, use it for substitution. */ @@ -501,11 +509,6 @@ static int solve_answer_section(int state, knot_pkt_t *pkt, struct query_data *q /* Additional resolving for CNAME/DNAME chain. */ while (state == FOLLOW) { state = solve_name(state, pkt, qdata); - /* Chain lead to NXDOMAIN, this is okay since - * the first CNAME/DNAME is a valid answer. */ - if (state == MISS) { - state = HIT; - } } return state;