From: Mark Andrews Date: Mon, 1 Mar 2021 05:46:07 +0000 (+1100) Subject: Handle DNAME lookup via itself X-Git-Tag: v9.17.12~3^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c3d8191bb1dde2522b946c66785fbfad1dde061;p=thirdparty%2Fbind9.git Handle DNAME lookup via itself When answering a query, named should never attempt to add the same RRset to the ANSWER section more than once. However, such a situation may arise when chasing DNAME records: one of the DNAME records placed in the ANSWER section may turn out to be the final answer to a client query, but there is no way to know that in advance. Tweak the relevant INSIST assertion in query_respond() so that it handles this case properly. qctx->rdataset is freed later anyway, so there is no need to clean it up in query_respond(). --- diff --git a/lib/ns/query.c b/lib/ns/query.c index 79110122866..65d582f4cff 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -8176,10 +8176,16 @@ query_respond(query_ctx_t *qctx) { query_addnoqnameproof(qctx); /* - * We shouldn't ever fail to add 'rdataset' - * because it's already in the answer. - */ - INSIST(qctx->rdataset == NULL); + * 'qctx->rdataset' will only be non-NULL here if the ANSWER section of + * the message to be sent to the client already contains an RRset with + * the same owner name and the same type as 'qctx->rdataset'. This + * should never happen, with one exception: when chasing DNAME records, + * one of the DNAME records placed in the ANSWER section may turn out + * to be the final answer to the client's query, but we have no way of + * knowing that until now. In such a case, 'qctx->rdataset' will be + * freed later, so we do not need to free it here. + */ + INSIST(qctx->rdataset == NULL || qctx->qtype == dns_rdatatype_dname); query_addauth(qctx);