]> 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>
Mon, 12 Apr 2021 10:10:12 +0000 (12:10 +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 791101228667195f4ce387f0d7634348ae33026a..65d582f4cffad71c5b95ef7cd1a24ef02bd7995d 100644 (file)
@@ -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);