]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix that nxdomain synthesis does not happen above the stub or
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 13 Apr 2021 11:52:57 +0000 (13:52 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 13 Apr 2021 11:52:57 +0000 (13:52 +0200)
  forward definition.

cachedb/cachedb.c
doc/Changelog
edns-subnet/subnetmod.c
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
services/cache/dns.c
services/cache/dns.h

index e948a6b0dd34a14179630f3694cbf6947c0d1466..af4ffe5f28b5d05dd1437bad71212d1bdbd18c69 100644 (file)
@@ -617,12 +617,18 @@ cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
 static int
 cachedb_intcache_lookup(struct module_qstate* qstate)
 {
+       uint8_t* dpname=NULL;
+       size_t dpnamelen=0;
        struct dns_msg* msg;
+       if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo,
+               &dpname, &dpnamelen))
+               return 0; /* no cache for these queries */
        msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
                qstate->qinfo.qname_len, qstate->qinfo.qtype,
                qstate->qinfo.qclass, qstate->query_flags,
                qstate->region, qstate->env->scratch,
-               1 /* no partial messages with only a CNAME */
+               1, /* no partial messages with only a CNAME */
+               dpname, dpnamelen
                );
        if(!msg && qstate->env->neg_cache &&
                iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
index c62b48893b242148d4cbee0a74d082fbe282f749..1f61b19bb454de9341487a025da29294ec64baf2 100644 (file)
@@ -1,3 +1,7 @@
+13 April 2021: Wouter
+       - Fix that nxdomain synthesis does not happen above the stub or
+         forward definition.
+
 12 April 2021: George
        - Fix (increase) verbosity level for iterator error log in
          processQueryTargets().
index 6c8589aba4daf42d9e1b2714086658a1427f1ed3..ade40c66e85fae7f74ca0f5190e8e85f06c298da 100644 (file)
@@ -150,7 +150,7 @@ int ecs_whitelist_check(struct query_info* qinfo,
 
        /* Cache by default, might be disabled after parsing EDNS option
         * received from nameserver. */
-       if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo)) {
+       if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)) {
                qstate->no_cache_store = 0;
        }
 
index 94fa18f63c7e9564bd8b07c994a37f664c230ffd..adc611f73947149d990e80a4c1920d5efa6b167d 100644 (file)
@@ -1391,7 +1391,8 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp)
 }
 
 int
-iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
+iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
+       uint8_t** retdpname, size_t* retdpnamelen)
 {
        struct iter_hints_stub *stub;
        struct delegpt *dp;
@@ -1420,6 +1421,10 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
                        dname_str(stub->dp->name, dpname);
                        verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
                }
+               if(retdpname) {
+                       *retdpname = stub->dp->name;
+                       *retdpnamelen = stub->dp->namelen;
+               }
                return (stub->dp->no_cache);
        }
 
@@ -1432,8 +1437,16 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf)
                        dname_str(dp->name, dpname);
                        verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
                }
+               if(retdpname) {
+                       *retdpname = dp->name;
+                       *retdpnamelen = dp->namelen;
+               }
                return (dp->no_cache);
        }
+       if(retdpname) {
+               *retdpname = NULL;
+               *retdpnamelen = 0;
+       }
        return 0;
 }
 
index 7be79cf4a6686fd1bdae339dadb2fa530bb14ea5..509d2921e3066c90e6ea09f668484bec36fe83b1 100644 (file)
@@ -382,10 +382,15 @@ int iter_dp_cangodown(struct query_info* qinfo, struct delegpt* dp);
  * Lookup if no_cache is set in stub or fwd.
  * @param qstate: query state with env with hints and fwds.
  * @param qinf: query name to lookup for.
+ * @param retdpname: returns NULL or the deepest enclosing name of fwd or stub.
+ *     This is the name under which the closest lookup is going to happen.
+ *     Used for NXDOMAIN checks, above that it is an nxdomain from a
+ *     different server and zone. You can pass NULL to not get it.
+ * @param retdpnamelen: returns the length of the dpname.
  * @return true if no_cache is set in stub or fwd.
  */
 int iter_stub_fwd_no_cache(struct module_qstate *qstate,
-       struct query_info *qinf);
+       struct query_info *qinf, uint8_t** retdpname, size_t* retdpnamelen);
 
 /**
  * Set support for IP4 and IP6 depending on outgoing interfaces
index 83ded0808ded725c31f887dea92cd06b2ff824e5..0f662304d345270e3d8ea4e1bbcd4176362ff227 100644 (file)
@@ -1228,8 +1228,8 @@ static int
 processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
        struct iter_env* ie, int id)
 {
-       uint8_t* delname;
-       size_t delnamelen;
+       uint8_t* delname, *dpname=NULL;
+       size_t delnamelen, dpnamelen=0;
        struct dns_msg* msg = NULL;
 
        log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
@@ -1283,7 +1283,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
        /* This either results in a query restart (CNAME cache response), a
         * terminating response (ANSWER), or a cache miss (null). */
        
-       if (iter_stub_fwd_no_cache(qstate, &iq->qchase)) {
+       if (iter_stub_fwd_no_cache(qstate, &iq->qchase, &dpname, &dpnamelen)) {
                /* Asked to not query cache. */
                verbose(VERB_ALGO, "no-cache set, going to the network");
                qstate->no_cache_lookup = 1;
@@ -1298,7 +1298,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
                msg = dns_cache_lookup(qstate->env, iq->qchase.qname, 
                        iq->qchase.qname_len, iq->qchase.qtype, 
                        iq->qchase.qclass, qstate->query_flags,
-                       qstate->region, qstate->env->scratch, 0);
+                       qstate->region, qstate->env->scratch, 0, dpname,
+                       dpnamelen);
                if(!msg && qstate->env->neg_cache &&
                        iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) {
                        /* lookup in negative cache; may result in
@@ -2288,7 +2289,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                                iq->qinfo_out.qname, iq->qinfo_out.qname_len, 
                                iq->qinfo_out.qtype, iq->qinfo_out.qclass, 
                                qstate->query_flags, qstate->region, 
-                               qstate->env->scratch, 0);
+                               qstate->env->scratch, 0, iq->dp->name,
+                               iq->dp->namelen);
                        if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
                                LDNS_RCODE_NOERROR)
                                /* no need to send query if it is already 
index f3149b614b54b1a934423f4d4d976423c5059b3c..5b64fe47520ca3aca11996a6bb4b8ac5fcbeb974 100644 (file)
@@ -801,7 +801,7 @@ struct dns_msg*
 dns_cache_lookup(struct module_env* env,
        uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
        uint16_t flags, struct regional* region, struct regional* scratch,
-       int no_partial)
+       int no_partial, uint8_t* dpname, size_t dpnamelen)
 {
        struct lruhash_entry* e;
        struct query_info k;
@@ -923,6 +923,9 @@ dns_cache_lookup(struct module_env* env,
         * the same.  We search upwards for NXDOMAINs. */
        if(env->cfg->harden_below_nxdomain) {
                while(!dname_is_root(k.qname)) {
+                       if(dpname && dpnamelen
+                               && !dname_subdomain_c(k.qname, dpname))
+                               break; /* no synth nxdomain above the stub */
                        dname_remove_label(&k.qname, &k.qname_len);
                        h = query_info_hash(&k, flags);
                        e = slabhash_lookup(env->msg_cache, h, &k, 0);
index f1b77fb36c004c63f3d55c50d3bebcff238cf853..bece837029609335955ada4cf4a69a917dab2b99 100644 (file)
@@ -164,6 +164,8 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
  * @param scratch: where to allocate temporary data.
  * @param no_partial: if true, only complete messages and not a partial
  *     one (with only the start of the CNAME chain and not the rest).
+ * @param dpname: if not NULL, do not return NXDOMAIN above this name.
+ * @param dpnamelen: length of dpname.
  * @return new response message (alloced in region, rrsets do not have IDs).
  *     or NULL on error or if not found in cache.
  *     TTLs are made relative to the current time.
@@ -171,7 +173,7 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q,
 struct dns_msg* dns_cache_lookup(struct module_env* env,
        uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
        uint16_t flags, struct regional* region, struct regional* scratch,
-       int no_partial);
+       int no_partial, uint8_t* dpname, size_t dpnamelen);
 
 /** 
  * find and add A and AAAA records for missing nameservers in delegpt