partial busy

git-svn-id: file:///svn/unbound/trunk@346 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-05-29 14:02:17 +00:00
parent d2318c50cd
commit 3e7a53c5ca
3 changed files with 124 additions and 6 deletions

View file

@ -103,6 +103,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->query_restart_count = 0; iq->query_restart_count = 0;
iq->referral_count = 0; iq->referral_count = 0;
iq->priming_stub = 0; iq->priming_stub = 0;
iq->orig_qflags = qstate->query_flags;
outbound_list_init(&iq->outlist); outbound_list_init(&iq->outlist);
return 1; return 1;
} }
@ -255,6 +256,96 @@ error_response(struct module_qstate* qstate, struct iter_qstate* iq, int rcode)
return final_state(qstate, iq); return final_state(qstate, iq);
} }
/** prepend the prepend list in the answer section of dns_msg */
static int
iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
struct region* region)
{
struct packed_rrset_list* p;
struct ub_packed_rrset_key** sets;
size_t num = 0;
for(p = iq->prepend_list; p; p = p->next)
num++;
if(num == 0)
return 1;
sets = region_alloc(region, (num+msg->rep->rrset_count) *
sizeof(struct ub_packed_rrset_key*));
if(!sets)
return 0;
memcpy(sets+num, msg->rep->rrsets, msg->rep->rrset_count *
sizeof(struct ub_packed_rrset_key*));
num = 0;
for(p = iq->prepend_list; p; p = p->next) {
sets[num] = (struct ub_packed_rrset_key*)region_alloc(region,
sizeof(struct ub_packed_rrset_key));
if(!sets[num])
return 0;
sets[num]->rk = *p->rrset.k;
sets[num]->entry.data = p->rrset.d;
num++;
}
msg->rep->rrsets = sets;
return 1;
}
/**
* Encode response message for iterator responses. Into response buffer.
* On error an error message is encoded.
* @param qstate: query state. With qinfo information.
* @param iq: iterator query state. With qinfo original and prepend list.
* @param msg: answer message.
*/
static void
iter_encode_respmsg(struct module_qstate* qstate, struct iter_qstate* iq,
struct dns_msg* msg)
{
struct query_info qinf = qstate->qinfo;
uint32_t now = time(NULL);
struct edns_data edns;
if(iq->orig_qname) {
qinf.qname = iq->orig_qname;
qinf.qname_len = iq->orig_qnamelen;
}
if(iq->prepend_list) {
if(!iter_prepend(iq, msg, qstate->region)) {
error_response(qstate, iq, LDNS_RCODE_SERVFAIL);
return;
}
}
edns.edns_present = qstate->edns.edns_present;
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.ext_rcode = 0;
edns.bits = qstate->edns.bits & EDNS_DO;
if(!reply_info_answer_encode(&qinf, msg->rep, 0, iq->orig_qflags,
qstate->buf, now, 1, qstate->scratch, qstate->edns.udp_size,
&edns)) {
/* encode servfail */
error_response(qstate, iq, LDNS_RCODE_SERVFAIL);
return;
}
}
/**
* Given a CNAME response (defined as a response containing a CNAME or DNAME
* that does not answer the request), process the response, modifying the
* state as necessary. This follows the CNAME/DNAME chain and returns the
* final query name.
*
* sets the new query name, after following the CNAME/DNAME chain.
* @param qstate: query state.
* @param iq: iterator query state.
* @param ie: iterator shared global environment.
*/
static void
handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
struct iter_env* ie)
{
}
/** /**
* Process the initial part of the request handling. This state roughly * Process the initial part of the request handling. This state roughly
* corresponds to resolver algorithms steps 1 (find answer in cache) and 2 * corresponds to resolver algorithms steps 1 (find answer in cache) and 2
@ -279,6 +370,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
int d; int d;
uint8_t* delname; uint8_t* delname;
size_t delnamelen; size_t delnamelen;
struct dns_msg* msg;
log_nametypeclass("resolving", qstate->qinfo.qname, log_nametypeclass("resolving", qstate->qinfo.qname,
qstate->qinfo.qtype, qstate->qinfo.qclass); qstate->qinfo.qtype, qstate->qinfo.qclass);
/* check effort */ /* check effort */
@ -308,14 +401,30 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* This either results in a query restart (CNAME cache response), a /* This either results in a query restart (CNAME cache response), a
* terminating response (ANSWER), or a cache miss (null). */ * terminating response (ANSWER), or a cache miss (null). */
/* TODO: cache lookup */ msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
/* lookup qname, qtype qclass */ qstate->qinfo.qname_len, qstate->qinfo.qtype,
qstate->qinfo.qclass, qstate->qinfo.has_cd,
qstate->region, qstate->scratch);
if(msg) {
/* handle positive cache response */
/*
enum response_type type = type_cache_response(msg);
if(type == RESPONSE_TYPE_CNAME) */ {
verbose(VERB_ALGO, "returning CNAME response from "
"cache");
/* handleCnameresponse &iq->orig_qname, &iq->orig_qname_len */
/* his *is* a query restart, even if it is a cheap
* one. */
iq->query_restart_count++;
return next_state(qstate, iq, INIT_REQUEST_STATE);
}
/* TODO: handle positive cache response */
/* calc response type (from cache msg) */
/* if cname */
/* handle cname, overwrite qname, restart */
/* it is an answer, response, to final state */ /* it is an answer, response, to final state */
verbose(VERB_ALGO, "returning answer from cache.");
iter_encode_respmsg(qstate, iq, msg);
return final_state(qstate, iq);
}
/* TODO attempt to forward the request */ /* TODO attempt to forward the request */

View file

@ -167,6 +167,13 @@ struct iter_qstate {
/** Last element of the prepend list */ /** Last element of the prepend list */
struct packed_rrset_list* prepend_last; struct packed_rrset_list* prepend_last;
/** original query name - if not NULL, malloced and before CNAME */
uint8_t* orig_qname;
/** original query name length */
size_t orig_qnamelen;
/** original query flags (i.e. RD flag) */
uint16_t orig_qflags;
/** /**
* This is the current delegation point for an in-progress query. This * This is the current delegation point for an in-progress query. This
* object retains state as to which delegation targets need to be * object retains state as to which delegation targets need to be

View file

@ -47,6 +47,8 @@
#define BIT_AA 0x0400 #define BIT_AA 0x0400
/** RD flag */ /** RD flag */
#define BIT_RD 0x0100 #define BIT_RD 0x0100
/** RA flag */
#define BIT_RA 0x0080
/** CD flag */ /** CD flag */
#define BIT_CD 0x0010 #define BIT_CD 0x0010
/** QR flag */ /** QR flag */