{
const knot_dname_t *cname = NULL;
int state = unroll_cname(pkt, req, true, &cname);
+ struct kr_query *query = req->current_query;
if (state != kr_ok()) {
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_BAD_CNAME);
return KR_STATE_FAIL;
}
- struct kr_query *query = req->current_query;
if (!(query->flags.CACHED)) {
/* If not cached (i.e. got from upstream)
* make sure that this is not an authoritative answer
/* Process answer type */
int state = unroll_cname(pkt, req, false, &cname);
if (state != kr_ok()) {
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_BAD_CNAME);
return state;
}
/* Make sure that this is an authoritative answer (even with AA=0) for other layers */
q->stype == query->stype &&
knot_dname_is_equal(q->sname, cname)) {
VERBOSE_MSG("<= cname chain loop\n");
+ query->server_selection.error(query, req->upstream.transport, KR_SELECTION_BAD_CNAME);
return KR_STATE_FAIL;
}
}
}
}
+ if (request->state & KR_STATE_FAIL) {
+ qry->flags.RESOLVED = false;
+ }
+
/* Pop query if resolved. */
if (request->state == KR_STATE_YIELD) {
return KR_STATE_PRODUCE; /* Requery */
KR_SELECTION_FORMERROR,
KR_SELECTION_NOTIMPL,
KR_SELECTION_OTHER_RCODE,
- KR_SELECTION_TRUNCATED,
// DNS errors
+ KR_SELECTION_TRUNCATED,
KR_SELECTION_DNSSEC_ERROR,
KR_SELECTION_LAME_DELEGATION,
+ KR_SELECTION_BAD_CNAME, /**< Too long chain, or cycle. */
KR_SELECTION_NUMBER_OF_ERRORS /**< Leave this last, as it is used as array size. */
};
[KR_SELECTION_TRUNCATED] = false,
[KR_SELECTION_DNSSEC_ERROR] = true,
[KR_SELECTION_LAME_DELEGATION] = true,
+ [KR_SELECTION_BAD_CNAME] = true,
};
enum kr_transport_protocol {