Prime response state, both root priming and stub priming handling.

git-svn-id: file:///svn/unbound/trunk@364 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-06-04 12:22:38 +00:00
parent 2102aa0a3a
commit 81ae42fde0
4 changed files with 87 additions and 5 deletions

View file

@ -4,6 +4,7 @@
- cache lameness in response handling.
- do not touch qstate after worker_process_query because it may have
been deleted by that routine.
- Prime response state.
1 June 2007: Wouter
- normalize incoming messages. Like unbound-java, with CNAME chain

View file

@ -218,6 +218,22 @@ dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg, struct region* region)
return m;
}
struct dns_msg*
dns_copy_msg(struct dns_msg* from, struct region* region)
{
struct dns_msg* m = (struct dns_msg*)region_alloc(region,
sizeof(struct dns_msg));
if(!m)
return NULL;
m->qinfo = from->qinfo;
if(!(m->qinfo.qname = region_alloc_init(region, from->qinfo.qname,
from->qinfo.qname_len)))
return NULL;
if(!(m->rep = reply_info_copy(from->rep, NULL, region)))
return NULL;
return m;
}
int
iter_dns_store(struct module_env* env, struct dns_msg* msg, int is_referral)
{

View file

@ -86,6 +86,14 @@ struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
struct dns_msg* dns_alloc_msg(ldns_buffer* pkt, struct msg_parse* msg,
struct region* region);
/**
* Copy a dns_msg to this region.
* @param from: dns message, also in region.
* @param region: region to use for allocation.
* @return newly allocated dns_msg, or NULL on memory error.
*/
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.
* @param env: environment, with alloc structure and dns cache.

View file

@ -1197,15 +1197,67 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(qstate, iq, QUERYTARGETS_STATE);
}
#if 0
/** TODO */
/**
* This handles the response to a priming query. This is used to handle both
* root and stub priming responses. This is basically the equivalent of the
* QUERY_RESP_STATE, but will not handle CNAME responses and will treat
* REFERRALs as ANSWERS. It will also update and reactivate the originating
* event.
*
* @param qstate: query state.
* @param iq: iterator query state.
* @param id: module id.
* @return true if the event needs more immediate processing, false if not.
* This state always returns false.
*/
static int
processPrimeResponse(struct module_qstate* qstate, struct iter_qstate* iq,
struct iter_env* ie, int id)
int id)
{
struct module_qstate* forq = qstate->parent;
struct iter_qstate* foriq;
struct delegpt* dp = NULL;
enum response_type type = response_type_from_server(iq->response,
&qstate->qinfo, iq->dp);
log_assert(qstate->parent); /* this is a subrequest of another */
if(type == RESPONSE_TYPE_ANSWER) {
/* Convert our response to a delegation point */
dp = delegpt_from_message(iq->response, forq->region);
}
if(!dp) {
/* if there is no convertable delegation point, then
* the ANSWER type was (presumably) a negative answer. */
verbose(VERB_ALGO, "prime response was not a positive "
"ANSWER; failing");
/* note that this will call the forevent with event error. */
qstate->ext_state[id] = module_error;
return 0;
}
log_nametypeclass("priming successful for", qstate->qinfo.qname,
qstate->qinfo.qtype, qstate->qinfo.qclass);
/* This event is finished. */
qstate->ext_state[id] = module_finished;
foriq = (struct iter_qstate*)forq->minfo[id];
foriq->dp = dp;
foriq->response = dns_copy_msg(iq->response, forq->region);
if(!foriq->response) {
log_err("copy prime response: out of memory");
/* note that this will call the forevent with event error. */
qstate->ext_state[id] = module_error;
return 0;
}
/* root priming responses go to init stage 2, priming stub
* responses to to stage 3. */
if(iq->priming_stub)
foriq->state = INIT_REQUEST_3_STATE;
else foriq->state = INIT_REQUEST_2_STATE;
/* because we are finished, the parent will be reactivated */
return 0;
}
#if 0
/** TODO */
static int
processTargetResponse(struct module_qstate* qstate, struct iter_qstate* iq,
@ -1259,10 +1311,10 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
case QUERY_RESP_STATE:
cont = processQueryResponse(qstate, iq, id);
break;
#if 0
case PRIME_RESP_STATE:
cont = processPrimeResponse(qstate, iq, ie, id);
cont = processPrimeResponse(qstate, iq, id);
break;
#if 0
case TARGET_RESP_STATE:
cont = processTargetResponse(qstate, iq, ie, id);
break;
@ -1387,6 +1439,11 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
process_response(qstate, iq, ie, id, outbound, event);
return;
}
if(event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
qstate->ext_state[id] = module_error;
return;
}
log_err("bad event for iterator");
qstate->ext_state[id] = module_error;