]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
move application of dns64 to a separate function
authorEvan Hunt <each@isc.org>
Sun, 23 Mar 2025 20:45:04 +0000 (13:45 -0700)
committerEvan Hunt <each@isc.org>
Wed, 26 Mar 2025 23:30:38 +0000 (23:30 +0000)
the code in query_dns64() that applies the dns64 prefixes to
an A rdataset has been moved into the dns_dns64 module, and
dns_dns64_destroy() now unlinks the dns64 object from its
containing list. with these changes, we no longer need the
list-manipulation API calls dns_dns64_next() and
dns_dns64_unlink().

lib/dns/dns64.c
lib/dns/include/dns/dns64.h
lib/dns/view.c
lib/ns/query.c

index b5332fd42b5113f58e9a4a97a9d28b8203740fc6..a1fbf25084992cadd56725ecf6f28650b054154a 100644 (file)
@@ -24,6 +24,7 @@
 #include <dns/acl.h>
 #include <dns/dns64.h>
 #include <dns/rdata.h>
+#include <dns/rdatalist.h>
 #include <dns/rdataset.h>
 
 struct dns_dns64 {
@@ -103,7 +104,7 @@ dns_dns64_create(isc_mem_t *mctx, const isc_netaddr_t *prefix,
 }
 
 void
-dns_dns64_destroy(dns_dns64_t **dns64p) {
+dns_dns64_destroy(dns_dns64list_t *list, dns_dns64_t **dns64p) {
        dns_dns64_t *dns64;
 
        REQUIRE(dns64p != NULL && *dns64p != NULL);
@@ -111,7 +112,7 @@ dns_dns64_destroy(dns_dns64_t **dns64p) {
        dns64 = *dns64p;
        *dns64p = NULL;
 
-       REQUIRE(!ISC_LINK_LINKED(dns64, link));
+       ISC_LIST_UNLINK(*list, dns64, link);
 
        if (dns64->clients != NULL) {
                dns_acl_detach(&dns64->clients);
@@ -193,22 +194,11 @@ dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
        return ISC_R_SUCCESS;
 }
 
-dns_dns64_t *
-dns_dns64_next(dns_dns64_t *dns64) {
-       dns64 = ISC_LIST_NEXT(dns64, link);
-       return dns64;
-}
-
 void
 dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64) {
        ISC_LIST_APPEND(*list, dns64, link);
 }
 
-void
-dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64) {
-       ISC_LIST_UNLINK(*list, dns64, link);
-}
-
 bool
 dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
                 const dns_name_t *reqsigner, dns_aclenv_t *env,
@@ -481,3 +471,76 @@ dns_dns64_findprefix(dns_rdataset_t *rdataset, isc_netprefix_t *prefix,
        *len = count;
        return ISC_R_SUCCESS;
 }
+
+isc_result_t
+dns_dns64_apply(isc_mem_t *mctx, dns_dns64list_t dns64s, unsigned int count,
+               dns_message_t *message, dns_aclenv_t *env, isc_sockaddr_t *peer,
+               dns_name_t *reqsigner, unsigned int flags, dns_rdataset_t *a,
+               dns_rdataset_t **aaaap) {
+       isc_result_t result;
+       dns_rdatalist_t *aaaalist = NULL;
+       isc_buffer_t *buffer = NULL;
+       isc_netaddr_t netaddr;
+
+       REQUIRE(aaaap != NULL && *aaaap == NULL);
+       REQUIRE(a->type == dns_rdatatype_a);
+
+       isc_netaddr_fromsockaddr(&netaddr, peer);
+
+       isc_buffer_allocate(mctx, &buffer, count * 16 * dns_rdataset_count(a));
+
+       dns_message_gettemprdatalist(message, &aaaalist);
+       aaaalist->rdclass = dns_rdataclass_in;
+       aaaalist->type = dns_rdatatype_aaaa;
+
+       for (result = dns_rdataset_first(a); result == ISC_R_SUCCESS;
+            result = dns_rdataset_next(a))
+       {
+               for (dns_dns64_t *dns64 = ISC_LIST_HEAD(dns64s); dns64 != NULL;
+                    dns64 = ISC_LIST_NEXT(dns64, link))
+               {
+                       dns_rdata_t rdata = DNS_RDATA_INIT;
+                       dns_rdata_t *dns64_rdata = NULL;
+                       isc_region_t r;
+
+                       dns_rdataset_current(a, &rdata);
+                       isc_buffer_availableregion(buffer, &r);
+                       INSIST(r.length >= 16);
+                       result = dns_dns64_aaaafroma(dns64, &netaddr, reqsigner,
+                                                    env, flags, rdata.data,
+                                                    r.base);
+                       if (result != ISC_R_SUCCESS) {
+                               continue;
+                       }
+                       isc_buffer_add(buffer, 16);
+                       isc_buffer_remainingregion(buffer, &r);
+                       isc_buffer_forward(buffer, 16);
+                       dns_message_gettemprdata(message, &dns64_rdata);
+                       dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
+                                            dns_rdatatype_aaaa, &r);
+                       ISC_LIST_APPEND(aaaalist->rdata, dns64_rdata, link);
+               }
+       }
+
+       if (!ISC_LIST_EMPTY(aaaalist->rdata)) {
+               dns_rdataset_t *aaaa = NULL;
+               dns_message_gettemprdataset(message, &aaaa);
+               dns_rdatalist_tordataset(aaaalist, aaaa);
+               dns_message_takebuffer(message, &buffer);
+               aaaa->trust = a->trust;
+               *aaaap = aaaa;
+               return ISC_R_SUCCESS;
+       }
+
+       /* No applicable dns64; free the resources */
+       isc_buffer_free(&buffer);
+       for (dns_rdata_t *rdata = ISC_LIST_HEAD(aaaalist->rdata); rdata != NULL;
+            rdata = ISC_LIST_HEAD(aaaalist->rdata))
+       {
+               ISC_LIST_UNLINK(aaaalist->rdata, rdata, link);
+               dns_message_puttemprdata(message, &rdata);
+       }
+       dns_message_puttemprdatalist(message, &aaaalist);
+
+       return ISC_R_NOMORE;
+}
index 22331bb6dca3a6fb6a049534a03990ffd6e4a8a3..fbbd0d02fe0da2b885eff7bf14156588afe32305 100644 (file)
@@ -82,11 +82,9 @@ dns_dns64_create(isc_mem_t *mctx, const isc_netaddr_t *prefix,
  */
 
 void
-dns_dns64_destroy(dns_dns64_t **dns64p);
+dns_dns64_destroy(dns_dns64list_t *list, dns_dns64_t **dns64p);
 /*
- * Destroys a dns64 record.
- *
- * Requires the record to not be linked.
+ * Unlinks a dns64 record from list, then destroys it.
  */
 
 isc_result_t
@@ -121,24 +119,12 @@ dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
  *     DNS_R_DISALLOWED        if there is no match.
  */
 
-dns_dns64_t *
-dns_dns64_next(dns_dns64_t *dns64);
-/*
- * Return the next dns64 record in the list.
- */
-
 void
 dns_dns64_append(dns_dns64list_t *list, dns_dns64_t *dns64);
 /*
  * Append the dns64 record to the list.
  */
 
-void
-dns_dns64_unlink(dns_dns64list_t *list, dns_dns64_t *dns64);
-/*
- * Unlink the dns64 record from the list.
- */
-
 bool
 dns_dns64_aaaaok(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
                 const dns_name_t *reqsigner, dns_aclenv_t *env,
@@ -182,3 +168,19 @@ dns_dns64_findprefix(dns_rdataset_t *rdataset, isc_netprefix_t *prefix,
  *                     into 'prefix'.
  *     ISC_R_NOTFOUND  no prefixes where found.
  */
+
+isc_result_t
+dns_dns64_apply(isc_mem_t *mctx, dns_dns64list_t dns64s, unsigned int count,
+               dns_message_t *message, dns_aclenv_t *env, isc_sockaddr_t *peer,
+               dns_name_t *reqsigner, unsigned int flags, dns_rdataset_t *a,
+               dns_rdataset_t **aaaap);
+/*
+ * Apply a list of 'count' dns64 prefixes in the list 'dns64s'
+ * to an 'a' rdataset, based 'peer', 'reqsigner', 'env', and 'flags'.
+ * If synthesis is performed then return an AAAA rdataset in '*aaaap'.
+ *
+ * Returns:
+ *     ISC_R_SUCCESS
+ *     ISC_R_NOMORE    The list was fully iterated and no
+ *                     dns64 conversions were applied
+ */
index 963d862723e71a74f93582628e47b133d7ad2a32..5fcd86967be2a2bf4615ea75a94ecd9cc6bfc6e4 100644 (file)
@@ -326,8 +326,7 @@ destroy(dns_view_t *view) {
        for (dns64 = ISC_LIST_HEAD(view->dns64); dns64 != NULL;
             dns64 = ISC_LIST_HEAD(view->dns64))
        {
-               dns_dns64_unlink(&view->dns64, dns64);
-               dns_dns64_destroy(&dns64);
+               dns_dns64_destroy(&view->dns64, &dns64);
        }
        if (view->managed_keys != NULL) {
                dns_zone_detach(&view->managed_keys);
index 23f3d11cf47428f358b3360fe298ca51eaa88adc..d892f96b491a29499d1b74f97834c51b0d224dc0 100644 (file)
@@ -8182,22 +8182,14 @@ cleanup:
 
 static isc_result_t
 query_dns64(query_ctx_t *qctx) {
-       ns_client_t *client = qctx->client;
-       dns_aclenv_t *env = client->manager->aclenv;
-       dns_name_t *name, *mname;
-       dns_rdata_t *dns64_rdata;
-       dns_rdata_t rdata = DNS_RDATA_INIT;
-       dns_rdatalist_t *dns64_rdatalist;
-       dns_rdataset_t *dns64_rdataset;
-       dns_rdataset_t *mrdataset;
-       isc_buffer_t *buffer;
-       isc_region_t r;
        isc_result_t result;
+       ns_client_t *client = qctx->client;
+       dns_name_t *name = NULL, *mname = NULL;
+       dns_rdataset_t *mrdataset = NULL;
+       dns_rdataset_t *dns64_rdataset = NULL;
        dns_view_t *view = client->view;
-       isc_netaddr_t netaddr;
-       dns_dns64_t *dns64;
-       unsigned int flags = 0;
        const dns_section_t section = DNS_SECTION_ANSWER;
+       unsigned int flags = 0;
 
        /*%
         * To the current response for 'qctx->client', add the answer RRset
@@ -8215,12 +8207,6 @@ query_dns64(query_ctx_t *qctx) {
        qctx->qtype = qctx->type = dns_rdatatype_aaaa;
 
        name = qctx->fname;
-       mname = NULL;
-       mrdataset = NULL;
-       buffer = NULL;
-       dns64_rdata = NULL;
-       dns64_rdataset = NULL;
-       dns64_rdatalist = NULL;
        result = dns_message_findname(
                client->message, section, name, dns_rdatatype_aaaa,
                qctx->rdataset->covers, &mname, &mrdataset);
@@ -8256,27 +8242,6 @@ query_dns64(query_ctx_t *qctx) {
                client->query.attributes &= ~NS_QUERYATTR_SECURE;
        }
 
-       isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
-
-       isc_buffer_allocate(client->manager->mctx, &buffer,
-                           view->dns64cnt * 16 *
-                                   dns_rdataset_count(qctx->rdataset));
-       dns_message_gettemprdataset(client->message, &dns64_rdataset);
-       dns_message_gettemprdatalist(client->message, &dns64_rdatalist);
-
-       dns64_rdatalist->rdclass = dns_rdataclass_in;
-       dns64_rdatalist->type = dns_rdatatype_aaaa;
-       if (client->query.dns64_ttl != UINT32_MAX) {
-               dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl,
-                                              client->query.dns64_ttl);
-       } else {
-               dns64_rdatalist->ttl = ISC_MIN(qctx->rdataset->ttl, 600);
-       }
-
-       if (RECURSIONOK(client)) {
-               flags |= DNS_DNS64_RECURSIVE;
-       }
-
        /*
         * We use the signatures from the A lookup to set DNS_DNS64_DNSSEC
         * as this provides a easy way to see if the answer was signed.
@@ -8287,77 +8252,35 @@ query_dns64(query_ctx_t *qctx) {
                flags |= DNS_DNS64_DNSSEC;
        }
 
-       for (result = dns_rdataset_first(qctx->rdataset);
-            result == ISC_R_SUCCESS;
-            result = dns_rdataset_next(qctx->rdataset))
-       {
-               for (dns64 = ISC_LIST_HEAD(client->view->dns64); dns64 != NULL;
-                    dns64 = dns_dns64_next(dns64))
-               {
-                       dns_rdataset_current(qctx->rdataset, &rdata);
-                       isc_buffer_availableregion(buffer, &r);
-                       INSIST(r.length >= 16);
-                       result = dns_dns64_aaaafroma(dns64, &netaddr,
-                                                    client->signer, env, flags,
-                                                    rdata.data, r.base);
-                       if (result != ISC_R_SUCCESS) {
-                               dns_rdata_reset(&rdata);
-                               continue;
-                       }
-                       isc_buffer_add(buffer, 16);
-                       isc_buffer_remainingregion(buffer, &r);
-                       isc_buffer_forward(buffer, 16);
-                       dns_message_gettemprdata(client->message, &dns64_rdata);
-                       dns_rdata_fromregion(dns64_rdata, dns_rdataclass_in,
-                                            dns_rdatatype_aaaa, &r);
-                       ISC_LIST_APPEND(dns64_rdatalist->rdata, dns64_rdata,
-                                       link);
-                       dns64_rdata = NULL;
-                       dns_rdata_reset(&rdata);
-               }
-       }
-       if (result != ISC_R_NOMORE) {
-               goto cleanup;
+       if (RECURSIONOK(client)) {
+               flags |= DNS_DNS64_RECURSIVE;
        }
 
-       if (ISC_LIST_EMPTY(dns64_rdatalist->rdata)) {
+       result = dns_dns64_apply(
+               client->manager->mctx, view->dns64, view->dns64cnt,
+               client->message, client->manager->aclenv, &client->peeraddr,
+               client->signer, flags, qctx->rdataset, &dns64_rdataset);
+       if (result != ISC_R_SUCCESS) {
                goto cleanup;
        }
 
-       dns_rdatalist_tordataset(dns64_rdatalist, dns64_rdataset);
        dns_rdataset_setownercase(dns64_rdataset, mname);
        client->query.attributes |= NS_QUERYATTR_NOADDITIONAL;
-       dns64_rdataset->trust = qctx->rdataset->trust;
+
+       if (client->query.dns64_ttl != UINT32_MAX) {
+               dns64_rdataset->ttl = ISC_MIN(qctx->rdataset->ttl,
+                                             client->query.dns64_ttl);
+       } else {
+               dns64_rdataset->ttl = ISC_MIN(qctx->rdataset->ttl, 600);
+       }
 
        query_addtoname(mname, dns64_rdataset);
        query_setorder(qctx, mname, dns64_rdataset);
 
-       dns64_rdataset = NULL;
-       dns64_rdatalist = NULL;
-       dns_message_takebuffer(client->message, &buffer);
        inc_stats(client, ns_statscounter_dns64);
        result = ISC_R_SUCCESS;
 
 cleanup:
-       if (buffer != NULL) {
-               isc_buffer_free(&buffer);
-       }
-
-       if (dns64_rdataset != NULL) {
-               dns_message_puttemprdataset(client->message, &dns64_rdataset);
-       }
-
-       if (dns64_rdatalist != NULL) {
-               for (dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata);
-                    dns64_rdata != NULL;
-                    dns64_rdata = ISC_LIST_HEAD(dns64_rdatalist->rdata))
-               {
-                       ISC_LIST_UNLINK(dns64_rdatalist->rdata, dns64_rdata,
-                                       link);
-                       dns_message_puttemprdata(client->message, &dns64_rdata);
-               }
-               dns_message_puttemprdatalist(client->message, &dns64_rdatalist);
-       }
 
        CTRACE(ISC_LOG_DEBUG(3), "query_dns64: done");
        return result;
@@ -8366,13 +8289,10 @@ cleanup:
 static void
 query_filter64(query_ctx_t *qctx) {
        ns_client_t *client = qctx->client;
-       dns_name_t *name, *mname;
-       dns_rdata_t *myrdata;
-       dns_rdata_t rdata = DNS_RDATA_INIT;
-       dns_rdatalist_t *myrdatalist;
-       dns_rdataset_t *myrdataset;
-       isc_buffer_t *buffer;
-       isc_region_t r;
+       dns_name_t *name = NULL, *mname = NULL;
+       dns_rdatalist_t *myrdatalist = NULL;
+       dns_rdataset_t *myrdataset = NULL;
+       isc_buffer_t *buffer = NULL;
        isc_result_t result;
        unsigned int i;
        const dns_section_t section = DNS_SECTION_ANSWER;
@@ -8384,11 +8304,6 @@ query_filter64(query_ctx_t *qctx) {
               dns_rdataset_count(qctx->rdataset));
 
        name = qctx->fname;
-       mname = NULL;
-       buffer = NULL;
-       myrdata = NULL;
-       myrdataset = NULL;
-       myrdatalist = NULL;
        result = dns_message_findname(
                client->message, section, name, dns_rdatatype_aaaa,
                qctx->rdataset->covers, &mname, &myrdataset);
@@ -8432,6 +8347,10 @@ query_filter64(query_ctx_t *qctx) {
             result == ISC_R_SUCCESS;
             result = dns_rdataset_next(qctx->rdataset))
        {
+               dns_rdata_t rdata = DNS_RDATA_INIT;
+               dns_rdata_t *myrdata = NULL;
+               isc_region_t r;
+
                if (!client->query.dns64_aaaaok[i++]) {
                        continue;
                }
@@ -8441,15 +8360,9 @@ query_filter64(query_ctx_t *qctx) {
                isc_buffer_remainingregion(buffer, &r);
                isc_buffer_forward(buffer, rdata.length);
                dns_message_gettemprdata(client->message, &myrdata);
-               dns_rdata_init(myrdata);
                dns_rdata_fromregion(myrdata, dns_rdataclass_in,
                                     dns_rdatatype_aaaa, &r);
                ISC_LIST_APPEND(myrdatalist->rdata, myrdata, link);
-               myrdata = NULL;
-               dns_rdata_reset(&rdata);
-       }
-       if (result != ISC_R_NOMORE) {
-               goto cleanup;
        }
 
        dns_rdatalist_tordataset(myrdatalist, myrdataset);
@@ -8467,30 +8380,11 @@ query_filter64(query_ctx_t *qctx) {
        query_addtoname(mname, myrdataset);
        query_setorder(qctx, mname, myrdataset);
 
-       myrdataset = NULL;
-       myrdatalist = NULL;
        dns_message_takebuffer(client->message, &buffer);
-
-cleanup:
        if (buffer != NULL) {
                isc_buffer_free(&buffer);
        }
 
-       if (myrdataset != NULL) {
-               dns_message_puttemprdataset(client->message, &myrdataset);
-       }
-
-       if (myrdatalist != NULL) {
-               for (myrdata = ISC_LIST_HEAD(myrdatalist->rdata);
-                    myrdata != NULL;
-                    myrdata = ISC_LIST_HEAD(myrdatalist->rdata))
-               {
-                       ISC_LIST_UNLINK(myrdatalist->rdata, myrdata, link);
-                       dns_message_puttemprdata(client->message, &myrdata);
-               }
-               dns_message_puttemprdatalist(client->message, &myrdatalist);
-       }
-
        if (qctx->dbuf != NULL) {
                ns_client_releasename(client, &name);
        }