mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-08 07:49:35 -05:00
shuffle NS selection randomly for getting addresses.
git-svn-id: file:///svn/unbound/trunk@436 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
59501db3bd
commit
55630293b9
5 changed files with 57 additions and 18 deletions
|
|
@ -1,3 +1,6 @@
|
|||
19 July 2007: Wouter
|
||||
- shuffle NS selection when getting nameserver target addresses.
|
||||
|
||||
18 July 2007: Wouter
|
||||
- do not query addresses, 127.0.0.1, and ::1 by default.
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,17 @@ delegpt_add_ns(struct delegpt* dp, struct region* region, uint8_t* name)
|
|||
(void)dname_count_size_labels(name, &ns->namelen);
|
||||
ns->name = region_alloc_init(region, name, ns->namelen);
|
||||
ns->resolved = 0;
|
||||
|
||||
/* Sanity check: if the target name is at or *below* the
|
||||
* delegation point itself, then this will be (potentially)
|
||||
* unresolvable. This is the one case where glue *must*
|
||||
* have been present.
|
||||
* FIXME: at this point, this *may* be resolvable, so
|
||||
* perhaps we should issue the query anyway and let it fail.*/
|
||||
if(dname_subdomain_c(ns->name, dp->name)) {
|
||||
ns->resolved = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -374,4 +385,3 @@ delegpt_add_rrset(struct delegpt* dp, struct region* region,
|
|||
log_warn("Unknown rrset type added to delegpt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -341,3 +341,15 @@ iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
iter_ns_probability(struct ub_randstate* rnd, int n, int m)
|
||||
{
|
||||
int sel;
|
||||
if(n == m) /* 100% chance */
|
||||
return 1;
|
||||
/* we do not need secure random numbers here, but
|
||||
* we do need it to be threadsafe, so we use this */
|
||||
sel = ub_random(rnd) % m;
|
||||
return (sel < n);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ struct delegpt_addr;
|
|||
struct delegpt;
|
||||
struct region;
|
||||
struct msg_parse;
|
||||
struct ub_randstate;
|
||||
|
||||
/**
|
||||
* Process config options and set iterator module state.
|
||||
|
|
@ -105,4 +106,14 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct region* region);
|
|||
int iter_dns_store(struct module_env* env, struct dns_msg* msg,
|
||||
int is_referral);
|
||||
|
||||
/**
|
||||
* Select randomly with n/m probability.
|
||||
* For shuffle NS records for address fetching.
|
||||
* @param rnd: random table
|
||||
* @param n: probability.
|
||||
* @param m: divisor for probability.
|
||||
* @return true with n/m probability.
|
||||
*/
|
||||
int iter_ns_probability(struct ub_randstate* rnd, int n, int m);
|
||||
|
||||
#endif /* ITERATOR_ITER_UTILS_H */
|
||||
|
|
|
|||
|
|
@ -803,29 +803,34 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
struct iter_env* ie, int id, int maxtargets, int* num)
|
||||
{
|
||||
int query_count = 0;
|
||||
int target_count = 0;
|
||||
struct delegpt_ns* ns = iq->dp->nslist;
|
||||
int missing = (int)delegpt_count_missing_targets(iq->dp);
|
||||
int toget = 0;
|
||||
log_assert(maxtargets != 0); /* that would not be useful */
|
||||
|
||||
/* Generate target requests. Basically, any missing targets
|
||||
* are queried for here, regardless if it is necessary to do
|
||||
* so to continue processing. */
|
||||
if(maxtargets < 0 || maxtargets > missing)
|
||||
toget = missing;
|
||||
else toget = maxtargets;
|
||||
if(toget == 0) {
|
||||
*num = 0;
|
||||
return 1;
|
||||
}
|
||||
/* select 'toget' items from the total of 'missing' items */
|
||||
log_assert(toget <= missing);
|
||||
|
||||
/* loop over missing targets */
|
||||
for(ns = iq->dp->nslist; ns; ns = ns->next) {
|
||||
if(ns->resolved)
|
||||
continue;
|
||||
|
||||
/* Sanity check: if the target name is at or *below* the
|
||||
* delegation point itself, then this will be (potentially)
|
||||
* unresolvable. This is the one case where glue *must*
|
||||
* have been present.
|
||||
* FIXME: at this point, this *may* be resolvable, so
|
||||
* perhaps we should issue the query anyway and let it fail.*/
|
||||
if(dname_subdomain_c(ns->name, iq->dp->name)) {
|
||||
log_nametypeclass(VERB_DETAIL, "skipping target name "
|
||||
"because it should have been glue", ns->name,
|
||||
LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
/* randomly select this item with probability toget/missing */
|
||||
if(!iter_ns_probability(qstate->env->rnd, toget, missing)) {
|
||||
/* do not select this one, next; select toget number
|
||||
* of items from a list one less in size */
|
||||
missing --;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -846,10 +851,9 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
|
||||
/* mark this target as in progress. */
|
||||
ns->resolved = 1;
|
||||
|
||||
/* if maxtargets is negative, there is no maximum,
|
||||
* otherwise only query for ntarget names. */
|
||||
if(maxtargets >= 0 && ++target_count >= maxtargets)
|
||||
missing--;
|
||||
toget--;
|
||||
if(toget == 0)
|
||||
break;
|
||||
}
|
||||
*num = query_count;
|
||||
|
|
@ -1286,6 +1290,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||
rrset = reply_find_answer_rrset(&iq->qchase, iq->response->rep);
|
||||
if(rrset) {
|
||||
/* if CNAMEs have been followed - add new NS to delegpt. */
|
||||
/* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
|
||||
if(!delegpt_find_ns(foriq->dp, rrset->rk.dname,
|
||||
rrset->rk.dname_len)) {
|
||||
if(!delegpt_add_ns(foriq->dp, forq->region,
|
||||
|
|
@ -1295,8 +1300,6 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset))
|
||||
log_err("out of memory adding targets");
|
||||
} else dpns->resolved = 1; /* fail the target */
|
||||
|
||||
log_assert(dpns->resolved); /* one way or another it is now done */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue