]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix validation failures due to EDNS backoff retries, the retry
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 26 Aug 2011 09:00:43 +0000 (09:00 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 26 Aug 2011 09:00:43 +0000 (09:00 +0000)
         for fetch of data has want_dnssec because the iter_indicate_dnssec
         function returns true when validation failure retry happens, and
         then the serviced query code does not fallback to noEDNS, even if
         the cache says it has this.  This helps for DLV deployment when
         the DNSSEC status is not known for sure before the lookup concludes.

git-svn-id: file:///svn/unbound/trunk@2483 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
services/outside_network.c

index dd6c1f38c0d0e3cb163a39019c97890b083c5bbf..64fbcad2675f05f33dd49b8c228fc42bf4eb4f5e 100644 (file)
@@ -1,5 +1,11 @@
 26 August 2011: Wouter
        - Fix num-threads 0 does not segfault, reported by Simon Deziel.
+       - Fix validation failures due to EDNS backoff retries, the retry
+         for fetch of data has want_dnssec because the iter_indicate_dnssec
+         function returns true when validation failure retry happens, and
+         then the serviced query code does not fallback to noEDNS, even if
+         the cache says it has this.  This helps for DLV deployment when
+         the DNSSEC status is not known for sure before the lookup concludes.
 
 24 August 2011: Wouter
        - Applied patch from Karel Slany that fixes a memory leak in the
index dc1b3fe963a3a570c9cbe270c90c6aaa1fe4486e..2bb216f1becae4b322531b9757d765d09a84f74f 100644 (file)
@@ -534,7 +534,7 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
 
 int 
 iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
-        struct dns_msg* msg, uint16_t dclass)
+        struct dns_msg* msg, uint16_t dclass, struct module_qstate* qstate)
 {
        struct trust_anchor* a;
        /* information not available, !env->anchors can be common */
@@ -568,6 +568,15 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
                        regional_free_all(env->scratch);
                }
        }
+       /* on retries, we have to expect DNSSEC.
+        * just a blacklist of the cache is done for parentside lookups too,
+        * but blacklist of IPs is done for validation failures. */
+       if(qstate && qstate->blacklist) {
+               struct sock_list* p;
+               for(p=qstate->blacklist; p; p=p->next)
+                       if(p->len != 0)
+                               return 1;
+       }
        return 0;
 }
 
index deddac666e3aca3c8026125a6ccb4c1475925445..c7beeacc609a8aa43cb546098e1046e7415f11c0 100644 (file)
@@ -172,10 +172,12 @@ int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
  * @param dp: delegation point.
  * @param msg: delegation message, with DS if a secure referral.
  * @param dclass: class of query.
+ * @param qstate: module query state for the query in question, for validation
+ *     retry state.
  * @return 1 if dnssec is expected, 0 if not.
  */
 int iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
-       struct dns_msg* msg, uint16_t dclass);
+       struct dns_msg* msg, uint16_t dclass, struct module_qstate* qstate);
 
 /**
  * See if a message contains DNSSEC.
index 3924057ce0159f84db5c2deb0f36240592dfe43e..e4bfa8d5ddca646f985c6c5a4c1e1118765b4a17 100644 (file)
@@ -574,8 +574,8 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
                }
                /* there should not be any target queries. */
                subiq->num_target_queries = 0; 
-               subiq->dnssec_expected = iter_indicates_dnssec(
-                       qstate->env, subiq->dp, NULL, subq->qinfo.qclass);
+               subiq->dnssec_expected = iter_indicates_dnssec(qstate->env,
+                       subiq->dp, NULL, subq->qinfo.qclass, subq);
        }
        
        /* this module stops, our submodule starts, and does the query. */
@@ -669,8 +669,8 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
                 * missing targets. */
                subiq->num_target_queries = 0; 
                subiq->wait_priming_stub = 1;
-               subiq->dnssec_expected = iter_indicates_dnssec(
-                       qstate->env, subiq->dp, NULL, subq->qinfo.qclass);
+               subiq->dnssec_expected = iter_indicates_dnssec(qstate->env,
+                       subiq->dp, NULL, subq->qinfo.qclass, subq);
        }
        
        /* this module stops, our submodule starts, and does the query. */
@@ -1191,7 +1191,7 @@ processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq,
        /* if the cache reply dp equals a validation anchor or msg has DS,
         * then DNSSEC RRSIGs are expected in the reply */
        iq->dnssec_expected = iter_indicates_dnssec(qstate->env, iq->dp, 
-               iq->deleg_msg, iq->qchase.qclass);
+               iq->deleg_msg, iq->qchase.qclass, qstate);
 
        /* If the RD flag wasn't set, then we just finish with the 
         * cached referral as the response. */
@@ -1254,7 +1254,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
                        subiq->dp = delegpt_copy(iq->dp, subq->region);
                        subiq->dnssec_expected = iter_indicates_dnssec(
                                qstate->env, subiq->dp, NULL, 
-                               subq->qinfo.qclass);
+                               subq->qinfo.qclass, subq);
                        subiq->refetch_glue = 1;
                } else {
                        subiq->dp = dns_cache_find_delegation(qstate->env, 
@@ -1264,7 +1264,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
                        if(subiq->dp) { 
                                subiq->dnssec_expected = iter_indicates_dnssec(
                                        qstate->env, subiq->dp, NULL, 
-                                       subq->qinfo.qclass);
+                                       subq->qinfo.qclass, subq);
                                subiq->refetch_glue = 1;
                        }
                }
@@ -1897,7 +1897,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                /* see if the next dp is a trust anchor, or a DS was sent
                 * along, indicating dnssec is expected for next zone */
                iq->dnssec_expected = iter_indicates_dnssec(qstate->env, 
-                       iq->dp, iq->response, iq->qchase.qclass);
+                       iq->dp, iq->response, iq->qchase.qclass, qstate);
                /* if dnssec, validating then also fetch the key for the DS */
                if(iq->dnssec_expected && qstate->env->cfg->prefetch_key &&
                        !(qstate->query_flags&BIT_CD))
index 5397e8afb5e3668d9e2abbb11afb95d5c2dc8781..59482c6ba5a2263abec5455c27e508d098e554e3 100644 (file)
@@ -1318,7 +1318,7 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
                        /* even 700 msec may be too small */
                        rtt = 1000;
                        sq->status = serviced_query_PROBE_EDNS;
-               } else if(vs != -1) {
+               } else if(vs != -1 || sq->want_dnssec) {
                        sq->status = serviced_query_UDP_EDNS;
                } else {        
                        sq->status = serviced_query_UDP; 
@@ -1536,7 +1536,7 @@ serviced_tcp_send(struct serviced_query* sq, ldns_buffer* buff)
        if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, 
                *sq->outnet->now_secs, &vs, &edns_lame_known, &rtt))
                return 0;
-       if(vs != -1)
+       if(vs != -1 || sq->want_dnssec)
                sq->status = serviced_query_TCP_EDNS;
        else    sq->status = serviced_query_TCP;
        serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);