From: Ralph Dolmans Date: Thu, 17 Mar 2016 14:44:41 +0000 (+0000) Subject: - Limit number of QNAME minimisation iterations. X-Git-Tag: release-1.5.9rc1~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6362a12bd701fe23a9928d44de87dcaea2f31664;p=thirdparty%2Funbound.git - Limit number of QNAME minimisation iterations. git-svn-id: file:///svn/unbound/trunk@3681 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 251bc1b11..3834d9d75 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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 diff --git a/iterator/iterator.c b/iterator/iterator.c index ccc5d3408..38f79699a 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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 diff --git a/iterator/iterator.h b/iterator/iterator.h index b7aa82ebe..52172b4e4 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -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; }; /**