mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Mesh design and preparatory cleanup.
- removed unused _node iterator value from rbtree_t. Takes up space.
- iterator can handle querytargets state without a delegation point
set, so that a priming(stub) subquery error can be handled.
- iterator stores if it is priming or not.
- log_query_info() neater logging.
git-svn-id: file:///svn/unbound/trunk@418 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
b2deaa21ba
commit
fcd489a12a
9 changed files with 173 additions and 54 deletions
|
|
@ -215,8 +215,7 @@ run_debug(struct module_qstate* p, int d)
|
||||||
}
|
}
|
||||||
buf[i++] = 'o';
|
buf[i++] = 'o';
|
||||||
buf[i] = 0;
|
buf[i] = 0;
|
||||||
log_nametypeclass(VERB_ALGO, buf, p->qinfo.qname, p->qinfo.qtype,
|
log_query_info(VERB_ALGO, buf, &p->qinfo);
|
||||||
p->qinfo.qclass);
|
|
||||||
for(p = p->subquery_first; p; p = p->subquery_next) {
|
for(p = p->subquery_first; p; p = p->subquery_next) {
|
||||||
run_debug(p, d+1);
|
run_debug(p, d+1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
22 June 2007: Wouter
|
||||||
|
- removed unused _node iterator value from rbtree_t. Takes up space.
|
||||||
|
- iterator can handle querytargets state without a delegation point
|
||||||
|
set, so that a priming(stub) subquery error can be handled.
|
||||||
|
- iterator stores if it is priming or not.
|
||||||
|
- log_query_info() neater logging.
|
||||||
|
|
||||||
21 June 2007: Wouter
|
21 June 2007: Wouter
|
||||||
- Fixup secondary buffer in case of error callback.
|
- Fixup secondary buffer in case of error callback.
|
||||||
- cleanup slumber list of runnable states.
|
- cleanup slumber list of runnable states.
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ iter_new(struct module_qstate* qstate, int id)
|
||||||
iq->num_current_queries = 0;
|
iq->num_current_queries = 0;
|
||||||
iq->query_restart_count = 0;
|
iq->query_restart_count = 0;
|
||||||
iq->referral_count = 0;
|
iq->referral_count = 0;
|
||||||
|
iq->priming = 0;
|
||||||
iq->priming_stub = 0;
|
iq->priming_stub = 0;
|
||||||
iq->orig_qflags = qstate->query_flags;
|
iq->orig_qflags = qstate->query_flags;
|
||||||
/* remove all weird bits from the query flags */
|
/* remove all weird bits from the query flags */
|
||||||
|
|
@ -554,6 +555,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
subiq->dp = dp;
|
subiq->dp = dp;
|
||||||
/* suppress any target queries. */
|
/* suppress any target queries. */
|
||||||
subiq->num_target_queries = 0;
|
subiq->num_target_queries = 0;
|
||||||
|
subiq->priming = 1;
|
||||||
|
|
||||||
/* this module stops, our submodule starts, and does the query. */
|
/* this module stops, our submodule starts, and does the query. */
|
||||||
qstate->ext_state[id] = module_wait_subquery;
|
qstate->ext_state[id] = module_wait_subquery;
|
||||||
|
|
@ -608,6 +610,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
/* suppress any target queries -- although there wouldn't be anyway,
|
/* suppress any target queries -- although there wouldn't be anyway,
|
||||||
* since stub hints never have missing targets.*/
|
* since stub hints never have missing targets.*/
|
||||||
subiq->num_target_queries = 0;
|
subiq->num_target_queries = 0;
|
||||||
|
subiq->priming = 1;
|
||||||
subiq->priming_stub = 1;
|
subiq->priming_stub = 1;
|
||||||
|
|
||||||
/* this module stops, our submodule starts, and does the query. */
|
/* this module stops, our submodule starts, and does the query. */
|
||||||
|
|
@ -641,8 +644,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
size_t delnamelen;
|
size_t delnamelen;
|
||||||
struct dns_msg* msg;
|
struct dns_msg* msg;
|
||||||
|
|
||||||
log_nametypeclass(VERB_DETAIL, "resolving", qstate->qinfo.qname,
|
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
|
||||||
qstate->qinfo.qtype, qstate->qinfo.qclass);
|
|
||||||
/* check effort */
|
/* check effort */
|
||||||
|
|
||||||
/* We enforce a maximum number of query restarts. This is primarily a
|
/* We enforce a maximum number of query restarts. This is primarily a
|
||||||
|
|
@ -801,8 +803,8 @@ static int
|
||||||
processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
struct iter_env* ie, int id)
|
struct iter_env* ie, int id)
|
||||||
{
|
{
|
||||||
log_nametypeclass(VERB_DETAIL, "resolving (init part 2): ",
|
log_query_info(VERB_DETAIL, "resolving (init part 2): ",
|
||||||
qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
|
&qstate->qinfo);
|
||||||
|
|
||||||
/* Check to see if we need to prime a stub zone. */
|
/* Check to see if we need to prime a stub zone. */
|
||||||
if(prime_stub(qstate, iq, ie, id, qstate->qinfo.qname,
|
if(prime_stub(qstate, iq, ie, id, qstate->qinfo.qname,
|
||||||
|
|
@ -828,8 +830,8 @@ processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
static int
|
static int
|
||||||
processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq)
|
processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||||
{
|
{
|
||||||
log_nametypeclass(VERB_DETAIL, "resolving (init part 3): ",
|
log_query_info(VERB_DETAIL, "resolving (init part 3): ",
|
||||||
qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
|
&qstate->qinfo);
|
||||||
/* If the RD flag wasn't set, then we just finish with the
|
/* If the RD flag wasn't set, then we just finish with the
|
||||||
* cached referral as the response. */
|
* cached referral as the response. */
|
||||||
if(!(qstate->query_flags & BIT_RD)) {
|
if(!(qstate->query_flags & BIT_RD)) {
|
||||||
|
|
@ -987,8 +989,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* needs to send a query to. That is, at least one per referral,
|
* needs to send a query to. That is, at least one per referral,
|
||||||
* more if some targets timeout or return throwaway answers. */
|
* more if some targets timeout or return throwaway answers. */
|
||||||
|
|
||||||
log_nametypeclass(VERB_DETAIL, "processQueryTargets:",
|
log_query_info(VERB_DETAIL, "processQueryTargets:", &qstate->qinfo);
|
||||||
qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
|
|
||||||
verbose(VERB_ALGO, "processQueryTargets: targetqueries %d, "
|
verbose(VERB_ALGO, "processQueryTargets: targetqueries %d, "
|
||||||
"currentqueries %d", iq->num_target_queries,
|
"currentqueries %d", iq->num_target_queries,
|
||||||
iq->num_current_queries);
|
iq->num_current_queries);
|
||||||
|
|
@ -1002,6 +1003,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure we have a delegation point, otherwise priming failed
|
||||||
|
* or another failure occurred */
|
||||||
|
if(!iq->dp) {
|
||||||
|
verbose(VERB_DETAIL, "Failed to get a delegation, giving up");
|
||||||
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
tf_policy = 0;
|
tf_policy = 0;
|
||||||
if(iq->depth <= ie->max_dependency_depth) {
|
if(iq->depth <= ie->max_dependency_depth) {
|
||||||
tf_policy = ie->target_fetch_policy[iq->depth];
|
tf_policy = ie->target_fetch_policy[iq->depth];
|
||||||
|
|
@ -1088,8 +1096,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have a valid target. */
|
/* We have a valid target. */
|
||||||
log_nametypeclass(VERB_DETAIL, "sending query:", qstate->qinfo.qname,
|
log_query_info(VERB_DETAIL, "sending query:", &qstate->qinfo);
|
||||||
qstate->qinfo.qtype, qstate->qinfo.qclass);
|
|
||||||
log_name_addr(VERB_DETAIL, "sending to target:", iq->dp->name,
|
log_name_addr(VERB_DETAIL, "sending to target:", iq->dp->name,
|
||||||
&target->addr, target->addrlen);
|
&target->addr, target->addrlen);
|
||||||
outq = (*qstate->env->send_query)(
|
outq = (*qstate->env->send_query)(
|
||||||
|
|
@ -1291,8 +1298,7 @@ processPrimeResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
log_nametypeclass(VERB_DETAIL, "priming successful for",
|
log_query_info(VERB_DETAIL, "priming successful for", &qstate->qinfo);
|
||||||
qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
|
|
||||||
delegpt_log(dp);
|
delegpt_log(dp);
|
||||||
foriq = (struct iter_qstate*)forq->minfo[id];
|
foriq = (struct iter_qstate*)forq->minfo[id];
|
||||||
foriq->dp = dp;
|
foriq->dp = dp;
|
||||||
|
|
@ -1400,8 +1406,8 @@ static int
|
||||||
processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
int id)
|
int id)
|
||||||
{
|
{
|
||||||
log_nametypeclass(VERB_DETAIL, "finishing processing for",
|
log_query_info(VERB_DETAIL, "finishing processing for",
|
||||||
qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
|
&qstate->qinfo);
|
||||||
|
|
||||||
if(!iq->response) {
|
if(!iq->response) {
|
||||||
verbose(VERB_ALGO, "No response is set, servfail");
|
verbose(VERB_ALGO, "No response is set, servfail");
|
||||||
|
|
@ -1603,8 +1609,7 @@ process_subq_error(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
if(!dpns) {
|
if(!dpns) {
|
||||||
/* not interested */
|
/* not interested */
|
||||||
verbose(VERB_ALGO, "got subq error, but not interested");
|
verbose(VERB_ALGO, "got subq error, but not interested");
|
||||||
log_nametypeclass(VERB_ALGO, "errname",
|
log_query_info(VERB_ALGO, "errname", &errinf);
|
||||||
errinf.qname, errinf.qtype, errinf.qclass);
|
|
||||||
delegpt_log(iq->dp);
|
delegpt_log(iq->dp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1623,8 +1628,8 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||||
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
|
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
|
||||||
verbose(VERB_DETAIL, "iterator[module %d] operate: extstate:%s event:%s",
|
verbose(VERB_DETAIL, "iterator[module %d] operate: extstate:%s event:%s",
|
||||||
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
|
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
|
||||||
if(iq) log_nametypeclass(VERB_DETAIL, "iterator operate: query",
|
if(iq) log_query_info(VERB_DETAIL, "iterator operate: query",
|
||||||
qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
|
&qstate->qinfo);
|
||||||
if(ie->fwd_addrlen != 0) {
|
if(ie->fwd_addrlen != 0) {
|
||||||
perform_forward(qstate, event, id, outbound);
|
perform_forward(qstate, event, id, outbound);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,12 @@ struct iter_qstate {
|
||||||
/** the number of times this query as followed a referral. */
|
/** the number of times this query as followed a referral. */
|
||||||
int referral_count;
|
int referral_count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This flag, if true, means that this event is a priming query.
|
||||||
|
* In that case priming stub may be set as well.
|
||||||
|
*/
|
||||||
|
int priming;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is flag that, if true, means that this event is
|
* This is flag that, if true, means that this event is
|
||||||
* representing a stub priming query. It is meaningless unless
|
* representing a stub priming query. It is meaningless unless
|
||||||
|
|
|
||||||
|
|
@ -44,4 +44,62 @@
|
||||||
*/
|
*/
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "services/mesh.h"
|
#include "services/mesh.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/net_help.h"
|
||||||
|
#include "util/module.h"
|
||||||
|
#include "util/region-allocator.h"
|
||||||
|
|
||||||
|
/** compare two mesh_states */
|
||||||
|
static int
|
||||||
|
mesh_state_compare(const void* ap, const void* bp)
|
||||||
|
{
|
||||||
|
struct mesh_state* a = (struct mesh_state*)ap;
|
||||||
|
struct mesh_state* b = (struct mesh_state*)bp;
|
||||||
|
|
||||||
|
if(a->is_priming && !b->is_priming)
|
||||||
|
return -1;
|
||||||
|
if(!a->is_priming && b->is_priming)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if((a->state->query_flags&BIT_RD) && !(b->state->query_flags&BIT_RD))
|
||||||
|
return -1;
|
||||||
|
if(!(a->state->query_flags&BIT_RD) && (b->state->query_flags&BIT_RD))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return query_info_compare(&a->state->qinfo, &b->state->qinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** compare two mesh references */
|
||||||
|
static int
|
||||||
|
mesh_state_ref_compare(const void* ap, const void* bp)
|
||||||
|
{
|
||||||
|
struct mesh_state_ref* a = (struct mesh_state_ref*)ap;
|
||||||
|
struct mesh_state_ref* b = (struct mesh_state_ref*)bp;
|
||||||
|
return mesh_state_compare(a->s, b->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mesh_area*
|
||||||
|
mesh_create(struct worker* worker)
|
||||||
|
{
|
||||||
|
struct mesh_area* mesh = calloc(1, sizeof(struct mesh_area));
|
||||||
|
if(!mesh) {
|
||||||
|
log_err("mesh area alloc: out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
mesh->worker = worker;
|
||||||
|
rbtree_init(&mesh->run, &mesh_state_compare);
|
||||||
|
rbtree_init(&mesh->all, &mesh_state_compare);
|
||||||
|
mesh->num_reply_addrs = 0;
|
||||||
|
mesh->num_reply_states = 0;
|
||||||
|
mesh->num_detached_states = 0;
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mesh_delete(struct mesh_area* mesh)
|
||||||
|
{
|
||||||
|
if(!mesh)
|
||||||
|
return;
|
||||||
|
/* free all query states */
|
||||||
|
free(mesh);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,42 +55,49 @@ struct mesh_reply;
|
||||||
struct worker;
|
struct worker;
|
||||||
struct query_info;
|
struct query_info;
|
||||||
struct reply_info;
|
struct reply_info;
|
||||||
|
struct outbound_entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mesh of query states
|
* Mesh of query states
|
||||||
*/
|
*/
|
||||||
struct query_mesh {
|
struct mesh_area {
|
||||||
/** what worker this is a part of */
|
/** what worker this is a part of */
|
||||||
struct worker* worker;
|
struct worker* worker;
|
||||||
/** set of runnable queries (mesh_state_ref*) */
|
/** set of runnable queries (mesh_state.run_node) */
|
||||||
rbtree_t run;
|
rbtree_t run;
|
||||||
/** rbtree of all current queries */
|
/** rbtree of all current queries (mesh_state.node)*/
|
||||||
rbtree_t all;
|
rbtree_t all;
|
||||||
/** count of the number of mesh_reply entries */
|
|
||||||
size_t reply_count;
|
/** count of the total number of mesh_reply entries */
|
||||||
/** count of the number of mesh_states that have no mesh_replies
|
size_t num_reply_addrs;
|
||||||
* i.e. are for internal use. */
|
/** count of the number of mesh_states that have mesh_replies
|
||||||
size_t internal_count;
|
* Because a state can send results to multiple reply addresses,
|
||||||
|
* this number must be equal or lower than num_reply_addrs. */
|
||||||
|
size_t num_reply_states;
|
||||||
|
/** number of mesh_states that have no mesh_replies, and also
|
||||||
|
* an empty set of super-states, thus are 'toplevel' or detached
|
||||||
|
* internal opportunistic queries */
|
||||||
|
size_t num_detached_states;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mesh query state
|
* A mesh query state
|
||||||
* Unique per qname, qtype, qclass.
|
* Unique per qname, qtype, qclass (from the qstate).
|
||||||
* And RD flag; in case a client turns it off.
|
* And RD flag; in case a client turns it off.
|
||||||
* And priming queries are different from ordinary queries (because of hints).
|
* And priming queries are different from ordinary queries (because of hints).
|
||||||
|
*
|
||||||
|
* The entire structure is allocated in a region, this region is the qstate
|
||||||
|
* region. All parts (rbtree nodes etc) are also allocated in the region.
|
||||||
*/
|
*/
|
||||||
struct mesh_state {
|
struct mesh_state {
|
||||||
/** node in query_mesh all tree, key is this struct */
|
/** node in mesh_area all tree, key is this struct */
|
||||||
rbnode_t node;
|
rbnode_t node;
|
||||||
/** node in query_mesh runnable tree, key is this struct */
|
/** node in mesh_area runnable tree, key is this struct */
|
||||||
rbnode_t run_node;
|
rbnode_t run_node;
|
||||||
/** unique identity for this mesh state: what is it for */
|
/** if this is a (stub or root) priming query (with hints) */
|
||||||
/* Note that qstate qinfo is changed by iterator */
|
|
||||||
|
|
||||||
/** if this is a priming query (with hints) */
|
|
||||||
int is_priming;
|
int is_priming;
|
||||||
|
/** the query state. Note that the qinfo and query_flags
|
||||||
/** the query state */
|
* may not change. */
|
||||||
struct module_qstate* state;
|
struct module_qstate* state;
|
||||||
/** the list of replies to clients for the results */
|
/** the list of replies to clients for the results */
|
||||||
struct mesh_reply* reply_list;
|
struct mesh_reply* reply_list;
|
||||||
|
|
@ -123,38 +130,59 @@ struct mesh_reply {
|
||||||
struct comm_reply query_reply;
|
struct comm_reply query_reply;
|
||||||
/** edns data from query */
|
/** edns data from query */
|
||||||
struct edns_data edns;
|
struct edns_data edns;
|
||||||
|
/** the time when request was entered */
|
||||||
|
struct timeval start_time;
|
||||||
/** id of query, in network byteorder. */
|
/** id of query, in network byteorder. */
|
||||||
uint16_t qid;
|
uint16_t qid;
|
||||||
/** flags of query, for reply flags */
|
/** flags of query, for reply flags */
|
||||||
uint16_t qflags;
|
uint16_t qflags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ------------------- Functions for worker -------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate mesh, to empty.
|
* Allocate mesh, to empty.
|
||||||
* @param worker: what worker it is part of.
|
* @param worker: what worker it is part of.
|
||||||
* @return mesh: the new mesh or NULL on error.
|
* @return mesh: the new mesh or NULL on error.
|
||||||
*/
|
*/
|
||||||
struct query_mesh* mesh_create(struct worker* worker);
|
struct mesh_area* mesh_create(struct worker* worker);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete mesh, and all query states and replies in it.
|
* Delete mesh, and all query states and replies in it.
|
||||||
* @param mesh: the mesh to delete.
|
* @param mesh: the mesh to delete.
|
||||||
*/
|
*/
|
||||||
void mesh_delete(struct query_mesh* mesh);
|
void mesh_delete(struct mesh_area* mesh);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New query incoming from clients. Create new query state if needed, and
|
* New query incoming from clients. Create new query state if needed, and
|
||||||
* add mesh_reply to it. Returns error to client on malloc failures.
|
* add mesh_reply to it. Returns error to client on malloc failures.
|
||||||
|
* Will run the mesh area queries to process if a new query state is created.
|
||||||
|
*
|
||||||
* @param mesh: the mesh.
|
* @param mesh: the mesh.
|
||||||
* @param qinfo: query from client.
|
* @param qinfo: query from client.
|
||||||
* @param qflags: flags from client query.
|
* @param qflags: flags from client query.
|
||||||
* @param edns: edns data from client query.
|
* @param edns: edns data from client query.
|
||||||
* @param rep: where to reply to.
|
* @param rep: where to reply to.
|
||||||
* @param id: query id to reply with.
|
* @param qid: query id to reply with.
|
||||||
*/
|
*/
|
||||||
void mesh_new_client(struct query_mesh* mesh, struct query_info* qinfo,
|
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||||
uint16_t id);
|
uint16_t qid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle new event from the wire. A serviced query has returned.
|
||||||
|
* The query state will be made runnable, and the mesh_area will process
|
||||||
|
* query states until processing is complete.
|
||||||
|
*
|
||||||
|
* @param mesh: the query mesh.
|
||||||
|
* @param e: outbound entry, with query state to run and reply pointer.
|
||||||
|
* @param is_ok: if true, reply is OK, otherwise a timeout happened.
|
||||||
|
* @param reply: the comm point reply info.
|
||||||
|
*/
|
||||||
|
void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||||
|
int is_ok, struct comm_reply* reply);
|
||||||
|
|
||||||
|
/* ------------------- Functions for module environment --------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detach-subqueries.
|
* Detach-subqueries.
|
||||||
|
|
@ -179,7 +207,7 @@ void mesh_detach_subs(struct module_qstate* qstate);
|
||||||
* the results from the new subquery.
|
* the results from the new subquery.
|
||||||
* @param qinfo: what to query for (copied).
|
* @param qinfo: what to query for (copied).
|
||||||
* @param qflags: what flags to use (RD flag or not).
|
* @param qflags: what flags to use (RD flag or not).
|
||||||
* @param prime: if it is a priming query.
|
* @param prime: if it is a (stub) priming query.
|
||||||
* @param newq: If the new subquery needs initialisation, it is returned,
|
* @param newq: If the new subquery needs initialisation, it is returned,
|
||||||
* otherwise NULL is returned.
|
* otherwise NULL is returned.
|
||||||
* @return: false on error, true if success (and init may be needed).
|
* @return: false on error, true if success (and init may be needed).
|
||||||
|
|
@ -221,4 +249,15 @@ void mesh_query_done(struct module_qstate* qstate, int rcode,
|
||||||
void mesh_walk_supers(struct module_qstate* qstate, int id, int rcode,
|
void mesh_walk_supers(struct module_qstate* qstate, int id, int rcode,
|
||||||
void (*cb)(struct module_qstate*, int, struct module_qstate*, int));
|
void (*cb)(struct module_qstate*, int, struct module_qstate*, int));
|
||||||
|
|
||||||
|
/* ------------------- Functions for mesh -------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and initialize a new mesh state and its query state
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup a mesh state and its query state. Does not do rbtree or
|
||||||
|
* reference cleanup.
|
||||||
|
*/
|
||||||
|
|
||||||
#endif /* SERVICES_MESH_H */
|
#endif /* SERVICES_MESH_H */
|
||||||
|
|
|
||||||
|
|
@ -691,3 +691,10 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
|
||||||
ldns_buffer_free(buf);
|
ldns_buffer_free(buf);
|
||||||
region_destroy(region);
|
region_destroy(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
log_query_info(enum verbosity_value v, const char* str,
|
||||||
|
struct query_info* qinf)
|
||||||
|
{
|
||||||
|
log_nametypeclass(v, str, qinf->qname, qinf->qtype, qinf->qclass);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,4 +309,13 @@ struct ub_packed_rrset_key* reply_find_answer_rrset(struct query_info* qinfo,
|
||||||
void log_dns_msg(const char* str, struct query_info* qinfo,
|
void log_dns_msg(const char* str, struct query_info* qinfo,
|
||||||
struct reply_info* rep);
|
struct reply_info* rep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print string with neat domain name, type, class from query info.
|
||||||
|
* @param v: at what verbosity level to print this.
|
||||||
|
* @param str: string of message.
|
||||||
|
* @param qinf: query info structure with name, type and class.
|
||||||
|
*/
|
||||||
|
void log_query_info(enum verbosity_value v, const char* str,
|
||||||
|
struct query_info* qinf);
|
||||||
|
|
||||||
#endif /* UTIL_DATA_MSGREPLY_H */
|
#endif /* UTIL_DATA_MSGREPLY_H */
|
||||||
|
|
|
||||||
|
|
@ -80,9 +80,6 @@ struct rbtree_t {
|
||||||
/** The number of the nodes in the tree */
|
/** The number of the nodes in the tree */
|
||||||
size_t count;
|
size_t count;
|
||||||
|
|
||||||
/** Current node for walks... */
|
|
||||||
rbnode_t *_node;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key compare function. <0,0,>0 like strcmp.
|
* Key compare function. <0,0,>0 like strcmp.
|
||||||
* Return 0 on two NULL ptrs.
|
* Return 0 on two NULL ptrs.
|
||||||
|
|
@ -169,14 +166,6 @@ rbnode_t *rbtree_next(rbnode_t *rbtree);
|
||||||
*/
|
*/
|
||||||
rbnode_t *rbtree_previous(rbnode_t *rbtree);
|
rbnode_t *rbtree_previous(rbnode_t *rbtree);
|
||||||
|
|
||||||
/**
|
|
||||||
* Macro to walk through the tree, sets k to key, d to data, for every element.
|
|
||||||
*/
|
|
||||||
#define RBTREE_WALK(rbtree, k, d) \
|
|
||||||
for((rbtree)->_node = rbtree_first(rbtree);\
|
|
||||||
(rbtree)->_node != RBTREE_NULL && ((k) = (rbtree)->_node->key) && \
|
|
||||||
((d) = (void *) (rbtree)->_node); (rbtree)->_node = rbtree_next((rbtree)->_node))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call with node=variable of struct* with rbnode_t as first element.
|
* Call with node=variable of struct* with rbnode_t as first element.
|
||||||
* with type is the type of a pointer to that struct.
|
* with type is the type of a pointer to that struct.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue