mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-24 08:39:51 -05:00
Fix bug#307: 0x20 fallback outstanding query count, together with rec_lame,
and canonical rrset comparison. git-svn-id: file:///svn/unbound/trunk@2097 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
f12b7a8dd9
commit
3a754ae461
4 changed files with 58 additions and 5 deletions
|
|
@ -7,6 +7,11 @@
|
||||||
no more double include.
|
no more double include.
|
||||||
- More strict scrubber (Thanks to George Barwood for the idea):
|
- More strict scrubber (Thanks to George Barwood for the idea):
|
||||||
NS set must be pertinent to the query (qname subdomain nsname).
|
NS set must be pertinent to the query (qname subdomain nsname).
|
||||||
|
- Fix bug#307: In 0x20 backoff fix fallback so the number of
|
||||||
|
outstanding queries does not become -1 and block the request.
|
||||||
|
Fixed handling of recursion-lame in combination with 0x20 fallback.
|
||||||
|
Fix so RRsets are compared canonicalized and sorted if the immediate
|
||||||
|
comparison fails, this makes it work around round-robin sites.
|
||||||
|
|
||||||
23 April 2010: Wouter
|
23 April 2010: Wouter
|
||||||
- Squelch log message: sendto failed permission denied for
|
- Squelch log message: sendto failed permission denied for
|
||||||
|
|
|
||||||
|
|
@ -674,7 +674,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
reply_equal(struct reply_info* p, struct reply_info* q)
|
reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
if(p->flags != q->flags ||
|
if(p->flags != q->flags ||
|
||||||
|
|
@ -688,9 +688,30 @@ reply_equal(struct reply_info* p, struct reply_info* q)
|
||||||
p->rrset_count != q->rrset_count)
|
p->rrset_count != q->rrset_count)
|
||||||
return 0;
|
return 0;
|
||||||
for(i=0; i<p->rrset_count; i++) {
|
for(i=0; i<p->rrset_count; i++) {
|
||||||
if(!rrset_equal(p->rrsets[i], q->rrsets[i]))
|
if(!rrset_equal(p->rrsets[i], q->rrsets[i])) {
|
||||||
|
/* fallback procedure: try to sort and canonicalize */
|
||||||
|
ldns_rr_list* pl, *ql;
|
||||||
|
pl = packed_rrset_to_rr_list(p->rrsets[i], scratch);
|
||||||
|
ql = packed_rrset_to_rr_list(q->rrsets[i], scratch);
|
||||||
|
if(!pl || !ql) {
|
||||||
|
ldns_rr_list_deep_free(pl);
|
||||||
|
ldns_rr_list_deep_free(ql);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
ldns_rr_list2canonical(pl);
|
||||||
|
ldns_rr_list2canonical(ql);
|
||||||
|
ldns_rr_list_sort(pl);
|
||||||
|
ldns_rr_list_sort(ql);
|
||||||
|
if(ldns_rr_list_compare(pl, ql) != 0) {
|
||||||
|
ldns_rr_list_deep_free(pl);
|
||||||
|
ldns_rr_list_deep_free(ql);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ldns_rr_list_deep_free(pl);
|
||||||
|
ldns_rr_list_deep_free(ql);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -792,3 +813,18 @@ iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iter_dec_attempts(struct delegpt* dp, int d)
|
||||||
|
{
|
||||||
|
struct delegpt_addr* a;
|
||||||
|
for(a=dp->target_list; a; a = a->next_target) {
|
||||||
|
if(a->attempts >= OUTBOUND_MSG_RETRY) {
|
||||||
|
/* add back to result list */
|
||||||
|
a->next_result = dp->result_list;
|
||||||
|
dp->result_list = a;
|
||||||
|
}
|
||||||
|
if(a->attempts > d)
|
||||||
|
a->attempts -= d;
|
||||||
|
else a->attempts = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,9 +211,10 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp,
|
||||||
* @param p: reply one. The reply has rrset data pointers in region.
|
* @param p: reply one. The reply has rrset data pointers in region.
|
||||||
* Does not check rrset-IDs
|
* Does not check rrset-IDs
|
||||||
* @param q: reply two
|
* @param q: reply two
|
||||||
|
* @param buf: scratch buffer.
|
||||||
* @return if one and two are equal.
|
* @return if one and two are equal.
|
||||||
*/
|
*/
|
||||||
int reply_equal(struct reply_info* p, struct reply_info* q);
|
int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store in-zone glue in seperate rrset cache entries for later last-resort
|
* Store in-zone glue in seperate rrset cache entries for later last-resort
|
||||||
|
|
@ -257,4 +258,11 @@ int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
|
||||||
void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
|
void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
|
||||||
uint8_t* z);
|
uint8_t* z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove query attempts from all available ips. For 0x20.
|
||||||
|
* @param dp: delegpt.
|
||||||
|
* @param d: decrease.
|
||||||
|
*/
|
||||||
|
void iter_dec_attempts(struct delegpt* dp, int d);
|
||||||
|
|
||||||
#endif /* ITERATOR_ITER_UTILS_H */
|
#endif /* ITERATOR_ITER_UTILS_H */
|
||||||
|
|
|
||||||
|
|
@ -1416,6 +1416,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
"match for %d wanted, done.",
|
"match for %d wanted, done.",
|
||||||
(int)iq->caps_server+1, (int)naddr*3);
|
(int)iq->caps_server+1, (int)naddr*3);
|
||||||
iq->caps_fallback = 0;
|
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->state = QUERY_RESP_STATE;
|
iq->state = QUERY_RESP_STATE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -2384,7 +2387,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
goto handle_it;
|
goto handle_it;
|
||||||
} else {
|
} else {
|
||||||
/* check if reply is the same, otherwise, fail */
|
/* check if reply is the same, otherwise, fail */
|
||||||
if(!reply_equal(iq->response->rep, iq->caps_reply)) {
|
if(!reply_equal(iq->response->rep, iq->caps_reply,
|
||||||
|
qstate->env->scratch_buffer)) {
|
||||||
verbose(VERB_DETAIL, "Capsforid fallback: "
|
verbose(VERB_DETAIL, "Capsforid fallback: "
|
||||||
"getting different replies, failed");
|
"getting different replies, failed");
|
||||||
outbound_list_remove(&iq->outlist, outbound);
|
outbound_list_remove(&iq->outlist, outbound);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue