]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #1366: Infra cache does not work correctly for NAT64, by
authorYorgos Thessalonikefs <yorgos@nlnetlabs.nl>
Sat, 1 Nov 2025 14:10:27 +0000 (15:10 +0100)
committerYorgos Thessalonikefs <yorgos@nlnetlabs.nl>
Sat, 1 Nov 2025 14:10:27 +0000 (15:10 +0100)
  moving the NAT64 synthesis from the iterator when selecting a target
  address, to the delegation point itself when adding target
  addresses.

doc/Changelog
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
util/net_help.c
util/net_help.h

index 3a8506e61bfb850e60047856bf3fe6ddbcc79821..9829c8feb9a7b090e0263e2e83cccbf155445d51 100644 (file)
@@ -1,3 +1,9 @@
+1 November 2025: Yorgos
+       - Fix #1366: Infra cache does not work correctly for NAT64, by
+         moving the NAT64 synthesis from the iterator when selecting a target
+         address, to the delegation point itself when adding target
+         addresses.
+
 27 October 2025: Yorgos
        - Merge #1331 from Jitka PlesnĂ­ková: Replace deprecated $function by
          new $action, for SWIG.
index 1da21896cb2089e0d731c65df9c1efa4f3e295be..fb419f9ab32589f089eb15fd051ec855d8b81042 100644 (file)
@@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
        return 1;
 }
 
-/** filter out unsuitable targets
+/** filter out unsuitable targets.
+ * Applies NAT64 if needed as well by replacing the IPv4 with the synthesized
+ * IPv6 address.
  * @param iter_env: iterator environment with ipv6-support flag.
  * @param env: module environment with infra cache.
  * @param name: zone name
@@ -317,6 +319,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
           !addr_is_ip6(&a->addr, a->addrlen)) {
                return -1; /* there is no ip4 available */
        }
+       if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) {
+               struct sockaddr_storage real_addr;
+               socklen_t real_addrlen;
+               addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr,
+                       iter_env->nat64.nat64_prefix_addrlen,
+                       iter_env->nat64.nat64_prefix_net,
+                       &real_addr, &real_addrlen);
+               log_name_addr(VERB_QUERY, "NAT64 apply: from: ",
+                       name, &a->addr, a->addrlen);
+               log_name_addr(VERB_QUERY, "NAT64 apply:   to: ",
+                       name, &real_addr, real_addrlen);
+               a->addr = real_addr;
+               a->addrlen = real_addrlen;
+       }
        /* check lameness - need zone , class info */
        if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
                name, namelen, qtype, &lame, &dnsseclame, &reclame,
index b17b091e6639a87d393ff4118e59d9081f4c529d..f7f3747428036285effe8263ea6c1e4793c5f2c1 100644 (file)
@@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
 /**
  * Select a valid, nice target to send query to.
  * Sorting and removing unsuitable targets is combined.
+ * Adds records to the infra cache if not already there.
  *
  * @param iter_env: iterator module global state, with ip6 enabled and 
  *     do-not-query-addresses.
index 071dd0827e19154174f11ae865d5831dc620ca28..836cb36e0dcfe0a181c28b9b115f272992dc3a2f 100644 (file)
@@ -2436,8 +2436,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
        int tf_policy;
        struct delegpt_addr* target;
        struct outbound_entry* outq;
-       struct sockaddr_storage real_addr;
-       socklen_t real_addrlen;
        int auth_fallback = 0;
        uint8_t* qout_orig = NULL;
        size_t qout_orig_len = 0;
@@ -3060,17 +3058,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                        iq->dnssec_lame_query?" but lame_query anyway": "");
        }
 
-       real_addr = target->addr;
-       real_addrlen = target->addrlen;
-
-       if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) {
-               addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr,
-                       ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net,
-                       &real_addr, &real_addrlen);
-               log_name_addr(VERB_QUERY, "applied NAT64:",
-                       iq->dp->name, &real_addr, real_addrlen);
-       }
-
        fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
        outq = (*qstate->env->send_query)(&iq->qinfo_out,
                iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
@@ -3082,7 +3069,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                !qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
                &iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
                iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
-               ie, iq), sq_check_ratelimit, &real_addr, real_addrlen,
+               ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
                iq->dp->name, iq->dp->namelen,
                (iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
                (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
@@ -3099,7 +3086,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                        return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
                }
                log_addr(VERB_QUERY, "error sending query to auth server",
-                       &real_addr, real_addrlen);
+                       &target->addr, target->addrlen);
                if(qstate->env->cfg->qname_minimisation)
                        iq->minimisation_state = SKIP_MINIMISE_STATE;
                return next_state(iq, QUERYTARGETS_STATE);
index 426ace934d8c846f2400e11de1ab64dc398f3e0f..9ad9a3bb8854834bfa98db5430ce94349bbeba7a 100644 (file)
@@ -783,7 +783,7 @@ sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1,
 }
 
 int
-addr_is_ip6(struct sockaddr_storage* addr, socklen_t len)
+addr_is_ip6(const struct sockaddr_storage* addr, socklen_t len)
 {
        if(len == (socklen_t)sizeof(struct sockaddr_in6) &&
                ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6)
index 7b8a206424aeef217c0b2010898139d2304ff5f9..1f31a89c3c06d17a7299b40fa347ecd8bff09ba8 100644 (file)
@@ -307,7 +307,7 @@ int sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1,
  * @param len: the length of addr.
  * @return: true if sockaddr is ip6.
  */
-int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len);
+int addr_is_ip6(const struct sockaddr_storage* addr, socklen_t len);
 
 /**
  * Make sure the sockaddr ends in zeroes. For tree insertion and subsequent