From: Mark Andrews Date: Mon, 1 Mar 2021 16:46:07 +1100 Subject: 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_find() so that it handles this case properly. The rdataset is freed later anyway, so there is no need to clean it up immediately. --- bin/named/query.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bin/named/query.c b/bin/named/query.c index f8dbef2..b674b67 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -9087,10 +9087,17 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (noqname != NULL) query_addnoqnameproof(client, noqname); /* - * We shouldn't ever fail to add 'rdataset' - * because it's already in the answer. + * '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 + * '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, 'rdataset' will be freed later, so we + * do not need to free it here. */ - INSIST(rdataset == NULL); + INSIST(rdataset == NULL || qtype == dns_rdatatype_dname); } addauth: