- Limit number of QNAME minimisation iterations.

git-svn-id: file:///svn/unbound/trunk@3681 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Ralph Dolmans 2016-03-17 14:44:41 +00:00
parent df53793680
commit 6362a12bd7
3 changed files with 56 additions and 31 deletions

View file

@ -1,3 +1,6 @@
17 March 2016: Ralph
- Limit number of QNAME minimisation iterations.
17 March 2016: Wouter 17 March 2016: Wouter
- Fix #746: Fix unbound sets CD bit on all forwards. - Fix #746: Fix unbound sets CD bit on all forwards.
If no trust anchors, it'll not set CD bit when forwarding to another If no trust anchors, it'll not set CD bit when forwarding to another

View file

@ -82,20 +82,6 @@ iter_init(struct module_env* env, int id)
log_err("iterator: could not apply configuration settings."); log_err("iterator: could not apply configuration settings.");
return 0; 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; return 1;
} }
@ -117,7 +103,6 @@ iter_deinit(struct module_env* env, int id)
if(!env || !env->modinfo[id]) if(!env || !env->modinfo[id])
return; return;
iter_env = (struct iter_env*)env->modinfo[id]; iter_env = (struct iter_env*)env->modinfo[id];
free(iter_env->ip6arpa_dname);
free(iter_env->target_fetch_policy); free(iter_env->target_fetch_policy);
priv_delete(iter_env->priv); priv_delete(iter_env->priv);
donotq_delete(iter_env->donotq); donotq_delete(iter_env->donotq);
@ -162,6 +147,7 @@ iter_new(struct module_qstate* qstate, int id)
/* Start with the (current) qname. */ /* Start with the (current) qname. */
iq->qchase = qstate->qinfo; iq->qchase = qstate->qinfo;
outbound_list_init(&iq->outlist); outbound_list_init(&iq->outlist);
iq->minimise_count = 0;
if (qstate->env->cfg->qname_minimisation) if (qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE; iq->minimisation_state = INIT_MINIMISE_STATE;
else else
@ -2009,9 +1995,10 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
} }
if(iq->minimisation_state == INIT_MINIMISE_STATE) { if(iq->minimisation_state == INIT_MINIMISE_STATE) {
/* (Re)set qinfo_out to (new) delegation point, except /* (Re)set qinfo_out to (new) delegation point, except when
* when qinfo_out is already a subdomain of dp. This happens * qinfo_out is already a subdomain of dp. This happens when
* when resolving ip6.arpa dnames. */ * increasing by more than one label at once (QNAMEs with more
* than MAX_MINIMISE_COUNT labels). */
if(!(iq->qinfo_out.qname_len if(!(iq->qinfo_out.qname_len
&& dname_subdomain_c(iq->qchase.qname, && dname_subdomain_c(iq->qchase.qname,
iq->qinfo_out.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.qname_len = iq->dp->namelen;
iq->qinfo_out.qtype = LDNS_RR_TYPE_NS; iq->qinfo_out.qtype = LDNS_RR_TYPE_NS;
iq->qinfo_out.qclass = iq->qchase.qclass; iq->qinfo_out.qclass = iq->qchase.qclass;
iq->minimise_count = 0;
} }
iq->minimisation_state = MINIMISE_STATE; iq->minimisation_state = MINIMISE_STATE;
} }
if(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); dname_count_labels(iq->qinfo_out.qname);
iq->qinfo_out.qname = iq->qchase.qname; iq->qinfo_out.qname = iq->qchase.qname;
iq->qinfo_out.qname_len = iq->qchase.qname_len; iq->qinfo_out.qname_len = iq->qchase.qname_len;
iq->minimise_count++;
/* Special treatment for ip6.arpa lookups. /* Limit number of iterations for QNAMEs with more
* Reverse IPv6 dname has 34 labels, increment the IP part * than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
* (usually first 32 labels) by 8 labels (7 more than the * labels of QNAME always individually.
* default 1 label increment). */ */
if(labdiff <= 32 && if(qchaselabs > MAX_MINIMISE_COUNT && labdiff > 1 &&
dname_subdomain_c(iq->qchase.qname, ie->ip6arpa_dname)) { iq->minimise_count > MINIMISE_ONE_LAB) {
labdiff -= 7; if(iq->minimise_count < MAX_MINIMISE_COUNT) {
/* Small chance of zone cut after first label. Stop int multilabs = qchaselabs - 1 -
* minimising */ MINIMISE_ONE_LAB;
if(labdiff <= 1) int extralabs = multilabs /
labdiff = 0; 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) { if(labdiff > 1) {
@ -2068,7 +2074,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* cached as NOERROR/NODATA */ * cached as NOERROR/NODATA */
return 1; return 1;
} }
} }
if(iq->minimisation_state == SKIP_MINIMISE_STATE) if(iq->minimisation_state == SKIP_MINIMISE_STATE)
/* Do not increment qname, continue incrementing next /* Do not increment qname, continue incrementing next

View file

@ -61,6 +61,17 @@ struct rbtree_t;
#define MAX_REFERRAL_COUNT 130 #define MAX_REFERRAL_COUNT 130
/** max number of queries-sent-out. Make sure large NS set does not loop */ /** max number of queries-sent-out. Make sure large NS set does not loop */
#define MAX_SENT_COUNT 32 #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 */ /** at what query-sent-count to stop target fetch policy */
#define TARGET_FETCH_STOP 3 #define TARGET_FETCH_STOP 3
/** how nice is a server without further information, in msec /** how nice is a server without further information, in msec
@ -357,6 +368,12 @@ struct iter_qstate {
* when qname minimisation is enabled. * when qname minimisation is enabled.
*/ */
struct query_info qinfo_out; 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;
}; };
/** /**