module_subreq_remove(&qstate->subquery_first, s);
s->parent = NULL;
s->work_info = NULL;
- s->subquery_next = worker->slumber_list;
- s->subquery_prev = NULL;
- worker->slumber_list = s;
+ module_subreq_insert(&worker->slumber_list, s);
}
verbose(VERB_ALGO, "worker: slumber list has %d entries",
module_subreq_num(worker->slumber_list));
}
buf[i++] = 'o';
buf[i] = 0;
- log_nametypeclass(buf, p->qinfo.qname, p->qinfo.qtype, p->qinfo.qclass);
+ log_nametypeclass(VERB_ALGO, buf, p->qinfo.qname, p->qinfo.qtype,
+ p->qinfo.qclass);
for(p = p->subquery_first; p; p = p->subquery_next) {
run_debug(p, d+1);
}
find_runnable(struct module_qstate* subq)
{
struct module_qstate* p = subq;
- log_info("find runnable");
+ verbose(VERB_ALGO, "find runnable");
if(p->subquery_next && p->subquery_next->ext_state[
p->subquery_next->curmod] == module_state_initial)
return p->subquery_next;
struct outbound_entry* entry)
{
enum module_ext_state s;
+ verbose(VERB_DETAIL, "worker process handle event");
if(event == module_event_new) {
qstate->curmod = 0;
set_extstates_initial(worker, qstate);
region_free_all(worker->scratchpad);
qstate->reply = NULL;
s = qstate->ext_state[qstate->curmod];
- log_info("worker_process_query: module exit state is %s",
- strextstate(s));
+ verbose(VERB_ALGO, "worker_process_query: module "
+ "exit state is %s", strextstate(s));
+ if(s == module_state_initial) {
+ log_err("module exit in initial state, "
+ "it loops; aborted");
+ s = module_error;
+ }
/* examine results, start further modules, etc. */
- if(s == module_wait_subquery) {
- if(!qstate->subquery_first) {
+ if(s != module_error && s != module_finished) {
+ /* see if we can continue with other subrequests */
+ struct module_qstate* nxt = find_runnable(qstate);
+ if(s == module_wait_subquery && !nxt) {
log_err("module exit wait subq, but no subq");
s = module_error;
- } else {
+ }
+ if(nxt) {
/* start submodule */
- qstate = qstate->subquery_first;
+ qstate = nxt;
set_extstates_initial(worker, qstate);
- event = module_event_pass;
entry = NULL;
+ event = module_event_pass;
continue;
}
}
event = module_event_subq_done;
continue;
}
- if(s != module_error && s != module_finished) {
- /* see if we can continue with other subrequests */
- struct module_qstate* nxt = find_runnable(qstate);
- if(nxt) {
- qstate = nxt;
- entry = NULL;
- event = module_event_pass;
- continue;
- }
- }
break;
}
/* request done */
replyerror(LDNS_RCODE_SERVFAIL, w);
}
qstate_free(worker, qstate);
+ verbose(VERB_DETAIL, "worker process suspend");
return;
}
if(s == module_finished) {
req_release(w);
}
qstate_free(worker, qstate);
+ verbose(VERB_DETAIL, "worker process suspend");
return;
}
/* suspend, waits for wakeup callback */
+ verbose(VERB_DETAIL, "worker process suspend");
}
/** process incoming replies from the network */
edns.udp_size = 65535; /* max size for TCP replies */
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
- log_info("answer from the cache");
+ verbose(VERB_DETAIL, "answer from the cache");
if(answer_from_cache(worker, e,
*(uint16_t*)ldns_buffer_begin(c->buffer),
ldns_buffer_read_u16_at(c->buffer, 2), repinfo,
lock_rw_unlock(&e->lock);
return 1;
}
- log_info("answer from the cache -- data has timed out");
+ verbose(VERB_DETAIL, "answer from the cache -- data has timed out");
lock_rw_unlock(&e->lock);
}
ldns_buffer_rewind(c->buffer);
return 0;
}
q->state.env = &worker->env;
+ q->state.parent = NULL;
q->state.work_info = q;
q->next = worker->free_queries;
worker->free_queries = q;
- nicer printout of outgoing port selection.
- fixup cname target readout.
- nicer debug output.
+ - fixup rrset counts when prepending CNAMEs to the answer.
+ - fixup rrset TTL for prepended CNAMEs.
+ - process better check for looping modules, and which submodule to
+ run next.
+ - subreq insertion code fixup for slumber list.
+ - VERB_DETAIL, verbosity: 2 level gives short but readable output.
+ VERB_ALGO, verbosity: 3 gives extensive output.
5 June 2007: Wouter
- iterator state finished.
return 1;
}
+/** count NS and number missing */
+static void
+delegpt_count_ns(struct delegpt* dp, size_t* numns, size_t* missing)
+{
+ struct delegpt_ns* ns;
+ *numns = 0;
+ *missing = 0;
+ for(ns = dp->nslist; ns; ns = ns->next) {
+ (*numns)++;
+ if(!ns->resolved)
+ (*missing)++;
+ }
+}
+
+/** count addresses, and number in result and available lists */
+static void
+delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres,
+ size_t* numavail)
+{
+ struct delegpt_addr* a;
+ *numaddr = 0;
+ *numres = 0;
+ *numavail = 0;
+ for(a = dp->target_list; a; a = a->next_target) {
+ (*numaddr)++;
+ }
+ for(a = dp->result_list; a; a = a->next_result) {
+ (*numres)++;
+ }
+ for(a = dp->usable_list; a; a = a->next_usable) {
+ (*numavail)++;
+ }
+}
+
void delegpt_log(struct delegpt* dp)
{
char buf[LDNS_MAX_DOMAINLEN+1];
struct delegpt_ns* ns;
struct delegpt_addr* a;
+ size_t missing=0, numns=0, numaddr=0, numres=0, numavail=0;
dname_str(dp->name, buf);
if(dp->nslist == NULL && dp->target_list == NULL) {
log_info("DelegationPoint<%s>: empty", buf);
return;
}
- log_info("DelegationPoint<%s>:", buf);
- for(ns = dp->nslist; ns; ns = ns->next) {
- dname_str(ns->name, buf);
- log_info(" %s%s", buf, (ns->resolved?"*":""));
- }
- for(a = dp->target_list; a; a = a->next_target) {
- log_addr(" ", &a->addr, a->addrlen);
+ delegpt_count_ns(dp, &numns, &missing);
+ delegpt_count_addr(dp, &numaddr, &numres, &numavail);
+ log_info("DelegationPoint<%s>: %u names (%u missing), "
+ "%u addrs (%u result, %u avail)",
+ buf, (unsigned)numns, (unsigned)missing,
+ (unsigned)numaddr, (unsigned)numres, (unsigned)numavail);
+ if(verbosity >= VERB_ALGO) {
+ for(ns = dp->nslist; ns; ns = ns->next) {
+ dname_str(ns->name, buf);
+ log_info(" %s%s", buf, (ns->resolved?"*":""));
+ }
+ for(a = dp->target_list; a; a = a->next_target) {
+ log_addr(" ", &a->addr, a->addrlen);
+ }
}
}
if(d->rr_len[i] != 2 + INET_SIZE)
continue;
memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);
- log_addr("adding A to deleg", (struct sockaddr_storage*)&sa,
- len);
if(!delegpt_add_target(dp, region, ak->rk.dname,
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
len))
if(d->rr_len[i] != 2 + INET6_SIZE) /* rdatalen + len of IP6 */
continue;
memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);
- log_addr("adding AAAA to deleg", (struct sockaddr_storage*)&sa, len);
if(!delegpt_add_target(dp, region, ak->rk.dname,
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
len))
* it is relevant. */
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(mname, s->rk.dname) == 0) {
- log_nametypeclass("following CNAME from", mname, LDNS_RR_TYPE_CNAME, request->qclass);
get_cname_target(s, &mname, &mname_len);
- log_nametypeclass("following CNAME to", mname, request->qtype, request->qclass);
}
}
/* if we encountered a CNAME (or a bunch of CNAMEs), and
remove_rrset(const char* str, ldns_buffer* pkt, struct msg_parse* msg,
struct rrset_parse* prev, struct rrset_parse** rrset)
{
- if(verbosity >= VERB_ALGO
+ if(verbosity >= VERB_DETAIL
&& (*rrset)->dname_len <= LDNS_MAX_DOMAINLEN) {
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
dname_pkt_copy(pkt, buf, (*rrset)->dname);
- log_nametypeclass(str, buf,
+ log_nametypeclass(VERB_DETAIL, str, buf,
(*rrset)->type, ntohs((*rrset)->rrset_class));
}
if(prev)
struct rrset_parse* rrset, *prev;
prev = NULL;
rrset = msg->rrset_first;
- log_nametypeclass("sanitize for", zonename, 0, 0);
/* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that,
scrub_message(ldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct region* region)
{
- /* things to check:
- * if qdcount > 0 : qinfo.
- * from normalize() from NSclient.
- * from sanitize() from iterator.
- */
/* basic sanity checks */
+ log_nametypeclass(VERB_ALGO, "scrub for", zonename, LDNS_RR_TYPE_NS,
+ qinfo->qclass);
if(msg->qdcount > 1)
return 0;
if( !(msg->flags&BIT_QR) )
/* store rrsets */
struct rrset_ref ref;
uint32_t now = time(NULL);
- size_t i, j;
+ size_t i;
for(i=0; i<rep->rrset_count; i++) {
- /* fixup rrset ttl */
- struct packed_rrset_data* data = (struct
- packed_rrset_data*)rep->rrsets[i]->entry.data;
- data->ttl += now;
- for(j=0; j<data->count + data->rrsig_count; j++)
- data->rr_ttl[j] += now;
+ packed_rrset_ttl_add((struct packed_rrset_data*)
+ rep->rrsets[i]->entry.data, now);
ref.key = rep->rrsets[i];
ref.id = rep->rrsets[i]->id;
/*ignore ret: it was in the cache, ref updated */
error_response(struct module_qstate* qstate, int id, int rcode)
{
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
- log_info("err response %s", ldns_lookup_by_id(ldns_rcodes, rcode)?
+ verbose(VERB_DETAIL, "return error response %s",
+ ldns_lookup_by_id(ldns_rcodes, rcode)?
ldns_lookup_by_id(ldns_rcodes, rcode)->name:"??");
if(iq && iq->orig_qname) {
/* encode original query */
num++;
if(num == 0)
return 1;
+ verbose(VERB_ALGO, "prepending %d rrsets", (int)num);
sets = region_alloc(region, (num+msg->rep->rrset_count) *
sizeof(struct ub_packed_rrset_key*));
if(!sets)
for(p = iq->prepend_list; p; p = p->next) {
sets[num++] = p->rrset;
}
+ msg->rep->rrset_count += num;
+ msg->rep->an_numrrsets += num;
msg->rep->rrsets = sets;
return 1;
}
struct dns_msg* msg, int id)
{
struct query_info qinf = qstate->qinfo;
- uint32_t now = time(NULL);
struct edns_data edns;
if(iq->orig_qname) {
qinf.qname = iq->orig_qname;
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,
+ qstate->buf, 0, 1, qstate->scratch, qstate->edns.udp_size,
&edns)) {
/* encode servfail */
error_response(qstate, id, LDNS_RCODE_SERVFAIL);
subq->env = qstate->env;
subq->work_info = qstate->work_info;
subq->parent = qstate;
- if(qstate->subquery_first)
- qstate->subquery_first->subquery_prev = subq;
- subq->subquery_next = qstate->subquery_first;
- subq->subquery_prev = NULL;
- qstate->subquery_first = subq;
+ module_subreq_insert(&qstate->subquery_first, subq);
subiq = (struct iter_qstate*)subq->minfo[id];
memset(subiq, 0, sizeof(*subiq));
return 0;
/* Otherwise, we need to (re)prime the stub. */
- log_nametypeclass("priming stub", stub_dp->name, LDNS_RR_TYPE_NS,
- qclass);
+ log_nametypeclass(VERB_DETAIL, "priming stub", stub_dp->name,
+ LDNS_RR_TYPE_NS, qclass);
/* Stub priming events start at the QUERYTARGETS state to avoid the
* redundant INIT state processing. */
size_t delnamelen;
struct dns_msg* msg;
- log_nametypeclass("resolving", qstate->qinfo.qname,
+ log_nametypeclass(VERB_DETAIL, "resolving", qstate->qinfo.qname,
qstate->qinfo.qtype, qstate->qinfo.qclass);
/* check effort */
/* handle positive cache response */
enum response_type type = response_type_from_cache(msg,
&qstate->qinfo);
+ log_dns_msg("msg from cache lookup", &msg->qinfo, msg->rep);
if(type == RESPONSE_TYPE_CNAME) {
uint8_t* sname = 0;
processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
struct iter_env* ie, int id)
{
- log_nametypeclass("resolving (init part 2): ", qstate->qinfo.qname,
- qstate->qinfo.qtype, qstate->qinfo.qclass);
+ log_nametypeclass(VERB_DETAIL, "resolving (init part 2): ",
+ qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
/* Check to see if we need to prime a stub zone. */
if(prime_stub(qstate, iq, ie, id, qstate->qinfo.qname,
static int
processInitRequest3(struct module_qstate* qstate, struct iter_qstate* iq)
{
- log_nametypeclass("resolving (init part 3): ", qstate->qinfo.qname,
- qstate->qinfo.qtype, qstate->qinfo.qclass);
+ log_nametypeclass(VERB_DETAIL, "resolving (init part 3): ",
+ qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
/* If the RD flag wasn't set, then we just finish with the
* cached referral as the response. */
if(!(qstate->query_flags & BIT_RD)) {
free(subq);
return 0;
}
- log_nametypeclass("new target", name, qtype, qclass);
+ log_nametypeclass(VERB_DETAIL, "new target", name, qtype, qclass);
delegpt_log(subiq->dp);
return 1;
}
* FIXME: at this point, this *may* be resolvable, so
* perhaps we should issue the query anyway and let it fail.*/
if(dname_subdomain_c(ns->name, iq->dp->name)) {
- log_nametypeclass("skipping target name because "
- "it should have been glue", ns->name,
+ log_nametypeclass(VERB_DETAIL, "skipping target name "
+ "because it should have been glue", ns->name,
LDNS_RR_TYPE_NS, qstate->qinfo.qclass);
continue;
}
break;
}
*num = query_count;
+ if(query_count > 0)
+ qstate->ext_state[id] = module_wait_subquery;
return 1;
}
* needs to send a query to. That is, at least one per referral,
* more if some targets timeout or return throwaway answers. */
- log_nametypeclass("processQueryTargets:", qstate->qinfo.qname,
- qstate->qinfo.qtype, qstate->qinfo.qclass);
+ log_nametypeclass(VERB_DETAIL, "processQueryTargets:",
+ qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
verbose(VERB_ALGO, "processQueryTargets: targetqueries %d, "
"currentqueries %d", iq->num_target_queries,
iq->num_current_queries);
/* Make sure that we haven't run away */
/* FIXME: is this check even necessary? */
if(iq->referral_count > MAX_REFERRAL_COUNT) {
- verbose(VERB_ALGO, "request has exceeded the maximum "
+ verbose(VERB_DETAIL, "request has exceeded the maximum "
"number of referrrals with %d", iq->referral_count);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* Since a target query might have been made, we
* need to check again. */
if(iq->num_target_queries == 0) {
- verbose(VERB_ALGO, "out of query targets -- "
+ verbose(VERB_DETAIL, "out of query targets -- "
"returning SERVFAIL");
/* fail -- no more targets, no more hope
* of targets, no hope of a response. */
}
/* We have a valid target. */
- log_nametypeclass("sending query:", qstate->qinfo.qname,
+ log_nametypeclass(VERB_DETAIL, "sending query:", qstate->qinfo.qname,
qstate->qinfo.qtype, qstate->qinfo.qclass);
- log_addr("sending to target:", &target->addr, target->addrlen);
+ log_name_addr(VERB_DETAIL, "sending to target:", iq->dp->name,
+ &target->addr, target->addrlen);
outq = (*qstate->env->send_query)(
qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass,
if(type == RESPONSE_TYPE_ANSWER) {
/* ANSWER type responses terminate the query algorithm,
* so they sent on their */
- verbose(VERB_ALGO, "query response was ANSWER");
+ verbose(VERB_DETAIL, "query response was ANSWER");
/* FIXME: there is a question about whether this gets
* stored under the original query or most recent query.
} else if(type == RESPONSE_TYPE_REFERRAL) {
/* REFERRAL type responses get a reset of the
* delegation point, and back to the QUERYTARGETS_STATE. */
- verbose(VERB_ALGO, "query response was REFERRAL");
+ verbose(VERB_DETAIL, "query response was REFERRAL");
/* Store the referral under the current query */
if(!iter_dns_store(qstate->env, iq->response, 1))
/* CNAME type responses get a query restart (i.e., get a
* reset of the query state and go back to INIT_REQUEST_STATE).
*/
- verbose(VERB_ALGO, "query response was CNAME");
+ verbose(VERB_DETAIL, "query response was CNAME");
+ log_dns_msg("cname msg", &iq->response->qinfo, iq->response->rep);
/* Process the CNAME response. */
if(!iq->orig_qname) {
iq->orig_qname = qstate->qinfo.qname;
return next_state(qstate, iq, INIT_REQUEST_STATE);
} else if(type == RESPONSE_TYPE_LAME) {
/* Cache the LAMEness. */
- verbose(VERB_ALGO, "query response was LAME");
+ verbose(VERB_DETAIL, "query response was LAME");
if(!infra_set_lame(qstate->env->infra_cache,
&qstate->reply->addr, qstate->reply->addrlen,
iq->dp->name, iq->dp->namelen, time(NULL)))
* In this case, the event is just sent directly back to
* the QUERYTARGETS_STATE without resetting anything,
* because, clearly, the next target must be tried. */
- verbose(VERB_ALGO, "query response was THROWAWAY");
+ verbose(VERB_DETAIL, "query response was THROWAWAY");
} else {
log_warn("A query response came back with an unknown type: %d",
(int)type);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
- log_nametypeclass("priming successful for", qstate->qinfo.qname,
- qstate->qinfo.qtype, qstate->qinfo.qclass);
+ log_nametypeclass(VERB_DETAIL, "priming successful for",
+ qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
delegpt_log(dp);
foriq = (struct iter_qstate*)forq->minfo[id];
foriq->dp = dp;
processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
int id)
{
- log_nametypeclass("finishing processing for", qstate->qinfo.qname,
- qstate->qinfo.qtype, qstate->qinfo.qclass);
+ log_nametypeclass(VERB_DETAIL, "finishing processing for",
+ qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
if(!iq->response) {
verbose(VERB_ALGO, "No response is set, servfail");
iq->response = dns_alloc_msg(pkt, prs, qstate->region);
if(!iq->response)
goto handle_it;
- log_dns_msg("incoming scrubbed packet", &iq->response->qinfo,
- iq->response->rep);
+ log_name_addr(VERB_DETAIL, "incoming packet from target:", iq->dp->name,
+ &qstate->reply->addr, qstate->reply->addrlen);
+ if(verbosity >= VERB_ALGO)
+ log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo,
+ iq->response->rep);
handle_it:
outbound_list_remove(&iq->outlist, outbound);
{
struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
- verbose(VERB_ALGO, "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));
- if(iq) log_nametypeclass("for qstate", qstate->qinfo.qname,
- qstate->qinfo.qtype, qstate->qinfo.qclass);
+ if(iq) log_nametypeclass(VERB_DETAIL, "iterator operate: query",
+ qstate->qinfo.qname, qstate->qinfo.qtype, qstate->qinfo.qclass);
if(ie->fwd_addrlen != 0) {
perform_forward(qstate, event, id, outbound);
return;
}
/* perform iterator state machine */
if(event == module_event_new && iq == NULL) {
- log_info("iter state machine");
if(!iter_new(qstate, id)) {
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
return;
struct outside_network* outnet = pend->query->outnet;
verbose(VERB_ALGO, "outnettcp cb");
if(error != NETEVENT_NOERROR) {
- log_info("outnettcp got tcp error %d", error);
+ verbose(VERB_DETAIL, "outnettcp got tcp error %d", error);
/* pass error below and exit */
} else {
/* check ID */
verbose(VERB_ALGO, "answer cb");
if(error != NETEVENT_NOERROR) {
- log_info("outnetudp got udp error %d", error);
+ verbose(VERB_DETAIL, "outnetudp got udp error %d", error);
return 0;
}
if(ldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) {
- log_info("outnetudp udp too short");
+ verbose(VERB_DETAIL, "outnetudp udp too short");
return 0;
}
log_assert(reply_info);
key.id = LDNS_ID_WIRE(ldns_buffer_begin(c->buffer));
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
key.addrlen = reply_info->addrlen;
- verbose(VERB_ALGO, "Incoming reply id=%4.4x addr=", key.id);
+ verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id);
if(verbosity >= VERB_ALGO) {
- log_addr("Incoming reply addr=", &reply_info->addr, reply_info->addrlen);
+ log_addr("Incoming reply addr =", &reply_info->addr, reply_info->addrlen);
}
/* find it, see if this thing is a valid query response */
log_err("gettimeofday: %s", strerror(errno));
return 0;
}
- verbose(VERB_DETAIL, "serviced query UDP timeout=%d msec", rtt);
+ verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt);
sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr,
sq->addrlen, rtt, serviced_udp_callback, sq, sq->outnet->rnd);
if(!sq->pending)
/* convert from microseconds to milliseconds */
int roundtime = (now.tv_sec - sq->last_sent_time.tv_sec)*1000
+ ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
- log_info("measured roundtrip at %d msec", roundtime);
+ verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime);
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
roundtime, (time_t)now.tv_sec))
log_err("out of memory noting rtt.");
*dname = d->rr_data[0]+sizeof(uint16_t);
*dname_len = len;
}
+
+void
+packed_rrset_ttl_add(struct packed_rrset_data* data, uint32_t add)
+{
+ size_t i;
+ size_t total = data->count + data->rrsig_count;
+ data->ttl += add;
+ for(i=0; i<total; i++)
+ data->rr_ttl[i] += add;
+}
*/
void packed_rrset_ptr_fixup(struct packed_rrset_data* data);
+/**
+ * Fixup TTLs in fixed data packed_rrset_data blob.
+ * @param data: rrset data structure. Otherwise correctly filled in.
+ * @param add: how many seconds to add, pass time(0) for example.
+ */
+void packed_rrset_ttl_add(struct packed_rrset_data* data, uint32_t add);
+
/**
* Utility procedure to extract CNAME target name from its rdata.
* Failsafes; it will change passed dname to a valid dname or do nothing.
sub->subquery_prev = NULL;
}
+void
+module_subreq_insert(struct module_qstate** head, struct module_qstate* sub)
+{
+ if(*head)
+ (*head)->subquery_prev = sub;
+ sub->subquery_next = *head;
+ sub->subquery_prev = NULL;
+ *head = sub;
+}
+
int
module_subreq_depth(struct module_qstate* sub)
{
* Remove subqrequest from list.
* @param head: List head. pointer to start of subquery_next/prev sibling list.
* mostly reference to the parent subquery_first.
- * @param sub: subrequest. Parent pointer used to access list.
- * It is snipped off.
+ * @param sub: subrequest. It is snipped off.
*/
void module_subreq_remove(struct module_qstate** head,
struct module_qstate* sub);
+/**
+ * Insert subqrequest in list. You must set the parent ptr of sub correctly.
+ * @param head: List head. pointer to start of subquery_next/prev sibling list.
+ * mostly reference to the parent subquery_first.
+ * @param sub: subrequest. It is added to the list.
+ */
+void module_subreq_insert(struct module_qstate** head,
+ struct module_qstate* sub);
+
/**
* Calculate depth of subrequest
* @param sub: the subrequest. parent point is used.
}
void
-log_nametypeclass(const char* str, uint8_t* name, uint16_t type,
- uint16_t dclass)
+log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
+ uint16_t type, uint16_t dclass)
{
char buf[LDNS_MAX_DOMAINLEN+1];
char t[12], c[12];
const char *ts, *cs;
+ if(verbosity < v)
+ return;
dname_str(name, buf);
if(ldns_rr_descript(type) && ldns_rr_descript(type)->_name)
ts = ldns_rr_descript(type)->_name;
log_info("%s <%s %s %s>", str, buf, ts, cs);
}
+void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
+ struct sockaddr_storage* addr, socklen_t addrlen)
+{
+ uint16_t port;
+ const char* family = "unknown_family ";
+ char namebuf[LDNS_MAX_DOMAINLEN+1];
+ char dest[100];
+ int af = (int)((struct sockaddr_in*)addr)->sin_family;
+ void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
+ if(verbosity < v)
+ return;
+ switch(af) {
+ case AF_INET: family=""; break;
+ case AF_INET6: family="";
+ sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
+ break;
+ case AF_UNIX: family="unix_family "; break;
+ default: break;
+ }
+ if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
+ strncpy(dest, "(inet_ntop error)", sizeof(dest));
+ }
+ port = ntohs(((struct sockaddr_in*)addr)->sin_port);
+ dname_str(zone, namebuf);
+ if(af != AF_INET && af != AF_INET6)
+ verbose(VERB_DETAIL, "%s <%s> %s%s#%d (addrlen %d)",
+ str, namebuf, family, dest, (int)port, (int)addrlen);
+ else verbose(VERB_DETAIL, "%s <%s> %s%s#%d",
+ str, namebuf, family, dest, (int)port);
+}
+
int
addr_is_ip6(struct sockaddr_storage* addr)
{
#ifndef NET_HELP_H
#define NET_HELP_H
+#include "util/log.h"
/** DNS constants for uint16_t style flag manipulation. host byteorder. */
/** AA flag */
void log_addr(const char* str, struct sockaddr_storage* addr,
socklen_t addrlen);
+/**
+ * Prints zone name and sockaddr in readable format with log_info. Debug.
+ * @param v: at what verbosity level to print this.
+ * @param str: descriptive string printed with it.
+ * @param zone: DNS domain name, uncompressed wireformat.
+ * @param addr: the sockaddr to print. Can be ip4 or ip6.
+ * @param addrlen: length of addr.
+ */
+void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
+ struct sockaddr_storage* addr, socklen_t addrlen);
+
/**
* Convert ip address string and port to sockaddr.
* @param ip: ip4 or ip6 address string.
/**
* Print string with neat domain name, type and class.
+ * @param v: at what verbosity level to print this.
* @param str: string of message.
* @param name: domain name uncompressed wireformat.
* @param type: host format RR type.
* @param dclass: host format RR class.
*/
-void log_nametypeclass(const char* str, uint8_t* name, uint16_t type,
- uint16_t dclass);
+void log_nametypeclass(enum verbosity_value v, const char* str,
+ uint8_t* name, uint16_t type, uint16_t dclass);
/**
* Checkout address family.