mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-23 16:20:26 -05:00
cname chain caching (part).
git-svn-id: file:///svn/unbound/trunk@440 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
4e4fabfc40
commit
1d6715544a
5 changed files with 40 additions and 17 deletions
|
|
@ -222,6 +222,12 @@ worker_handle_control_cmd(struct comm_point* c, void* arg, int error,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** check cname chain in cache reply */
|
||||||
|
static int
|
||||||
|
check_cache_chain(struct reply_info* rep) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** answer query from the cache */
|
/** answer query from the cache */
|
||||||
static int
|
static int
|
||||||
answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
|
answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
|
||||||
|
|
@ -246,6 +252,17 @@ answer_from_cache(struct worker* worker, struct lruhash_entry* e, uint16_t id,
|
||||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
|
if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
|
||||||
return 0;
|
return 0;
|
||||||
/* locked and ids and ttls are OK. */
|
/* locked and ids and ttls are OK. */
|
||||||
|
/* check CNAME chain (if any) */
|
||||||
|
if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
|
||||||
|
htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
|
||||||
|
htons(LDNS_RR_TYPE_DNAME))) {
|
||||||
|
if(!check_cache_chain(rep)) {
|
||||||
|
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||||
|
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||||
|
region_free_all(worker->scratchpad);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(!reply_info_answer_encode(&mrentry->key, rep, id, flags,
|
if(!reply_info_answer_encode(&mrentry->key, rep, id, flags,
|
||||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||||
udpsize, edns, (int)(edns->bits & EDNS_DO) )) {
|
udpsize, edns, (int)(edns->bits & EDNS_DO) )) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
- fixup of deadlock warnings, yield cpu in checklock code so that
|
- fixup of deadlock warnings, yield cpu in checklock code so that
|
||||||
freebsd scheduler selects correct process to run.
|
freebsd scheduler selects correct process to run.
|
||||||
- added identity and version config options and replies.
|
- added identity and version config options and replies.
|
||||||
|
- store cname messages complete answers.
|
||||||
|
|
||||||
18 July 2007: Wouter
|
18 July 2007: Wouter
|
||||||
- do not query addresses, 127.0.0.1, and ::1 by default.
|
- do not query addresses, 127.0.0.1, and ::1 by default.
|
||||||
|
|
|
||||||
|
|
@ -293,11 +293,12 @@ dns_copy_msg(struct dns_msg* from, struct region* region)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
|
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
|
||||||
|
struct reply_info* msgrep, int is_referral)
|
||||||
{
|
{
|
||||||
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) */
|
||||||
rep = reply_info_copy(msg->rep, env->alloc, NULL);
|
rep = reply_info_copy(msgrep, env->alloc, NULL);
|
||||||
if(!rep)
|
if(!rep)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -322,10 +323,10 @@ iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
|
||||||
struct query_info qinf;
|
struct query_info qinf;
|
||||||
hashvalue_t h;
|
hashvalue_t h;
|
||||||
|
|
||||||
qinf = msg->qinfo;
|
qinf = *msgqinf;
|
||||||
qinf.qname = memdup(msg->qinfo.qname, msg->qinfo.qname_len);
|
qinf.qname = memdup(msgqinf->qname, msgqinf->qname_len);
|
||||||
if(!qinf.qname) {
|
if(!qinf.qname) {
|
||||||
reply_info_parsedelete(msg->rep, env->alloc);
|
reply_info_parsedelete(rep, env->alloc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* fixup flags to be sensible for a reply based on the cache */
|
/* fixup flags to be sensible for a reply based on the cache */
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,8 @@ struct delegpt;
|
||||||
struct region;
|
struct region;
|
||||||
struct msg_parse;
|
struct msg_parse;
|
||||||
struct ub_randstate;
|
struct ub_randstate;
|
||||||
|
struct query_info;
|
||||||
|
struct reply_info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process config options and set iterator module state.
|
* Process config options and set iterator module state.
|
||||||
|
|
@ -98,13 +100,14 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct region* region);
|
||||||
/**
|
/**
|
||||||
* Allocate a dns_msg with malloc/alloc structure and store in dns cache.
|
* Allocate a dns_msg with malloc/alloc structure and store in dns cache.
|
||||||
* @param env: environment, with alloc structure and dns cache.
|
* @param env: environment, with alloc structure and dns cache.
|
||||||
* @param msg: dns_msg from dns_alloc_msg for example.
|
* @param qinf: query info, the query for which answer is stored.
|
||||||
|
* @param rep: reply in dns_msg from dns_alloc_msg for example.
|
||||||
* @param is_referral: If true, then the given message to be stored is a
|
* @param is_referral: If true, then the given message to be stored is a
|
||||||
* referral. The cache implementation may use this as a hint.
|
* referral. The cache implementation may use this as a hint.
|
||||||
* @return 0 on alloc error (out of memory).
|
* @return 0 on alloc error (out of memory).
|
||||||
*/
|
*/
|
||||||
int iter_dns_store(struct module_env* env, struct dns_msg* msg,
|
int iter_dns_store(struct module_env* env, struct query_info* qinf,
|
||||||
int is_referral);
|
struct reply_info* rep, int is_referral);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select randomly with n/m probability.
|
* Select randomly with n/m probability.
|
||||||
|
|
|
||||||
|
|
@ -1053,13 +1053,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* ANSWER type responses terminate the query algorithm,
|
/* ANSWER type responses terminate the query algorithm,
|
||||||
* so they sent on their */
|
* so they sent on their */
|
||||||
verbose(VERB_DETAIL, "query response was ANSWER");
|
verbose(VERB_DETAIL, "query response was ANSWER");
|
||||||
|
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
/* FIXME: there is a question about whether this gets
|
iq->response->rep, 0))
|
||||||
* stored under the original query or most recent query.
|
|
||||||
* The original query would reduce cache work, but you
|
|
||||||
* need to apply the prependList before caching, and
|
|
||||||
* also cache under the latest query. */
|
|
||||||
if(!iter_dns_store(qstate->env, iq->response, 0))
|
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
/* close down outstanding requests to be discarded */
|
/* close down outstanding requests to be discarded */
|
||||||
outbound_list_clear(&iq->outlist);
|
outbound_list_clear(&iq->outlist);
|
||||||
|
|
@ -1073,7 +1068,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
verbose(VERB_DETAIL, "query response was REFERRAL");
|
verbose(VERB_DETAIL, "query response was REFERRAL");
|
||||||
|
|
||||||
/* Store the referral under the current query */
|
/* Store the referral under the current query */
|
||||||
if(!iter_dns_store(qstate->env, iq->response, 1))
|
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
|
iq->response->rep, 1))
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
|
||||||
/* Reset the event state, setting the current delegation
|
/* Reset the event state, setting the current delegation
|
||||||
|
|
@ -1111,7 +1107,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* cache the CNAME response under the current query */
|
/* cache the CNAME response under the current query */
|
||||||
/* NOTE : set referral=1, so that rrsets get stored but not
|
/* NOTE : set referral=1, so that rrsets get stored but not
|
||||||
* the partial query answer (CNAME only). */
|
* the partial query answer (CNAME only). */
|
||||||
if(!iter_dns_store(qstate->env, iq->response, 1))
|
if(!iter_dns_store(qstate->env, &iq->response->qinfo,
|
||||||
|
iq->response->rep, 1))
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
/* 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;
|
||||||
|
|
@ -1347,6 +1344,10 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
log_err("prepend rrsets: out of memory");
|
log_err("prepend rrsets: out of memory");
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
/* store message with the finished prepended items */
|
||||||
|
if(!iter_dns_store(qstate->env, &qstate->qinfo,
|
||||||
|
iq->response->rep, 0))
|
||||||
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
if(query_dname_compare(qstate->qinfo.qname,
|
if(query_dname_compare(qstate->qinfo.qname,
|
||||||
iq->response->qinfo.qname) == 0) {
|
iq->response->qinfo.qname) == 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue