]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add the ability to use DNS64 internally
authorMark Andrews <marka@isc.org>
Sun, 21 Jul 2019 16:26:39 +0000 (02:26 +1000)
committerMark Andrews <marka@isc.org>
Wed, 13 Sep 2023 04:31:43 +0000 (14:31 +1000)
Add a configuration option, resolver-use-dns64, which when true
will cause named to map IPv4 address to IPv6 addresses using the
view's DNS64 mapping rules when making iterative queries.

bin/named/config.c
bin/named/server.c
doc/misc/options
lib/dns/dns64.c
lib/dns/include/dns/dns64.h
lib/dns/include/dns/view.h
lib/dns/resolver.c
lib/isccfg/namedconf.c

index c0ac33a8b829dd1794b4322dcb63d6d8c5b5e51a..c0cbf3f18396faf2fe51bbb6dbadcdc786213d38 100644 (file)
@@ -201,6 +201,7 @@ options {\n\
        synth-from-dnssec yes;\n\
 #      topology <none>\n\
        transfer-format many-answers;\n\
+       resolver-use-dns64 false;\n\
        v6-bias 50;\n\
        zero-no-soa-ttl-cache no;\n\
 \n\
index f751b840eb5ba30cc1d010a28170e4b769e2ff36..714c1b10b3f2dc162d8e5dce3c4c3b712fc629d6 100644 (file)
@@ -4318,6 +4318,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
        INSIST(result == ISC_R_SUCCESS);
        zero_no_soattl = cfg_obj_asboolean(obj);
 
+       obj = NULL;
+       result = named_config_get(maps, "resolver-use-dns64", &obj);
+       INSIST(result == ISC_R_SUCCESS);
+       view->usedns64 = cfg_obj_asboolean(obj);
+
        obj = NULL;
        result = named_config_get(maps, "dns64", &obj);
        if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") &&
index c01314b7899e5600e63c5106b585cf7616b47952..18a51d86094433aa95b5b27107ed6ef2bee9bef9 100644 (file)
@@ -249,6 +249,7 @@ options {
        resolver-nonbackoff-tries <integer>;
        resolver-query-timeout <integer>;
        resolver-retry-interval <integer>;
+       resolver-use-dns64 <boolean>;
        response-padding { <address_match_element>; ... } block-size <integer>;
        response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
        reuseport <boolean>;
@@ -522,6 +523,7 @@ view <string> [ <class> ] {
        resolver-nonbackoff-tries <integer>;
        resolver-query-timeout <integer>;
        resolver-retry-interval <integer>;
+       resolver-use-dns64 <boolean>;
        response-padding { <address_match_element>; ... } block-size <integer>;
        response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
        root-key-sentinel <boolean>;
index b575726009e0b3f97f6819f2329680f67b3df3ca..80ed6c4d919ef2eaf681b99263c4c72286aa2e02 100644 (file)
@@ -146,7 +146,7 @@ dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
                return (DNS_R_DISALLOWED);
        }
 
-       if (dns64->clients != NULL) {
+       if (dns64->clients != NULL && reqaddr != NULL) {
                result = dns_acl_match(reqaddr, reqsigner, dns64->clients, env,
                                       &match, NULL);
                if (result != ISC_R_SUCCESS) {
index 8dd01032b2a2dc5cb43627a5a2a0ef35668c560a..9242cbcbc81f59625c7eb7e03f11d4c295154e3a 100644 (file)
@@ -107,6 +107,8 @@ dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
  * 'flags' and 'aaaa'.  If synthesis is performed then the result is
  * written to '*aaaa'.
  *
+ * If 'reqaddr' is NULL the 'client' acl is ignored.
+ *
  * The synthesised address will be of the form:
  *
  *      <prefix bits><a bits><suffix bits>
@@ -116,7 +118,7 @@ dns_dns64_aaaafroma(const dns_dns64_t *dns64, const isc_netaddr_t *reqaddr,
  *
  * Requires:
  *     'dns64'         to be valid.
- *     'reqaddr'       to be valid.
+ *     'reqaddr'       to be NULL or valid
  *     'reqsigner'     to be NULL or valid.
  *     'env'           to be valid.
  *     'a'             to point to a IPv4 address in network order.
index f8b1d943c75a536cba8b3e7be2f0a8cca8a97865..7e1babaa163719674394a6b7f42385ce4efdbb01 100644 (file)
@@ -165,22 +165,22 @@ struct dns_view {
        uint16_t              maxudp;
        dns_ttl_t             staleanswerttl;
        dns_stale_answer_t    staleanswersok;     /* rndc setting */
-       bool                  staleanswersenable; /* named.conf setting
-                                                  * */
-       uint32_t          staleanswerclienttimeout;
-       uint16_t          nocookieudp;
-       uint16_t          padding;
-       dns_acl_t        *pad_acl;
-       unsigned int      maxbits;
-       dns_dns64list_t   dns64;
-       unsigned int      dns64cnt;
-       dns_rpz_zones_t  *rpzs;
-       dns_catz_zones_t *catzs;
-       dns_dlzdblist_t   dlz_searched;
-       dns_dlzdblist_t   dlz_unsearched;
-       uint32_t          fail_ttl;
-       dns_badcache_t   *failcache;
-       unsigned int      udpsize;
+       bool                  staleanswersenable; /* named.conf setting */
+       uint32_t              staleanswerclienttimeout;
+       uint16_t              nocookieudp;
+       uint16_t              padding;
+       dns_acl_t            *pad_acl;
+       unsigned int          maxbits;
+       dns_dns64list_t       dns64;
+       unsigned int          dns64cnt;
+       bool                  usedns64;
+       dns_rpz_zones_t      *rpzs;
+       dns_catz_zones_t     *catzs;
+       dns_dlzdblist_t       dlz_searched;
+       dns_dlzdblist_t       dlz_unsearched;
+       uint32_t              fail_ttl;
+       dns_badcache_t       *failcache;
+       unsigned int          udpsize;
 
        /*
         * Configurable data for server use only,
index d017c2b3b03fe6825a60b4127f9c49db792aa0cf..94b78a91e211273e9f61ef0182844da12c004ba4 100644 (file)
@@ -44,6 +44,7 @@
 #include <dns/cache.h>
 #include <dns/db.h>
 #include <dns/dispatch.h>
+#include <dns/dns64.h>
 #include <dns/dnstap.h>
 #include <dns/ds.h>
 #include <dns/edns.h>
@@ -1938,8 +1939,9 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
           unsigned int options) {
        isc_result_t result;
        dns_resolver_t *res = NULL;
+       dns_dns64_t *dns64 = NULL;
        resquery_t *query = NULL;
-       isc_sockaddr_t addr;
+       isc_sockaddr_t addr, sockaddr;
        bool have_addr = false;
        unsigned int srtt;
        isc_tlsctx_cache_t *tlsctx_cache = NULL;
@@ -2011,15 +2013,46 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
        query->start = isc_time_now();
 
        /*
-        * If this is a TCP query, then we need to make a socket and
-        * a dispatch for it here.  Otherwise we use the resolver's
-        * shared dispatch.
+        * Maybe apply DNS64 mappings to IPv4 addresses.
         */
+       sockaddr = addrinfo->sockaddr;
+       dns64 = ISC_LIST_HEAD(fctx->res->view->dns64);
+       if (isc_sockaddr_pf(&sockaddr) == AF_INET &&
+           fctx->res->view->usedns64 && dns64 != NULL)
+       {
+               struct in6_addr aaaa;
+
+               result = dns_dns64_aaaafroma(
+                       dns64, NULL, NULL, fctx->res->view->aclenv, 0,
+                       (unsigned char *)&sockaddr.type.sin.sin_addr.s_addr,
+                       aaaa.s6_addr);
+               if (result == ISC_R_SUCCESS) {
+                       char sockaddrbuf1[ISC_SOCKADDR_FORMATSIZE];
+                       char sockaddrbuf2[ISC_SOCKADDR_FORMATSIZE];
+
+                       /* format old address */
+                       isc_sockaddr_format(&sockaddr, sockaddrbuf1,
+                                           sizeof(sockaddrbuf1));
+
+                       /* replace address */
+                       isc_sockaddr_fromin6(&sockaddr, &aaaa,
+                                            ntohs(sockaddr.type.sin.sin_port));
+                       addrinfo->sockaddr = sockaddr;
+
+                       /* format new address */
+                       isc_sockaddr_format(&sockaddr, sockaddrbuf2,
+                                           sizeof(sockaddrbuf2));
+                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+                                     DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+                                     "Using DNS64 address %s to talk to %s\n",
+                                     sockaddrbuf2, sockaddrbuf1);
+               }
+       }
        if (res->view->peers != NULL) {
                dns_peer_t *peer = NULL;
                isc_netaddr_t dstip;
                bool usetcp = false;
-               isc_netaddr_fromsockaddr(&dstip, &addrinfo->sockaddr);
+               isc_netaddr_fromsockaddr(&dstip, &sockaddr);
                result = dns_peerlist_peerbyaddr(res->view->peers, &dstip,
                                                 &peer);
                if (result == ISC_R_SUCCESS) {
@@ -2034,10 +2067,15 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
                }
        }
 
+       /*
+        * If this is a TCP query, then we need to make a socket and
+        * a dispatch for it here.  Otherwise we use the resolver's
+        * shared dispatch.
+        */
        if ((query->options & DNS_FETCHOPT_TCP) != 0) {
                int pf;
 
-               pf = isc_sockaddr_pf(&addrinfo->sockaddr);
+               pf = isc_sockaddr_pf(&sockaddr);
                if (!have_addr) {
                        switch (pf) {
                        case PF_INET:
@@ -2059,8 +2097,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
                isc_sockaddr_setport(&addr, 0);
 
                result = dns_dispatch_createtcp(res->view->dispatchmgr, &addr,
-                                               &addrinfo->sockaddr,
-                                               &query->dispatch);
+                                               &sockaddr, &query->dispatch);
                if (result != ISC_R_SUCCESS) {
                        goto cleanup_query;
                }
@@ -2075,7 +2112,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
                                goto cleanup_query;
                        }
                } else {
-                       switch (isc_sockaddr_pf(&addrinfo->sockaddr)) {
+                       switch (isc_sockaddr_pf(&sockaddr)) {
                        case PF_INET:
                                dns_dispatch_attach(
                                        dns_resolver_dispatchv4(res),
@@ -2124,12 +2161,12 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
        UNLOCK(&fctx->lock);
 
        /* Set up the dispatch and set the query ID */
-       result = dns_dispatch_add(
-               query->dispatch, fctx->loop, 0,
-               isc_interval_ms(&fctx->interval), &query->addrinfo->sockaddr,
-               addrinfo->transport, tlsctx_cache, resquery_connected,
-               resquery_senddone, resquery_response, query, &query->id,
-               &query->dispentry);
+       result = dns_dispatch_add(query->dispatch, fctx->loop, 0,
+                                 isc_interval_ms(&fctx->interval), &sockaddr,
+                                 addrinfo->transport, tlsctx_cache,
+                                 resquery_connected, resquery_senddone,
+                                 resquery_response, query, &query->id,
+                                 &query->dispentry);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_udpfetch;
        }
index afe4f5fabd193fc5c0eeb9bf2d0450132f3d2cc6..348be0f592e4d1204e8fbcd7277d2732a27008f9 100644 (file)
@@ -2151,6 +2151,7 @@ static cfg_clausedef_t view_clauses[] = {
        { "transfer-format", &cfg_type_transferformat, 0 },
        { "trust-anchor-telemetry", &cfg_type_boolean,
          CFG_CLAUSEFLAG_EXPERIMENTAL },
+       { "resolver-use-dns64", &cfg_type_boolean, 0 },
        { "use-queryport-pool", NULL, CFG_CLAUSEFLAG_ANCIENT },
        { "validate-except", &cfg_type_namelist, 0 },
        { "v6-bias", &cfg_type_uint32, 0 },