- Fix validation failures due to EDNS backoff retries, the retry

for fetch of data has want_dnssec because the iter_indicate_dnssec
         function returns true when validation failure retry happens, and
         then the serviced query code does not fallback to noEDNS, even if
         the cache says it has this.  This helps for DLV deployment when
         the DNSSEC status is not known for sure before the lookup concludes.


git-svn-id: file:///svn/unbound/trunk@2483 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2011-08-26 09:00:43 +00:00
parent accc4a6f68
commit d56aef7b33
5 changed files with 29 additions and 12 deletions

View file

@ -1,5 +1,11 @@
26 August 2011: Wouter
- Fix num-threads 0 does not segfault, reported by Simon Deziel.
- Fix validation failures due to EDNS backoff retries, the retry
for fetch of data has want_dnssec because the iter_indicate_dnssec
function returns true when validation failure retry happens, and
then the serviced query code does not fallback to noEDNS, even if
the cache says it has this. This helps for DLV deployment when
the DNSSEC status is not known for sure before the lookup concludes.
24 August 2011: Wouter
- Applied patch from Karel Slany that fixes a memory leak in the

View file

@ -534,7 +534,7 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
int
iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
struct dns_msg* msg, uint16_t dclass)
struct dns_msg* msg, uint16_t dclass, struct module_qstate* qstate)
{
struct trust_anchor* a;
/* information not available, !env->anchors can be common */
@ -568,6 +568,15 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
regional_free_all(env->scratch);
}
}
/* on retries, we have to expect DNSSEC.
* just a blacklist of the cache is done for parentside lookups too,
* but blacklist of IPs is done for validation failures. */
if(qstate && qstate->blacklist) {
struct sock_list* p;
for(p=qstate->blacklist; p; p=p->next)
if(p->len != 0)
return 1;
}
return 0;
}

View file

@ -172,10 +172,12 @@ int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
* @param dp: delegation point.
* @param msg: delegation message, with DS if a secure referral.
* @param dclass: class of query.
* @param qstate: module query state for the query in question, for validation
* retry state.
* @return 1 if dnssec is expected, 0 if not.
*/
int iter_indicates_dnssec(struct module_env* env, struct delegpt* dp,
struct dns_msg* msg, uint16_t dclass);
struct dns_msg* msg, uint16_t dclass, struct module_qstate* qstate);
/**
* See if a message contains DNSSEC.

View file

@ -574,8 +574,8 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* there should not be any target queries. */
subiq->num_target_queries = 0;
subiq->dnssec_expected = iter_indicates_dnssec(
qstate->env, subiq->dp, NULL, subq->qinfo.qclass);
subiq->dnssec_expected = iter_indicates_dnssec(qstate->env,
subiq->dp, NULL, subq->qinfo.qclass, subq);
}
/* this module stops, our submodule starts, and does the query. */
@ -669,8 +669,8 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
* missing targets. */
subiq->num_target_queries = 0;
subiq->wait_priming_stub = 1;
subiq->dnssec_expected = iter_indicates_dnssec(
qstate->env, subiq->dp, NULL, subq->qinfo.qclass);
subiq->dnssec_expected = iter_indicates_dnssec(qstate->env,
subiq->dp, NULL, subq->qinfo.qclass, subq);
}
/* this module stops, our submodule starts, and does the query. */
@ -1191,7 +1191,7 @@ processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq,
/* if the cache reply dp equals a validation anchor or msg has DS,
* then DNSSEC RRSIGs are expected in the reply */
iq->dnssec_expected = iter_indicates_dnssec(qstate->env, iq->dp,
iq->deleg_msg, iq->qchase.qclass);
iq->deleg_msg, iq->qchase.qclass, qstate);
/* If the RD flag wasn't set, then we just finish with the
* cached referral as the response. */
@ -1254,7 +1254,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
subiq->dp = delegpt_copy(iq->dp, subq->region);
subiq->dnssec_expected = iter_indicates_dnssec(
qstate->env, subiq->dp, NULL,
subq->qinfo.qclass);
subq->qinfo.qclass, subq);
subiq->refetch_glue = 1;
} else {
subiq->dp = dns_cache_find_delegation(qstate->env,
@ -1264,7 +1264,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
if(subiq->dp) {
subiq->dnssec_expected = iter_indicates_dnssec(
qstate->env, subiq->dp, NULL,
subq->qinfo.qclass);
subq->qinfo.qclass, subq);
subiq->refetch_glue = 1;
}
}
@ -1897,7 +1897,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* see if the next dp is a trust anchor, or a DS was sent
* along, indicating dnssec is expected for next zone */
iq->dnssec_expected = iter_indicates_dnssec(qstate->env,
iq->dp, iq->response, iq->qchase.qclass);
iq->dp, iq->response, iq->qchase.qclass, qstate);
/* if dnssec, validating then also fetch the key for the DS */
if(iq->dnssec_expected && qstate->env->cfg->prefetch_key &&
!(qstate->query_flags&BIT_CD))

View file

@ -1318,7 +1318,7 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
/* even 700 msec may be too small */
rtt = 1000;
sq->status = serviced_query_PROBE_EDNS;
} else if(vs != -1) {
} else if(vs != -1 || sq->want_dnssec) {
sq->status = serviced_query_UDP_EDNS;
} else {
sq->status = serviced_query_UDP;
@ -1536,7 +1536,7 @@ serviced_tcp_send(struct serviced_query* sq, ldns_buffer* buff)
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen,
*sq->outnet->now_secs, &vs, &edns_lame_known, &rtt))
return 0;
if(vs != -1)
if(vs != -1 || sq->want_dnssec)
sq->status = serviced_query_TCP_EDNS;
else sq->status = serviced_query_TCP;
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);