]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #746: Fix unbound sets CD bit on all forwards.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 17 Mar 2016 14:01:59 +0000 (14:01 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 17 Mar 2016 14:01:59 +0000 (14:01 +0000)
  If no trust anchors, it'll not set CD bit when forwarding to another
  server.  If a trust anchor, no CD bit on the first attempt to a
  forwarder, but CD bit thereafter on repeated attempts to get DNSSEC.

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

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

index 2ac0dda416f11ccd5d7d72ac8df59cc2c5edc672..c10fd0f158ee2b4c2ddaeeaa6625d672b6c21b5b 100644 (file)
@@ -1,3 +1,9 @@
+17 March 2016: Wouter
+       - Fix #746: Fix unbound sets CD bit on all forwards.
+         If no trust anchors, it'll not set CD bit when forwarding to another
+         server.  If a trust anchor, no CD bit on the first attempt to a
+         forwarder, but CD bit thereafter on repeated attempts to get DNSSEC.
+
 16 March 2016: Wouter
        - Fix ip-transparent for ipv6 on FreeBSD, thanks to Nick Hibma.
        - Fix ip-transparent for tcp on freebsd.
index 58e62fbeb27bdd63a0d1f7c5c14a14af3b1b3721..a5aefa9602c2b5736bfd7a263190c4fad6c195a7 100644 (file)
@@ -590,6 +590,27 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
        return 1;
 }
 
+int
+iter_indicates_dnssec_fwd(struct module_env* env, struct query_info *qinfo)
+{
+       struct trust_anchor* a;
+       if(!env || !env->anchors || !qinfo || !qinfo->qname)
+               return 0;
+       /* a trust anchor exists above the name? */
+       if((a=anchors_lookup(env->anchors, qinfo->qname, qinfo->qname_len,
+               qinfo->qclass))) { 
+               if(a->numDS == 0 && a->numDNSKEY == 0) {
+                       /* insecure trust point */
+                       lock_basic_unlock(&a->lock);
+                       return 0;
+               }
+               lock_basic_unlock(&a->lock);
+               return 1;
+       }
+       /* no trust anchor above it. */
+       return 0;
+}
+
 int 
 iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
         struct dns_msg* msg, uint16_t dclass)
index 3a4df3e45968bd3bfbe70b7860d5bb59cf4b4750..50c5fc093f6c4933b62ba7a0746ff4343c7862b7 100644 (file)
@@ -173,6 +173,18 @@ void iter_mark_pside_cycle_targets(struct module_qstate* qstate,
 int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, 
        struct delegpt* dp);
 
+/**
+ * See if qname has DNSSEC needs in the forwarding case.  This is true if
+ * there is a trust anchor above it.  Whether there is an insecure delegation
+ * to the data is unknown, but CD-retry is needed.
+ * @param env: environment with anchors.
+ * @param qinfo: query name and class.
+ * @return true if trust anchor above qname, false if no anchor or insecure
+ * point above qname.
+ */
+int iter_indicates_dnssec_fwd(struct module_env* env,
+       struct query_info *qinfo);
+
 /**
  * See if delegation is expected to have DNSSEC information (RRSIGs) in 
  * its answers, or not. Inspects delegation point (name), trust anchors,
index b1bf902d583df0587c0379a2ce00584120dab887..ccc5d3408e43cd8537f58327681acf6043c5f5d8 100644 (file)
@@ -2090,7 +2090,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
        outq = (*qstate->env->send_query)(
                iq->qinfo_out.qname, iq->qinfo_out.qname_len, 
                iq->qinfo_out.qtype, iq->qinfo_out.qclass, 
-               iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD, 
+               iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), 
+               /* unset CD if to forwarder(RD set) and not dnssec retry
+                * (blacklist nonempty) and no trust-anchors are configured
+                * above the qname or on the first attempt when dnssec is on */
+               EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&&
+               !qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
+               &iq->qinfo_out)||target->attempts==1)?0:BIT_CD), 
                iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
                ie, iq), &target->addr, target->addrlen, iq->dp->name,
                iq->dp->namelen, qstate);