]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Limit number of QNAME minimisation iterations.
authorRalph Dolmans <ralph@nlnetlabs.nl>
Thu, 17 Mar 2016 14:44:41 +0000 (14:44 +0000)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Thu, 17 Mar 2016 14:44:41 +0000 (14:44 +0000)
git-svn-id: file:///svn/unbound/trunk@3681 be551aaa-1e26-0410-a405-d3ace91eadb9

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

index 251bc1b11f6eee1396576c3dc1b4449c9bc7adeb..3834d9d7556d18431a624ceebd5cbc49ce6aa7bf 100644 (file)
@@ -1,3 +1,6 @@
+17 March 2016: Ralph
+       - Limit number of QNAME minimisation iterations.
+
 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
index ccc5d3408e43cd8537f58327681acf6043c5f5d8..38f79699a3462fe7082cb1df668a444a76bf5c16 100644 (file)
@@ -82,20 +82,6 @@ iter_init(struct module_env* env, int id)
                log_err("iterator: could not apply configuration settings.");
                return 0;
        }
-       if(env->cfg->qname_minimisation) {
-               uint8_t dname[LDNS_MAX_DOMAINLEN+1];
-               size_t len = sizeof(dname);
-               if(sldns_str2wire_dname_buf("ip6.arpa.", dname, &len) != 0) {
-                       log_err("ip6.arpa. parse error");
-                       return 0;
-               }
-               iter_env->ip6arpa_dname = (uint8_t*)malloc(len);
-               if(!iter_env->ip6arpa_dname) {
-                       log_err("malloc failure");
-                       return 0;
-               }
-               memcpy(iter_env->ip6arpa_dname, dname, len);
-       }
 
        return 1;
 }
@@ -117,7 +103,6 @@ iter_deinit(struct module_env* env, int id)
        if(!env || !env->modinfo[id])
                return;
        iter_env = (struct iter_env*)env->modinfo[id];
-       free(iter_env->ip6arpa_dname);
        free(iter_env->target_fetch_policy);
        priv_delete(iter_env->priv);
        donotq_delete(iter_env->donotq);
@@ -162,6 +147,7 @@ iter_new(struct module_qstate* qstate, int id)
        /* Start with the (current) qname. */
        iq->qchase = qstate->qinfo;
        outbound_list_init(&iq->outlist);
+       iq->minimise_count = 0;
        if (qstate->env->cfg->qname_minimisation)
                iq->minimisation_state = INIT_MINIMISE_STATE;
        else
@@ -2009,9 +1995,10 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
        }
 
        if(iq->minimisation_state == INIT_MINIMISE_STATE) {
-               /* (Re)set qinfo_out to (new) delegation point, except
-                * when qinfo_out is already a subdomain of dp. This happens
-                * when resolving ip6.arpa dnames. */
+               /* (Re)set qinfo_out to (new) delegation point, except when
+                * qinfo_out is already a subdomain of dp. This happens when
+                * increasing by more than one label at once (QNAMEs with more
+                * than MAX_MINIMISE_COUNT labels). */
                if(!(iq->qinfo_out.qname_len 
                        && dname_subdomain_c(iq->qchase.qname, 
                                iq->qinfo_out.qname)
@@ -2021,28 +2008,47 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                        iq->qinfo_out.qname_len = iq->dp->namelen;
                        iq->qinfo_out.qtype = LDNS_RR_TYPE_NS;
                        iq->qinfo_out.qclass = iq->qchase.qclass;
+                       iq->minimise_count = 0;
                }
 
                iq->minimisation_state = MINIMISE_STATE;
        }
        if(iq->minimisation_state == MINIMISE_STATE) {
-               int labdiff = dname_count_labels(iq->qchase.qname) -
+               int qchaselabs = dname_count_labels(iq->qchase.qname);
+               int labdiff = qchaselabs -
                        dname_count_labels(iq->qinfo_out.qname);
 
                iq->qinfo_out.qname = iq->qchase.qname;
                iq->qinfo_out.qname_len = iq->qchase.qname_len;
+               iq->minimise_count++;
 
-               /* Special treatment for ip6.arpa lookups.
-                * Reverse IPv6 dname has 34 labels, increment the IP part 
-                * (usually first 32 labels) by 8 labels (7 more than the 
-                * default 1 label increment). */
-               if(labdiff <= 32 &&
-                       dname_subdomain_c(iq->qchase.qname, ie->ip6arpa_dname)) {
-                       labdiff -= 7;
-                       /* Small chance of zone cut after first label. Stop
-                        * minimising */
-                       if(labdiff <= 1)
-                               labdiff = 0;
+               /* Limit number of iterations for QNAMEs with more
+                * than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
+                * labels of QNAME always individually.
+                */
+               if(qchaselabs > MAX_MINIMISE_COUNT && labdiff > 1 && 
+                       iq->minimise_count > MINIMISE_ONE_LAB) {
+                       if(iq->minimise_count < MAX_MINIMISE_COUNT) {
+                               int multilabs = qchaselabs - 1 - 
+                                       MINIMISE_ONE_LAB;
+                               int extralabs = multilabs / 
+                                       MINIMISE_MULTIPLE_LABS;
+
+                               if (MAX_MINIMISE_COUNT - iq->minimise_count >= 
+                                       multilabs % MINIMISE_MULTIPLE_LABS)
+                                       /* Default behaviour is to add 1 label
+                                        * every iteration. Therefore, decrement
+                                        * the extralabs by 1 */
+                                       extralabs--;
+                               if (extralabs < labdiff)
+                                       labdiff -= extralabs;
+                               else
+                                       labdiff = 1;
+                       }
+                       /* Last minimised iteration, send all labels with
+                        * QTYPE=NS */
+                       else
+                               labdiff = 1;
                }
 
                if(labdiff > 1) {
@@ -2068,7 +2074,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
                                 * cached as NOERROR/NODATA */
                                return 1;
                }
-               
        }
        if(iq->minimisation_state == SKIP_MINIMISE_STATE)
                /* Do not increment qname, continue incrementing next 
index b7aa82ebe4ed82093165bdac9c24ad2fad5367ee..52172b4e46392088289ab89711ca671c872b1318 100644 (file)
@@ -61,6 +61,17 @@ struct rbtree_t;
 #define MAX_REFERRAL_COUNT     130
 /** max number of queries-sent-out.  Make sure large NS set does not loop */
 #define MAX_SENT_COUNT         32
+/**
+ * max number of QNAME minimisation iterations. Limits number of queries for
+ * QNAMEs with a lot of labels.
+*/
+#define MAX_MINIMISE_COUNT     10
+/**
+ * number of labels from QNAME that are always send individually when using
+ * QNAME minimisation, even when the number of labels of the QNAME is bigger
+ * tham MAX_MINIMISE_COUNT */
+#define MINIMISE_ONE_LAB       4
+#define MINIMISE_MULTIPLE_LABS (MAX_MINIMISE_COUNT - MINIMISE_ONE_LAB)
 /** at what query-sent-count to stop target fetch policy */
 #define TARGET_FETCH_STOP      3
 /** how nice is a server without further information, in msec 
@@ -357,6 +368,12 @@ struct iter_qstate {
         * when qname minimisation is enabled.
         */
        struct query_info qinfo_out;
+
+       /**
+        * Count number of QNAME minisation iterations. Used to limit number of
+        * outgoing queries when QNAME minimisation is enabled.
+        */
+       int minimise_count;
 };
 
 /**