mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
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:
parent
2102aa0a3a
commit
81ae42fde0
4 changed files with 87 additions and 5 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue