mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
partial busy
git-svn-id: file:///svn/unbound/trunk@346 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
d2318c50cd
commit
3e7a53c5ca
3 changed files with 124 additions and 6 deletions
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue