]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- 0x20 fallback improved, better handling of servfail responses,
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 4 Mar 2015 08:30:17 +0000 (08:30 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 4 Mar 2015 08:30:17 +0000 (08:30 +0000)
  they do not count as missing comparisons (except if all are failed),
  and better handling of inability to find nameservers, no more
  nameservers can be found results in fallback acceptance.

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

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

index 100ffc61260a89ee48258a17ae8b38f778e5797d..a3b05b49a47929b7e3a01215c8b6b5475db44c58 100644 (file)
@@ -1,6 +1,10 @@
 4 March 2015: Wouter
        - Patch from Brad Smith that syncs compat/getentropy_linux with
          OpenBSD's version (2015-03-04).
+       - 0x20 fallback improved, better handling of servfail responses,
+         they do not count as missing comparisons (except if all are failed),
+         and better handling of inability to find nameservers, no more
+         nameservers can be found results in fallback acceptance.
 
 3 March 2015: Wouter
        - tag 1.5.3rc1
index 10ae12f75c6cd728c860b8acc4ffb6fd9f13cfed..8c90653c0cfb2f9323a4c287d3913d1c1454443e 100644 (file)
@@ -750,6 +750,12 @@ caps_strip_reply(struct reply_info* rep)
        }
 }
 
+int caps_failed_rcode(struct reply_info* rep)
+{
+       return !(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR ||
+               FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN);
+}
+
 void 
 iter_store_parentside_rrset(struct module_env* env, 
        struct ub_packed_rrset_key* rrset)
index 9373487e002c95712c8f5a7721bb8778eeb247b9..3a4df3e45968bd3bfbe70b7860d5bb59cf4b4750 100644 (file)
@@ -231,6 +231,14 @@ int reply_equal(struct reply_info* p, struct reply_info* q, struct regional* reg
  */
 void caps_strip_reply(struct reply_info* rep);
 
+/**
+ * see if reply has a 'useful' rcode for capsforid comparison, so
+ * not SERVFAIL or REFUSED, and thus NOERROR or NXDOMAIN.
+ * @param rep: reply to check.
+ * @return true if the rcode is a bad type of message.
+ */
+int caps_failed_rcode(struct reply_info* rep);
+
 /**
  * Store parent-side rrset in seperate rrset cache entries for later 
  * last-resort * lookups in case the child-side versions of this information 
index 2037cc8814f2b962f7df61eb5e20f24a369e1c43..cd7e5b36b1f34361863f2212927312d0a4f01920 100644 (file)
@@ -1866,6 +1866,23 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                        /* Since a target query might have been made, we 
                         * need to check again. */
                        if(iq->num_target_queries == 0) {
+                               /* if in capsforid fallback, instead of last
+                                * resort, we agree with the current reply
+                                * we have (if any) (our count of addrs bad)*/
+                               if(iq->caps_fallback && iq->caps_reply) {
+                                       /* we're done, process the response */
+                                       verbose(VERB_ALGO, "0x20 fallback had %d responses, "
+                                               "but no more servers except "
+                                               "last resort, done.", 
+                                               (int)iq->caps_server+1);
+                                       iq->caps_fallback = 0;
+                                       iter_dec_attempts(iq->dp, 3); /* space for fallback */
+                                       iq->num_current_queries++; /* RespState decrements it*/
+                                       iq->referral_count++; /* make sure we don't loop */
+                                       iq->sent_count = 0;
+                                       iq->state = QUERY_RESP_STATE;
+                                       return 1;
+                               }
                                return processLastResort(qstate, iq, ie, id);
                        }
                }
@@ -2900,6 +2917,20 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
                                iq->caps_reply = iq->response->rep;
                                iq->caps_server = -1; /*become zero at ++,
                                so that we start the full set of trials */
+                       } else if(caps_failed_rcode(iq->caps_reply) &&
+                               !caps_failed_rcode(iq->response->rep)) {
+                               /* prefer to upgrade to non-SERVFAIL */
+                               iq->caps_reply = iq->response->rep;
+                       } else if(!caps_failed_rcode(iq->caps_reply) &&
+                               caps_failed_rcode(iq->response->rep)) {
+                               /* if we have non-SERVFAIL as answer then 
+                                * we can ignore SERVFAILs for the equality
+                                * comparison */
+                               /* no instructions here, skip other else */
+                       } else if(caps_failed_rcode(iq->caps_reply) &&
+                               caps_failed_rcode(iq->response->rep)) {
+                               /* failure is same as other failure in fallbk*/
+                               /* no instructions here, skip other else */
                        } else if(!reply_equal(iq->response->rep, iq->caps_reply,
                                qstate->env->scratch)) {
                                verbose(VERB_DETAIL, "Capsforid fallback: "