mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Fix that CD flag disables DNS64 processing, returning the DNSSEC
signed AAAA denial. git-svn-id: file:///svn/unbound/trunk@3273 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
fcfbfe4030
commit
b781f2d48d
19 changed files with 134 additions and 71 deletions
|
|
@ -664,7 +664,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||||
if(!go_on)
|
if(!go_on)
|
||||||
return 1; /* skip this one, not all references satisfied */
|
return 1; /* skip this one, not all references satisfied */
|
||||||
|
|
||||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) {
|
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) {
|
||||||
log_warn("error out of memory");
|
log_warn("error out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1095,8 +1095,13 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||||
k.qname_len = nmlen;
|
k.qname_len = nmlen;
|
||||||
k.qtype = t;
|
k.qtype = t;
|
||||||
k.qclass = c;
|
k.qclass = c;
|
||||||
h = query_info_hash(&k);
|
h = query_info_hash(&k, 0);
|
||||||
slabhash_remove(worker->env.msg_cache, h, &k);
|
slabhash_remove(worker->env.msg_cache, h, &k);
|
||||||
|
if(t == LDNS_RR_TYPE_AAAA) {
|
||||||
|
/* for AAAA also flush dns64 bit_cd packet */
|
||||||
|
h = query_info_hash(&k, BIT_CD);
|
||||||
|
slabhash_remove(worker->env.msg_cache, h, &k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** flush a type */
|
/** flush a type */
|
||||||
|
|
|
||||||
|
|
@ -935,7 +935,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||||
&repinfo->addr, repinfo->addrlen);
|
&repinfo->addr, repinfo->addrlen);
|
||||||
goto send_reply;
|
goto send_reply;
|
||||||
}
|
}
|
||||||
h = query_info_hash(&qinfo);
|
h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||||
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
|
||||||
/* answer from cache - we have acquired a readlock on it */
|
/* answer from cache - we have acquired a readlock on it */
|
||||||
if(answer_from_cache(worker, &qinfo,
|
if(answer_from_cache(worker, &qinfo,
|
||||||
|
|
|
||||||
|
|
@ -399,7 +399,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||||
|
|
||||||
/* Create the new sub-query. */
|
/* Create the new sub-query. */
|
||||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
|
||||||
&subq))
|
&subq))
|
||||||
return module_error;
|
return module_error;
|
||||||
if (subq) {
|
if (subq) {
|
||||||
|
|
@ -451,7 +451,7 @@ generate_type_A_query(struct module_qstate* qstate, int id)
|
||||||
/* Start the sub-query. */
|
/* Start the sub-query. */
|
||||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
||||||
&subq))
|
0, &subq))
|
||||||
{
|
{
|
||||||
verbose(VERB_ALGO, "dns64: sub-query creation failed");
|
verbose(VERB_ALGO, "dns64: sub-query creation failed");
|
||||||
return module_error;
|
return module_error;
|
||||||
|
|
@ -520,11 +520,13 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||||
*
|
*
|
||||||
* - An internal query.
|
* - An internal query.
|
||||||
* - A query for a record type other than AAAA.
|
* - A query for a record type other than AAAA.
|
||||||
|
* - CD FLAG was set on querier
|
||||||
* - An AAAA query for which an error was returned.
|
* - An AAAA query for which an error was returned.
|
||||||
* - A successful AAAA query with an answer.
|
* - A successful AAAA query with an answer.
|
||||||
*/
|
*/
|
||||||
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|
||||||
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|
||||||
|
|| (qstate->query_flags & BIT_CD)
|
||||||
|| qstate->return_rcode != LDNS_RCODE_NOERROR
|
|| qstate->return_rcode != LDNS_RCODE_NOERROR
|
||||||
|| (qstate->return_msg &&
|
|| (qstate->return_msg &&
|
||||||
qstate->return_msg->rep &&
|
qstate->return_msg->rep &&
|
||||||
|
|
@ -813,7 +815,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
|
||||||
|
|
||||||
/* Store the generated response in cache. */
|
/* Store the generated response in cache. */
|
||||||
if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||||
0, 0, 0, NULL))
|
0, 0, 0, NULL, super->query_flags))
|
||||||
log_err("out of memory");
|
log_err("out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
18 November 2014: Wouter
|
||||||
|
- Fix that CD flag disables DNS64 processing, returning the DNSSEC
|
||||||
|
signed AAAA denial.
|
||||||
|
|
||||||
17 November 2014: Wouter
|
17 November 2014: Wouter
|
||||||
- Fix #627: SSL_CTX_load_verify_locations return code not properly
|
- Fix #627: SSL_CTX_load_verify_locations return code not properly
|
||||||
checked.
|
checked.
|
||||||
|
|
|
||||||
|
|
@ -425,10 +425,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
|
||||||
void
|
void
|
||||||
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
||||||
struct regional* region)
|
struct regional* region, uint16_t flags)
|
||||||
{
|
{
|
||||||
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
|
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
|
||||||
pside, region))
|
pside, region, flags))
|
||||||
log_err("out of memory: cannot store data in cache");
|
log_err("out of memory: cannot store data in cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -457,7 +457,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen,
|
||||||
fptr_ok(fptr_whitelist_modenv_detect_cycle(
|
fptr_ok(fptr_whitelist_modenv_detect_cycle(
|
||||||
qstate->env->detect_cycle));
|
qstate->env->detect_cycle));
|
||||||
return (*qstate->env->detect_cycle)(qstate, &qinf,
|
return (*qstate->env->detect_cycle)(qstate, &qinf,
|
||||||
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming);
|
(uint16_t)(BIT_RD|BIT_CD), qstate->is_priming,
|
||||||
|
qstate->is_valrec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
|
||||||
* @param pside: true if dp is parentside, thus message is 'fresh' and NS
|
* @param pside: true if dp is parentside, thus message is 'fresh' and NS
|
||||||
* can be prefetch-updates.
|
* can be prefetch-updates.
|
||||||
* @param region: to copy modified (cache is better) rrs back to.
|
* @param region: to copy modified (cache is better) rrs back to.
|
||||||
|
* @param flags: with BIT_CD for dns64 AAAA translated queries.
|
||||||
* @return void, because we are not interested in alloc errors,
|
* @return void, because we are not interested in alloc errors,
|
||||||
* the iterator and validator can operate on the results in their
|
* the iterator and validator can operate on the results in their
|
||||||
* scratch space (the qstate.region) and are not dependent on the cache.
|
* scratch space (the qstate.region) and are not dependent on the cache.
|
||||||
|
|
@ -132,7 +133,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
|
||||||
*/
|
*/
|
||||||
void iter_dns_store(struct module_env* env, struct query_info* qinf,
|
void iter_dns_store(struct module_env* env, struct query_info* qinf,
|
||||||
struct reply_info* rep, int is_referral, time_t leeway, int pside,
|
struct reply_info* rep, int is_referral, time_t leeway, int pside,
|
||||||
struct regional* region);
|
struct regional* region, uint16_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select randomly with n/m probability.
|
* Select randomly with n/m probability.
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||||
verbose(VERB_ALGO, "error response for prefetch in cache");
|
verbose(VERB_ALGO, "error response for prefetch in cache");
|
||||||
/* attempt to adjust the cache entry prefetch */
|
/* attempt to adjust the cache entry prefetch */
|
||||||
if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
|
if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo,
|
||||||
NORR_TTL))
|
NORR_TTL, qstate->query_flags))
|
||||||
return error_response(qstate, id, rcode);
|
return error_response(qstate, id, rcode);
|
||||||
/* if that fails (not in cache), fall through to store err */
|
/* if that fails (not in cache), fall through to store err */
|
||||||
}
|
}
|
||||||
|
|
@ -270,7 +270,8 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||||
/* do not waste time trying to validate this servfail */
|
/* do not waste time trying to validate this servfail */
|
||||||
err.security = sec_status_indeterminate;
|
err.security = sec_status_indeterminate;
|
||||||
verbose(VERB_ALGO, "store error response in message cache");
|
verbose(VERB_ALGO, "store error response in message cache");
|
||||||
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL);
|
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
|
||||||
|
qstate->query_flags);
|
||||||
return error_response(qstate, id, rcode);
|
return error_response(qstate, id, rcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -504,7 +505,8 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||||
|
|
||||||
/* attach subquery, lookup existing or make a new one */
|
/* attach subquery, lookup existing or make a new one */
|
||||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) {
|
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, 0,
|
||||||
|
&subq)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*subq_ret = subq;
|
*subq_ret = subq;
|
||||||
|
|
@ -938,7 +940,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
} else {
|
} else {
|
||||||
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
|
||||||
iq->qchase.qname_len, iq->qchase.qtype,
|
iq->qchase.qname_len, iq->qchase.qtype,
|
||||||
iq->qchase.qclass, qstate->region, qstate->env->scratch);
|
iq->qchase.qclass, qstate->query_flags,
|
||||||
|
qstate->region, qstate->env->scratch);
|
||||||
if(!msg && qstate->env->neg_cache) {
|
if(!msg && qstate->env->neg_cache) {
|
||||||
/* lookup in negative cache; may result in
|
/* lookup in negative cache; may result in
|
||||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||||
|
|
@ -1991,7 +1994,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||||
iq->dp&&iq->dp->has_parent_side_NS,
|
iq->dp&&iq->dp->has_parent_side_NS,
|
||||||
qstate->region);
|
qstate->region, qstate->query_flags);
|
||||||
/* close down outstanding requests to be discarded */
|
/* close down outstanding requests to be discarded */
|
||||||
outbound_list_clear(&iq->outlist);
|
outbound_list_clear(&iq->outlist);
|
||||||
iq->num_current_queries = 0;
|
iq->num_current_queries = 0;
|
||||||
|
|
@ -2029,7 +2032,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* Store the referral under the current query */
|
/* Store the referral under the current query */
|
||||||
/* no prefetch-leeway, since its not the answer */
|
/* no prefetch-leeway, since its not the answer */
|
||||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
iq->response->rep, 1, 0, 0, NULL);
|
iq->response->rep, 1, 0, 0, NULL, 0);
|
||||||
if(iq->store_parent_NS)
|
if(iq->store_parent_NS)
|
||||||
iter_store_parentside_NS(qstate->env,
|
iter_store_parentside_NS(qstate->env,
|
||||||
iq->response->rep);
|
iq->response->rep);
|
||||||
|
|
@ -2128,7 +2131,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* prefetchleeway applied because this updates answer parts */
|
/* prefetchleeway applied because this updates answer parts */
|
||||||
iter_dns_store(qstate->env, &iq->response->qinfo,
|
iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
iq->response->rep, 1, qstate->prefetch_leeway,
|
iq->response->rep, 1, qstate->prefetch_leeway,
|
||||||
iq->dp&&iq->dp->has_parent_side_NS, NULL);
|
iq->dp&&iq->dp->has_parent_side_NS, NULL,
|
||||||
|
qstate->query_flags);
|
||||||
/* set the current request's qname to the new value. */
|
/* set the current request's qname to the new value. */
|
||||||
iq->qchase.qname = sname;
|
iq->qchase.qname = sname;
|
||||||
iq->qchase.qname_len = snamelen;
|
iq->qchase.qname_len = snamelen;
|
||||||
|
|
@ -2209,7 +2213,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return priming query results to interestes super querystates.
|
* Return priming query results to interested super querystates.
|
||||||
*
|
*
|
||||||
* Sets the delegation point and delegation message (not nonRD queries).
|
* Sets the delegation point and delegation message (not nonRD queries).
|
||||||
* This is a callback from walk_supers.
|
* This is a callback from walk_supers.
|
||||||
|
|
@ -2640,7 +2644,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
iter_dns_store(qstate->env, &qstate->qinfo,
|
iter_dns_store(qstate->env, &qstate->qinfo,
|
||||||
iq->response->rep, 0, qstate->prefetch_leeway,
|
iq->response->rep, 0, qstate->prefetch_leeway,
|
||||||
iq->dp&&iq->dp->has_parent_side_NS,
|
iq->dp&&iq->dp->has_parent_side_NS,
|
||||||
qstate->region);
|
qstate->region, qstate->query_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
|
||||||
}
|
}
|
||||||
|
|
||||||
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
|
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
|
||||||
qstate->prefetch_leeway, 0, NULL);
|
qstate->prefetch_leeway, 0, NULL, qstate->query_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invalidate the message associated with query_info stored in message cache */
|
/* Invalidate the message associated with query_info stored in message cache */
|
||||||
|
|
@ -78,7 +78,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin
|
||||||
struct reply_info *r;
|
struct reply_info *r;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
|
||||||
h = query_info_hash(qinfo);
|
h = query_info_hash(qinfo, qstate->query_flags);
|
||||||
if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0)))
|
if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0)))
|
||||||
{
|
{
|
||||||
r = (struct reply_info*)(e->data);
|
r = (struct reply_info*)(e->data);
|
||||||
|
|
|
||||||
34
services/cache/dns.c
vendored
34
services/cache/dns.c
vendored
|
|
@ -184,7 +184,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||||
/** lookup message in message cache */
|
/** lookup message in message cache */
|
||||||
static struct msgreply_entry*
|
static struct msgreply_entry*
|
||||||
msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||||
uint16_t qtype, uint16_t qclass, time_t now, int wr)
|
uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr)
|
||||||
{
|
{
|
||||||
struct lruhash_entry* e;
|
struct lruhash_entry* e;
|
||||||
struct query_info k;
|
struct query_info k;
|
||||||
|
|
@ -194,7 +194,7 @@ msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||||
k.qname_len = qnamelen;
|
k.qname_len = qnamelen;
|
||||||
k.qtype = qtype;
|
k.qtype = qtype;
|
||||||
k.qclass = qclass;
|
k.qclass = qclass;
|
||||||
h = query_info_hash(&k);
|
h = query_info_hash(&k, flags);
|
||||||
e = slabhash_lookup(env->msg_cache, h, &k, wr);
|
e = slabhash_lookup(env->msg_cache, h, &k, wr);
|
||||||
|
|
||||||
if(!e) return NULL;
|
if(!e) return NULL;
|
||||||
|
|
@ -226,8 +226,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||||
addr_to_additional(akey, region, *msg, now);
|
addr_to_additional(akey, region, *msg, now);
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
} else {
|
} else {
|
||||||
|
/* BIT_CD on false because delegpt lookup does
|
||||||
|
* not use dns64 translation */
|
||||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
LDNS_RR_TYPE_A, qclass, now, 0);
|
LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||||
if(neg) {
|
if(neg) {
|
||||||
delegpt_add_neg_msg(dp, neg);
|
delegpt_add_neg_msg(dp, neg);
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
|
|
@ -244,8 +246,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||||
addr_to_additional(akey, region, *msg, now);
|
addr_to_additional(akey, region, *msg, now);
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
} else {
|
} else {
|
||||||
|
/* BIT_CD on false because delegpt lookup does
|
||||||
|
* not use dns64 translation */
|
||||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
LDNS_RR_TYPE_AAAA, qclass, now, 0);
|
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||||
if(neg) {
|
if(neg) {
|
||||||
delegpt_add_neg_msg(dp, neg);
|
delegpt_add_neg_msg(dp, neg);
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
|
|
@ -276,8 +280,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||||
ns->name, LDNS_RR_TYPE_A, qclass);
|
ns->name, LDNS_RR_TYPE_A, qclass);
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
} else {
|
} else {
|
||||||
|
/* BIT_CD on false because delegpt lookup does
|
||||||
|
* not use dns64 translation */
|
||||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
LDNS_RR_TYPE_A, qclass, now, 0);
|
LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||||
if(neg) {
|
if(neg) {
|
||||||
delegpt_add_neg_msg(dp, neg);
|
delegpt_add_neg_msg(dp, neg);
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
|
|
@ -294,8 +300,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||||
ns->name, LDNS_RR_TYPE_AAAA, qclass);
|
ns->name, LDNS_RR_TYPE_AAAA, qclass);
|
||||||
lock_rw_unlock(&akey->entry.lock);
|
lock_rw_unlock(&akey->entry.lock);
|
||||||
} else {
|
} else {
|
||||||
|
/* BIT_CD on false because delegpt lookup does
|
||||||
|
* not use dns64 translation */
|
||||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||||
LDNS_RR_TYPE_AAAA, qclass, now, 0);
|
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||||
if(neg) {
|
if(neg) {
|
||||||
delegpt_add_neg_msg(dp, neg);
|
delegpt_add_neg_msg(dp, neg);
|
||||||
lock_rw_unlock(&neg->entry.lock);
|
lock_rw_unlock(&neg->entry.lock);
|
||||||
|
|
@ -626,7 +634,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||||
struct dns_msg*
|
struct dns_msg*
|
||||||
dns_cache_lookup(struct module_env* env,
|
dns_cache_lookup(struct module_env* env,
|
||||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||||
struct regional* region, struct regional* scratch)
|
uint16_t flags, struct regional* region, struct regional* scratch)
|
||||||
{
|
{
|
||||||
struct lruhash_entry* e;
|
struct lruhash_entry* e;
|
||||||
struct query_info k;
|
struct query_info k;
|
||||||
|
|
@ -639,7 +647,7 @@ dns_cache_lookup(struct module_env* env,
|
||||||
k.qname_len = qnamelen;
|
k.qname_len = qnamelen;
|
||||||
k.qtype = qtype;
|
k.qtype = qtype;
|
||||||
k.qclass = qclass;
|
k.qclass = qclass;
|
||||||
h = query_info_hash(&k);
|
h = query_info_hash(&k, flags);
|
||||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||||
if(e) {
|
if(e) {
|
||||||
struct msgreply_entry* key = (struct msgreply_entry*)e->key;
|
struct msgreply_entry* key = (struct msgreply_entry*)e->key;
|
||||||
|
|
@ -716,7 +724,7 @@ dns_cache_lookup(struct module_env* env,
|
||||||
if(env->cfg->harden_below_nxdomain)
|
if(env->cfg->harden_below_nxdomain)
|
||||||
while(!dname_is_root(k.qname)) {
|
while(!dname_is_root(k.qname)) {
|
||||||
dname_remove_label(&k.qname, &k.qname_len);
|
dname_remove_label(&k.qname, &k.qname_len);
|
||||||
h = query_info_hash(&k);
|
h = query_info_hash(&k, flags);
|
||||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||||
if(e) {
|
if(e) {
|
||||||
struct reply_info* data = (struct reply_info*)e->data;
|
struct reply_info* data = (struct reply_info*)e->data;
|
||||||
|
|
@ -741,7 +749,7 @@ dns_cache_lookup(struct module_env* env,
|
||||||
int
|
int
|
||||||
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
|
||||||
struct regional* region)
|
struct regional* region, uint16_t flags)
|
||||||
{
|
{
|
||||||
struct reply_info* rep = NULL;
|
struct reply_info* rep = NULL;
|
||||||
/* alloc, malloc properly (not in region, like msg is) */
|
/* alloc, malloc properly (not in region, like msg is) */
|
||||||
|
|
@ -786,7 +794,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
* Not AA from cache. Not CD in cache (depends on client bit). */
|
* Not AA from cache. Not CD in cache (depends on client bit). */
|
||||||
rep->flags |= (BIT_RA | BIT_QR);
|
rep->flags |= (BIT_RA | BIT_QR);
|
||||||
rep->flags &= ~(BIT_AA | BIT_CD);
|
rep->flags &= ~(BIT_AA | BIT_CD);
|
||||||
h = query_info_hash(&qinf);
|
h = query_info_hash(&qinf, flags);
|
||||||
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
|
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
|
||||||
region);
|
region);
|
||||||
/* qname is used inside query_info_entrysetup, and set to
|
/* qname is used inside query_info_entrysetup, and set to
|
||||||
|
|
@ -798,11 +806,11 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
|
|
||||||
int
|
int
|
||||||
dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
|
dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
|
||||||
time_t adjust)
|
time_t adjust, uint16_t flags)
|
||||||
{
|
{
|
||||||
struct msgreply_entry* msg;
|
struct msgreply_entry* msg;
|
||||||
msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
||||||
qinfo->qtype, qinfo->qclass, *env->now, 1);
|
qinfo->qtype, qinfo->qclass, flags, *env->now, 1);
|
||||||
if(msg) {
|
if(msg) {
|
||||||
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
||||||
if(rep) {
|
if(rep) {
|
||||||
|
|
|
||||||
9
services/cache/dns.h
vendored
9
services/cache/dns.h
vendored
|
|
@ -79,11 +79,12 @@ struct dns_msg {
|
||||||
* can be updated to full TTL even in prefetch situations.
|
* can be updated to full TTL even in prefetch situations.
|
||||||
* @param region: region to allocate better entries from cache into.
|
* @param region: region to allocate better entries from cache into.
|
||||||
* (used when is_referral is false).
|
* (used when is_referral is false).
|
||||||
|
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||||
* @return 0 on alloc error (out of memory).
|
* @return 0 on alloc error (out of memory).
|
||||||
*/
|
*/
|
||||||
int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
int dns_cache_store(struct module_env* env, struct query_info* qinf,
|
||||||
struct reply_info* rep, int is_referral, time_t leeway, int pside,
|
struct reply_info* rep, int is_referral, time_t leeway, int pside,
|
||||||
struct regional* region);
|
struct regional* region, uint16_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store message in the cache. Stores in message cache and rrset cache.
|
* Store message in the cache. Stores in message cache and rrset cache.
|
||||||
|
|
@ -132,6 +133,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
|
||||||
* @param qnamelen: length of qname.
|
* @param qnamelen: length of qname.
|
||||||
* @param qtype: query type.
|
* @param qtype: query type.
|
||||||
* @param qclass: query class.
|
* @param qclass: query class.
|
||||||
|
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||||
* @param region: where to allocate result.
|
* @param region: where to allocate result.
|
||||||
* @param scratch: where to allocate temporary data.
|
* @param scratch: where to allocate temporary data.
|
||||||
* @return new response message (alloced in region, rrsets do not have IDs).
|
* @return new response message (alloced in region, rrsets do not have IDs).
|
||||||
|
|
@ -140,7 +142,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
|
||||||
*/
|
*/
|
||||||
struct dns_msg* dns_cache_lookup(struct module_env* env,
|
struct dns_msg* dns_cache_lookup(struct module_env* env,
|
||||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||||
struct regional* region, struct regional* scratch);
|
uint16_t flags, struct regional* region, struct regional* scratch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find and add A and AAAA records for missing nameservers in delegpt
|
* find and add A and AAAA records for missing nameservers in delegpt
|
||||||
|
|
@ -186,9 +188,10 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||||
* @param env: module environment with caches and time.
|
* @param env: module environment with caches and time.
|
||||||
* @param qinfo: query info for the query that needs adjustment.
|
* @param qinfo: query info for the query that needs adjustment.
|
||||||
* @param adjust: time in seconds to add to the prefetch_leeway.
|
* @param adjust: time in seconds to add to the prefetch_leeway.
|
||||||
|
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
|
||||||
* @return false if not in cache. true if added.
|
* @return false if not in cache. true if added.
|
||||||
*/
|
*/
|
||||||
int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
|
int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo,
|
||||||
time_t adjust);
|
time_t adjust, uint16_t flags);
|
||||||
|
|
||||||
#endif /* SERVICES_CACHE_DNS_H */
|
#endif /* SERVICES_CACHE_DNS_H */
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,11 @@ mesh_state_compare(const void* ap, const void* bp)
|
||||||
if(!a->s.is_priming && b->s.is_priming)
|
if(!a->s.is_priming && b->s.is_priming)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if(a->s.is_valrec && !b->s.is_valrec)
|
||||||
|
return -1;
|
||||||
|
if(!a->s.is_valrec && b->s.is_valrec)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD))
|
if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD))
|
||||||
return -1;
|
return -1;
|
||||||
if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD))
|
if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD))
|
||||||
|
|
@ -277,11 +282,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||||
uint16_t qid)
|
uint16_t qid)
|
||||||
{
|
{
|
||||||
/* do not use CD flag from user for mesh state, we want the CD-query
|
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0, 0);
|
||||||
* to receive validation anyway, to protect out cache contents and
|
|
||||||
* avoid bad-data in this cache that a downstream validator cannot
|
|
||||||
* remove from this cache */
|
|
||||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
|
||||||
int was_detached = 0;
|
int was_detached = 0;
|
||||||
int was_noreply = 0;
|
int was_noreply = 0;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
|
@ -311,7 +312,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
#ifdef UNBOUND_DEBUG
|
#ifdef UNBOUND_DEBUG
|
||||||
struct rbnode_t* n;
|
struct rbnode_t* n;
|
||||||
#endif
|
#endif
|
||||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0, 0);
|
||||||
if(!s) {
|
if(!s) {
|
||||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||||
|
|
@ -375,7 +376,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
|
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
|
||||||
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
|
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
|
||||||
{
|
{
|
||||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0, 0);
|
||||||
int was_detached = 0;
|
int was_detached = 0;
|
||||||
int was_noreply = 0;
|
int was_noreply = 0;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
|
@ -386,7 +387,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
#ifdef UNBOUND_DEBUG
|
#ifdef UNBOUND_DEBUG
|
||||||
struct rbnode_t* n;
|
struct rbnode_t* n;
|
||||||
#endif
|
#endif
|
||||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0, 0);
|
||||||
if(!s) {
|
if(!s) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -428,7 +429,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
uint16_t qflags, time_t leeway)
|
uint16_t qflags, time_t leeway)
|
||||||
{
|
{
|
||||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0, 0);
|
||||||
#ifdef UNBOUND_DEBUG
|
#ifdef UNBOUND_DEBUG
|
||||||
struct rbnode_t* n;
|
struct rbnode_t* n;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -447,7 +448,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
mesh->stats_dropped ++;
|
mesh->stats_dropped ++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0, 0);
|
||||||
if(!s) {
|
if(!s) {
|
||||||
log_err("prefetch mesh_state_create: out of memory");
|
log_err("prefetch mesh_state_create: out of memory");
|
||||||
return;
|
return;
|
||||||
|
|
@ -496,7 +497,7 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||||
|
|
||||||
struct mesh_state*
|
struct mesh_state*
|
||||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||||
uint16_t qflags, int prime)
|
uint16_t qflags, int prime, int valrec)
|
||||||
{
|
{
|
||||||
struct regional* region = alloc_reg_obtain(env->alloc);
|
struct regional* region = alloc_reg_obtain(env->alloc);
|
||||||
struct mesh_state* mstate;
|
struct mesh_state* mstate;
|
||||||
|
|
@ -533,6 +534,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||||
/* remove all weird bits from qflags */
|
/* remove all weird bits from qflags */
|
||||||
mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD));
|
mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD));
|
||||||
mstate->s.is_priming = prime;
|
mstate->s.is_priming = prime;
|
||||||
|
mstate->s.is_valrec = valrec;
|
||||||
mstate->s.reply = NULL;
|
mstate->s.reply = NULL;
|
||||||
mstate->s.region = region;
|
mstate->s.region = region;
|
||||||
mstate->s.curmod = 0;
|
mstate->s.curmod = 0;
|
||||||
|
|
@ -679,12 +681,14 @@ void mesh_detach_subs(struct module_qstate* qstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t qflags, int prime, struct module_qstate** newq)
|
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
|
||||||
{
|
{
|
||||||
/* find it, if not, create it */
|
/* find it, if not, create it */
|
||||||
struct mesh_area* mesh = qstate->env->mesh;
|
struct mesh_area* mesh = qstate->env->mesh;
|
||||||
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime);
|
struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime,
|
||||||
|
valrec);
|
||||||
int was_detached;
|
int was_detached;
|
||||||
|
log_info("mesh attach sub: myvalrec is %d", qstate->is_valrec);
|
||||||
if(mesh_detect_cycle_found(qstate, sub)) {
|
if(mesh_detect_cycle_found(qstate, sub)) {
|
||||||
verbose(VERB_ALGO, "attach failed, cycle detected");
|
verbose(VERB_ALGO, "attach failed, cycle detected");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -694,7 +698,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
struct rbnode_t* n;
|
struct rbnode_t* n;
|
||||||
#endif
|
#endif
|
||||||
/* create a new one */
|
/* create a new one */
|
||||||
sub = mesh_state_create(qstate->env, qinfo, qflags, prime);
|
sub = mesh_state_create(qstate->env, qinfo, qflags, prime,
|
||||||
|
valrec);
|
||||||
if(!sub) {
|
if(!sub) {
|
||||||
log_err("mesh_attach_sub: out of memory");
|
log_err("mesh_attach_sub: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -941,13 +946,14 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||||
struct query_info* qinfo, uint16_t qflags, int prime)
|
struct query_info* qinfo, uint16_t qflags, int prime, int valrec)
|
||||||
{
|
{
|
||||||
struct mesh_state key;
|
struct mesh_state key;
|
||||||
struct mesh_state* result;
|
struct mesh_state* result;
|
||||||
|
|
||||||
key.node.key = &key;
|
key.node.key = &key;
|
||||||
key.s.is_priming = prime;
|
key.s.is_priming = prime;
|
||||||
|
key.s.is_valrec = valrec;
|
||||||
key.s.qinfo = *qinfo;
|
key.s.qinfo = *qinfo;
|
||||||
key.s.query_flags = qflags;
|
key.s.query_flags = qflags;
|
||||||
|
|
||||||
|
|
@ -1107,8 +1113,9 @@ mesh_log_list(struct mesh_area* mesh)
|
||||||
struct mesh_state* m;
|
struct mesh_state* m;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
||||||
snprintf(buf, sizeof(buf), "%d%s%s%s%s%s mod%d %s%s",
|
snprintf(buf, sizeof(buf), "%d%s%s%s%s%s%s mod%d %s%s",
|
||||||
num++, (m->s.is_priming)?"p":"", /* prime */
|
num++, (m->s.is_priming)?"p":"", /* prime */
|
||||||
|
(m->s.is_valrec)?"v":"", /* prime */
|
||||||
(m->s.query_flags&BIT_RD)?"RD":"",
|
(m->s.query_flags&BIT_RD)?"RD":"",
|
||||||
(m->s.query_flags&BIT_CD)?"CD":"",
|
(m->s.query_flags&BIT_CD)?"CD":"",
|
||||||
(m->super_set.count==0)?"d":"", /* detached */
|
(m->super_set.count==0)?"d":"", /* detached */
|
||||||
|
|
@ -1178,10 +1185,11 @@ mesh_get_mem(struct mesh_area* mesh)
|
||||||
|
|
||||||
int
|
int
|
||||||
mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t flags, int prime)
|
uint16_t flags, int prime, int valrec)
|
||||||
{
|
{
|
||||||
struct mesh_area* mesh = qstate->env->mesh;
|
struct mesh_area* mesh = qstate->env->mesh;
|
||||||
struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime);
|
struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime,
|
||||||
|
valrec);
|
||||||
return mesh_detect_cycle_found(qstate, dep_m);
|
return mesh_detect_cycle_found(qstate, dep_m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -353,12 +353,13 @@ void mesh_detach_subs(struct module_qstate* qstate);
|
||||||
* @param qinfo: what to query for (copied).
|
* @param qinfo: what to query for (copied).
|
||||||
* @param qflags: what flags to use (RD / CD flag or not).
|
* @param qflags: what flags to use (RD / CD flag or not).
|
||||||
* @param prime: if it is a (stub) priming query.
|
* @param prime: if it is a (stub) priming query.
|
||||||
|
* @param valrec: if it is a validation recursion query (lookup of key, DS).
|
||||||
* @param newq: If the new subquery needs initialisation, it is returned,
|
* @param newq: If the new subquery needs initialisation, it is returned,
|
||||||
* otherwise NULL is returned.
|
* otherwise NULL is returned.
|
||||||
* @return: false on error, true if success (and init may be needed).
|
* @return: false on error, true if success (and init may be needed).
|
||||||
*/
|
*/
|
||||||
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t qflags, int prime, struct module_qstate** newq);
|
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query state is done, send messages to reply entries.
|
* Query state is done, send messages to reply entries.
|
||||||
|
|
@ -406,10 +407,12 @@ void mesh_state_delete(struct module_qstate* qstate);
|
||||||
* @param qinfo: query info that the mesh is for.
|
* @param qinfo: query info that the mesh is for.
|
||||||
* @param qflags: flags for query (RD / CD flag).
|
* @param qflags: flags for query (RD / CD flag).
|
||||||
* @param prime: if true, it is a priming query, set is_priming on mesh state.
|
* @param prime: if true, it is a priming query, set is_priming on mesh state.
|
||||||
|
* @param valrec: if true, it is a validation recursion query, and sets
|
||||||
|
* is_valrec on the mesh state.
|
||||||
* @return: new mesh state or NULL on allocation error.
|
* @return: new mesh state or NULL on allocation error.
|
||||||
*/
|
*/
|
||||||
struct mesh_state* mesh_state_create(struct module_env* env,
|
struct mesh_state* mesh_state_create(struct module_env* env,
|
||||||
struct query_info* qinfo, uint16_t qflags, int prime);
|
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleanup a mesh state and its query state. Does not do rbtree or
|
* Cleanup a mesh state and its query state. Does not do rbtree or
|
||||||
|
|
@ -432,10 +435,11 @@ void mesh_delete_all(struct mesh_area* mesh);
|
||||||
* @param qinfo: what query
|
* @param qinfo: what query
|
||||||
* @param qflags: if RD / CD bit is set or not.
|
* @param qflags: if RD / CD bit is set or not.
|
||||||
* @param prime: if it is a priming query.
|
* @param prime: if it is a priming query.
|
||||||
|
* @param valrec: if it is a validation-recursion query.
|
||||||
* @return: mesh state or NULL if not found.
|
* @return: mesh state or NULL if not found.
|
||||||
*/
|
*/
|
||||||
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||||
struct query_info* qinfo, uint16_t qflags, int prime);
|
struct query_info* qinfo, uint16_t qflags, int prime, int valrec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup attachment super/sub relation between super and sub mesh state.
|
* Setup attachment super/sub relation between super and sub mesh state.
|
||||||
|
|
@ -523,13 +527,14 @@ size_t mesh_get_mem(struct mesh_area* mesh);
|
||||||
* @param qinfo: query info for dependency.
|
* @param qinfo: query info for dependency.
|
||||||
* @param flags: query flags of dependency.
|
* @param flags: query flags of dependency.
|
||||||
* @param prime: if dependency is a priming query or not.
|
* @param prime: if dependency is a priming query or not.
|
||||||
|
* @param valrec: if it is a validation recursion query (lookup of key, DS).
|
||||||
* @return true if the name,type,class exists and the given qstate mesh exists
|
* @return true if the name,type,class exists and the given qstate mesh exists
|
||||||
* as a dependency of that name. Thus if qstate becomes dependent on
|
* as a dependency of that name. Thus if qstate becomes dependent on
|
||||||
* name,type,class then a cycle is created, this is return value 1.
|
* name,type,class then a cycle is created, this is return value 1.
|
||||||
* Too large to search is value 2 (also true).
|
* Too large to search is value 2 (also true).
|
||||||
*/
|
*/
|
||||||
int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t flags, int prime);
|
uint16_t flags, int prime, int valrec);
|
||||||
|
|
||||||
/** compare two mesh_states */
|
/** compare two mesh_states */
|
||||||
int mesh_state_compare(const void* ap, const void* bp);
|
int mesh_state_compare(const void* ap, const void* bp);
|
||||||
|
|
|
||||||
|
|
@ -576,10 +576,12 @@ reply_info_delete(void* d, void* ATTR_UNUSED(arg))
|
||||||
}
|
}
|
||||||
|
|
||||||
hashvalue_t
|
hashvalue_t
|
||||||
query_info_hash(struct query_info *q)
|
query_info_hash(struct query_info *q, uint16_t flags)
|
||||||
{
|
{
|
||||||
hashvalue_t h = 0xab;
|
hashvalue_t h = 0xab;
|
||||||
h = hashlittle(&q->qtype, sizeof(q->qtype), h);
|
h = hashlittle(&q->qtype, sizeof(q->qtype), h);
|
||||||
|
if(q->qtype == LDNS_RR_TYPE_AAAA && (flags&BIT_CD))
|
||||||
|
h++;
|
||||||
h = hashlittle(&q->qclass, sizeof(q->qclass), h);
|
h = hashlittle(&q->qclass, sizeof(q->qclass), h);
|
||||||
h = dname_query_hash(q->qname, h);
|
h = dname_query_hash(q->qname, h);
|
||||||
return h;
|
return h;
|
||||||
|
|
|
||||||
|
|
@ -305,8 +305,9 @@ void query_entry_delete(void *q, void* arg);
|
||||||
/** delete reply_info data structure */
|
/** delete reply_info data structure */
|
||||||
void reply_info_delete(void* d, void* arg);
|
void reply_info_delete(void* d, void* arg);
|
||||||
|
|
||||||
/** calculate hash value of query_info, lowercases the qname */
|
/** calculate hash value of query_info, lowercases the qname,
|
||||||
hashvalue_t query_info_hash(struct query_info *q);
|
* uses CD flag for AAAA qtype */
|
||||||
|
hashvalue_t query_info_hash(struct query_info *q, uint16_t flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup query info entry
|
* Setup query info entry
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ fptr_whitelist_modenv_detach_subs(void (*fptr)(
|
||||||
int
|
int
|
||||||
fptr_whitelist_modenv_attach_sub(int (*fptr)(
|
fptr_whitelist_modenv_attach_sub(int (*fptr)(
|
||||||
struct module_qstate* qstate, struct query_info* qinfo,
|
struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t qflags, int prime, struct module_qstate** newq))
|
uint16_t qflags, int prime, int valrec, struct module_qstate** newq))
|
||||||
{
|
{
|
||||||
if(fptr == &mesh_attach_sub) return 1;
|
if(fptr == &mesh_attach_sub) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -296,7 +296,7 @@ fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq))
|
||||||
int
|
int
|
||||||
fptr_whitelist_modenv_detect_cycle(int (*fptr)(
|
fptr_whitelist_modenv_detect_cycle(int (*fptr)(
|
||||||
struct module_qstate* qstate, struct query_info* qinfo,
|
struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t flags, int prime))
|
uint16_t flags, int prime, int valrec))
|
||||||
{
|
{
|
||||||
if(fptr == &mesh_detect_cycle) return 1;
|
if(fptr == &mesh_detect_cycle) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ int fptr_whitelist_modenv_detach_subs(void (*fptr)(
|
||||||
*/
|
*/
|
||||||
int fptr_whitelist_modenv_attach_sub(int (*fptr)(
|
int fptr_whitelist_modenv_attach_sub(int (*fptr)(
|
||||||
struct module_qstate* qstate, struct query_info* qinfo,
|
struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t qflags, int prime, struct module_qstate** newq));
|
uint16_t qflags, int prime, int valrec, struct module_qstate** newq));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check function pointer whitelist for module_env kill_sub callback values.
|
* Check function pointer whitelist for module_env kill_sub callback values.
|
||||||
|
|
@ -251,7 +251,7 @@ int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq));
|
||||||
*/
|
*/
|
||||||
int fptr_whitelist_modenv_detect_cycle(int (*fptr)(
|
int fptr_whitelist_modenv_detect_cycle(int (*fptr)(
|
||||||
struct module_qstate* qstate, struct query_info* qinfo,
|
struct module_qstate* qstate, struct query_info* qinfo,
|
||||||
uint16_t flags, int prime));
|
uint16_t flags, int prime, int valrec));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check function pointer whitelist for module init call values.
|
* Check function pointer whitelist for module init call values.
|
||||||
|
|
|
||||||
|
|
@ -256,13 +256,14 @@ struct module_env {
|
||||||
* @param qinfo: what to query for (copied).
|
* @param qinfo: what to query for (copied).
|
||||||
* @param qflags: what flags to use (RD, CD flag or not).
|
* @param qflags: what flags to use (RD, CD flag or not).
|
||||||
* @param prime: if it is a (stub) priming query.
|
* @param prime: if it is a (stub) priming query.
|
||||||
|
* @param valrec: validation lookup recursion, does not need validation
|
||||||
* @param newq: If the new subquery needs initialisation, it is
|
* @param newq: If the new subquery needs initialisation, it is
|
||||||
* returned, otherwise NULL is returned.
|
* returned, otherwise NULL is returned.
|
||||||
* @return: false on error, true if success (and init may be needed).
|
* @return: false on error, true if success (and init may be needed).
|
||||||
*/
|
*/
|
||||||
int (*attach_sub)(struct module_qstate* qstate,
|
int (*attach_sub)(struct module_qstate* qstate,
|
||||||
struct query_info* qinfo, uint16_t qflags, int prime,
|
struct query_info* qinfo, uint16_t qflags, int prime,
|
||||||
struct module_qstate** newq);
|
int valrec, struct module_qstate** newq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kill newly attached sub. If attach_sub returns newq for
|
* Kill newly attached sub. If attach_sub returns newq for
|
||||||
|
|
@ -280,13 +281,15 @@ struct module_env {
|
||||||
* @param qinfo: query info for dependency.
|
* @param qinfo: query info for dependency.
|
||||||
* @param flags: query flags of dependency, RD/CD flags.
|
* @param flags: query flags of dependency, RD/CD flags.
|
||||||
* @param prime: if dependency is a priming query or not.
|
* @param prime: if dependency is a priming query or not.
|
||||||
|
* @param valrec: validation lookup recursion, does not need validation
|
||||||
* @return true if the name,type,class exists and the given
|
* @return true if the name,type,class exists and the given
|
||||||
* qstate mesh exists as a dependency of that name. Thus
|
* qstate mesh exists as a dependency of that name. Thus
|
||||||
* if qstate becomes dependent on name,type,class then a
|
* if qstate becomes dependent on name,type,class then a
|
||||||
* cycle is created.
|
* cycle is created.
|
||||||
*/
|
*/
|
||||||
int (*detect_cycle)(struct module_qstate* qstate,
|
int (*detect_cycle)(struct module_qstate* qstate,
|
||||||
struct query_info* qinfo, uint16_t flags, int prime);
|
struct query_info* qinfo, uint16_t flags, int prime,
|
||||||
|
int valrec);
|
||||||
|
|
||||||
/** region for temporary usage. May be cleared after operate() call. */
|
/** region for temporary usage. May be cleared after operate() call. */
|
||||||
struct regional* scratch;
|
struct regional* scratch;
|
||||||
|
|
@ -397,6 +400,9 @@ struct module_qstate {
|
||||||
uint16_t query_flags;
|
uint16_t query_flags;
|
||||||
/** if this is a (stub or root) priming query (with hints) */
|
/** if this is a (stub or root) priming query (with hints) */
|
||||||
int is_priming;
|
int is_priming;
|
||||||
|
/** if this is a validation recursion query that does not get
|
||||||
|
* validation itself */
|
||||||
|
int is_valrec;
|
||||||
|
|
||||||
/** comm_reply contains server replies */
|
/** comm_reply contains server replies */
|
||||||
struct comm_reply* reply;
|
struct comm_reply* reply;
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,11 @@ needs_validation(struct module_qstate* qstate, int ret_rc,
|
||||||
verbose(VERB_ALGO, "not validating response due to CD bit");
|
verbose(VERB_ALGO, "not validating response due to CD bit");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if(qstate->is_valrec) {
|
||||||
|
verbose(VERB_ALGO, "not validating response, is valrec"
|
||||||
|
"(validation recursion lookup)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(ret_rc != LDNS_RCODE_NOERROR || !ret_msg)
|
if(ret_rc != LDNS_RCODE_NOERROR || !ret_msg)
|
||||||
rcode = ret_rc;
|
rcode = ret_rc;
|
||||||
|
|
@ -351,14 +356,20 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
|
||||||
struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id];
|
struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id];
|
||||||
struct module_qstate* newq;
|
struct module_qstate* newq;
|
||||||
struct query_info ask;
|
struct query_info ask;
|
||||||
|
int valrec;
|
||||||
ask.qname = name;
|
ask.qname = name;
|
||||||
ask.qname_len = namelen;
|
ask.qname_len = namelen;
|
||||||
ask.qtype = qtype;
|
ask.qtype = qtype;
|
||||||
ask.qclass = qclass;
|
ask.qclass = qclass;
|
||||||
log_query_info(VERB_ALGO, "generate request", &ask);
|
log_query_info(VERB_ALGO, "generate request", &ask);
|
||||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||||
|
/* enable valrec flag to avoid recursion to the same validation
|
||||||
|
* routine, this lookup is simply a lookup. DLVs need validation */
|
||||||
|
if(qtype == LDNS_RR_TYPE_DLV)
|
||||||
|
valrec = 0;
|
||||||
|
else valrec = 1;
|
||||||
if(!(*qstate->env->attach_sub)(qstate, &ask,
|
if(!(*qstate->env->attach_sub)(qstate, &ask,
|
||||||
(uint16_t)(BIT_RD|flags), 0, &newq)){
|
(uint16_t)(BIT_RD|flags), 0, valrec, &newq)){
|
||||||
log_err("Could not generate request: out of memory");
|
log_err("Could not generate request: out of memory");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2005,14 +2016,16 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||||
/* if secure, this will override cache anyway, no need
|
/* if secure, this will override cache anyway, no need
|
||||||
* to check if from parentNS */
|
* to check if from parentNS */
|
||||||
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
||||||
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) {
|
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL,
|
||||||
|
qstate->query_flags)) {
|
||||||
log_err("out of memory caching validator results");
|
log_err("out of memory caching validator results");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* for a referral, store the verified RRsets */
|
/* for a referral, store the verified RRsets */
|
||||||
/* and this does not get prefetched, so no leeway */
|
/* and this does not get prefetched, so no leeway */
|
||||||
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
|
||||||
vq->orig_msg->rep, 1, 0, 0, NULL)) {
|
vq->orig_msg->rep, 1, 0, 0, NULL,
|
||||||
|
qstate->query_flags)) {
|
||||||
log_err("out of memory caching validator results");
|
log_err("out of memory caching validator results");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue