]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Handle DNAME lookup via itself
authorMark Andrews <marka@isc.org>
Mon, 1 Mar 2021 05:46:07 +0000 (16:46 +1100)
committerMichał Kępień <michal@isc.org>
Thu, 29 Apr 2021 09:12:38 +0000 (11:12 +0200)
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().

lib/ns/query.c

index 48e2184b44d2f3912803add17b6bfb844743aba0..fc000f5799478fe8c0dec11b3804c7963dd2c4bb 100644 (file)
@@ -7882,10 +7882,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);