]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add synthesis of NODATA at wildcard
authorMark Andrews <marka@isc.org>
Fri, 26 Nov 2021 23:41:38 +0000 (10:41 +1100)
committerPetr Špaček <pspacek@isc.org>
Thu, 2 Dec 2021 13:24:37 +0000 (14:24 +0100)
The old code rejected NSEC that proved the wildcard name existed
(exists).  The new code rejects NSEC that prove that the wildcard
name exists and that the type exists (exists && data) but accept
NSEC that prove the wildcard name exists.

query_synthnxdomain (renamed query_synthnxdomainnodata) already
took the NSEC records and added the correct records to the message
body for NXDOMAIN or NODATA responses with the above change.  The
only additional change needed was to ensure the correct RCODE is
set.

lib/ns/query.c

index ce88b2df51cbd986dae9f653f6c3f57528fc1111..c1242d004e7c26d20e145882552631ad88f6125d 100644 (file)
@@ -9856,17 +9856,18 @@ query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset,
 }
 
 /*
- * Synthesize a NXDOMAIN response from qctx (which contains the
- * NODATA proof), nowild + nowildrdataset + signowildrdataset (which
- * contains the NOWILDCARD proof) and signer + soardatasetp + sigsoardatasetp
- * which contain the SOA record + RRSIG for the negative answer.
+ * Synthesize a NXDOMAIN or NODATA response from qctx (which contains the
+ * NOQNAME proof), nowild + nowildrdataset + signowildrdataset (which
+ * contains the NOWILDCARD proof or NODATA at wildcard) and
+ * signer + soardatasetp + sigsoardatasetp which contain the
+ * SOA record + RRSIG for the negative answer.
  */
 static isc_result_t
-query_synthnxdomain(query_ctx_t *qctx, dns_name_t *nowild,
-                   dns_rdataset_t *nowildrdataset,
-                   dns_rdataset_t *signowildrdataset, dns_name_t *signer,
-                   dns_rdataset_t **soardatasetp,
-                   dns_rdataset_t **sigsoardatasetp) {
+query_synthnxdomainnodata(query_ctx_t *qctx, bool nodata, dns_name_t *nowild,
+                         dns_rdataset_t *nowildrdataset,
+                         dns_rdataset_t *signowildrdataset, dns_name_t *signer,
+                         dns_rdataset_t **soardatasetp,
+                         dns_rdataset_t **sigsoardatasetp) {
        dns_name_t *name = NULL;
        dns_ttl_t ttl;
        isc_buffer_t *dbuf, b;
@@ -9954,9 +9955,13 @@ query_synthnxdomain(query_ctx_t *qctx, dns_name_t *nowild,
                               DNS_SECTION_AUTHORITY);
        }
 
-       qctx->client->message->rcode = dns_rcode_nxdomain;
+       if (nodata) {
+               inc_stats(qctx->client, ns_statscounter_nodatasynth);
+       } else {
+               qctx->client->message->rcode = dns_rcode_nxdomain;
+               inc_stats(qctx->client, ns_statscounter_nxdomainsynth);
+       }
        result = ISC_R_SUCCESS;
-       inc_stats(qctx->client, ns_statscounter_nxdomainsynth);
 
 cleanup:
        if (name != NULL) {
@@ -10176,7 +10181,7 @@ query_coveringnsec(query_ctx_t *qctx) {
                result = dns_nsec_noexistnodata(qctx->qtype, wild, nowild,
                                                &rdataset, &exists, &data, NULL,
                                                log_noexistnodata, qctx);
-               if (result != ISC_R_SUCCESS || exists) {
+               if (result != ISC_R_SUCCESS || (exists && data)) {
                        goto cleanup;
                }
                break;
@@ -10240,9 +10245,9 @@ query_coveringnsec(query_ctx_t *qctx) {
        if (result != ISC_R_SUCCESS) {
                goto cleanup;
        }
-
-       (void)query_synthnxdomain(qctx, nowild, &rdataset, &sigrdataset, signer,
-                                 &soardataset, &sigsoardataset);
+       (void)query_synthnxdomainnodata(qctx, exists, nowild, &rdataset,
+                                       &sigrdataset, signer, &soardataset,
+                                       &sigsoardataset);
        done = true;
 
 cleanup: