2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

Return SERVFAIL for a too long CNAME chain

Due to the maximum query restart limitation a long CNAME chain
it is cut after 16 queries but named still returns NOERROR.

Return SERVFAIL instead and the partial answer.
This commit is contained in:
Aram Sargsyan 2024-06-06 12:06:59 +00:00
parent 40f392c124
commit b621f1d88e

View File

@ -11546,7 +11546,7 @@ isc_result_t
ns_query_done(query_ctx_t *qctx) {
isc_result_t result = ISC_R_UNSET;
const dns_namelist_t *secs = qctx->client->message->sections;
bool nodetach;
bool nodetach, partial_result_with_servfail = false;
CCTRACE(ISC_LOG_DEBUG(3), "ns_query_done");
@ -11580,21 +11580,44 @@ ns_query_done(query_ctx_t *qctx) {
/*
* Do we need to restart the query (e.g. for CNAME chaining)?
*/
if (qctx->want_restart && qctx->client->query.restarts < MAX_RESTARTS) {
query_ctx_t *saved_qctx = NULL;
qctx->client->query.restarts++;
saved_qctx = isc_mem_get(qctx->client->manager->mctx,
sizeof(*saved_qctx));
qctx_save(qctx, saved_qctx);
isc_nmhandle_attach(qctx->client->handle,
&qctx->client->restarthandle);
isc_async_run(qctx->client->manager->loop, async_restart,
saved_qctx);
return (DNS_R_CONTINUE);
if (qctx->want_restart) {
if (qctx->client->query.restarts < MAX_RESTARTS) {
query_ctx_t *saved_qctx = NULL;
qctx->client->query.restarts++;
saved_qctx = isc_mem_get(qctx->client->manager->mctx,
sizeof(*saved_qctx));
qctx_save(qctx, saved_qctx);
isc_nmhandle_attach(qctx->client->handle,
&qctx->client->restarthandle);
isc_async_run(qctx->client->manager->loop,
async_restart, saved_qctx);
return (DNS_R_CONTINUE);
} else {
/*
* This is e.g. a long CNAME chain which we cut short.
*/
qctx->client->query.attributes |=
NS_QUERYATTR_PARTIALANSWER;
qctx->client->message->rcode = dns_rcode_servfail;
qctx->result = DNS_R_SERVFAIL;
/*
* Send the answer back with a SERVFAIL result even
* if recursion was requested.
*/
partial_result_with_servfail = true;
ns_client_extendederror(qctx->client, 0,
"max. restarts reached");
ns_client_log(qctx->client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_QUERY, ISC_LOG_INFO,
"query iterations limit reached");
}
}
if (qctx->result != ISC_R_SUCCESS &&
(!PARTIALANSWER(qctx->client) || WANTRECURSION(qctx->client) ||
(!PARTIALANSWER(qctx->client) ||
(WANTRECURSION(qctx->client) && !partial_result_with_servfail) ||
qctx->result == DNS_R_DROP))
{
if (qctx->result == DNS_R_DUPLICATE ||