* context_r may be 0. *context_r may not be set when _next returns 0.
*/
-void adns_checkconsistency(adns_state ads);
+void adns_checkconsistency(adns_state ads, adns_query qu);
/* Checks the consistency of adns's internal data structures.
* If any error is found, the program will abort().
+ * You may pass 0 for qu; if you pass non-null then additional checks
+ * are done to make sure that qu is a valid query.
*/
/*
#include "internal.h"
-void adns_checkconsistency(adns_state ads) { adns__consistency(ads,cc_user); }
+void adns_checkconsistency(adns_state ads, adns_query qu) {
+ adns__consistency(ads,qu,cc_user);
+}
#define DLIST_CHECK(list, nodevar, part, body) \
if ((list).head) { \
} \
}
+#define DLIST_ASSERTON(node, nodevar, list, part) \
+ do { \
+ for ((nodevar)= (list).head; \
+ (nodevar) != (node); \
+ (nodevar)= (nodevar)->part next) { \
+ assert((nodevar)); \
+ } \
+ } while(0)
+
static void checkc_query_alloc(adns_state ads, adns_query qu) {
allocnode *an;
}
static void checkc_query(adns_state ads, adns_query qu) {
+ adns_query child;
+
assert(qu->udpnextserver < ads->nservers);
assert(!(qu->udpsent & (~0UL << ads->nservers)));
assert(!(qu->tcpfailed & (~0UL << ads->nservers)));
assert(qu->udpretries <= UDPMAXRETRIES);
assert(qu->search_pos <= ads->nsearchlist);
+ if (qu->parent) DLIST_ASSERTON(qu, child, qu->parent->children, siblings.);
}
static void checkc_global(adns_state ads) {
});
}
-void adns__consistency(adns_state ads, consistency_checks cc) {
+void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc) {
+ adns_query search;
+
switch (cc) {
case cc_user:
break;
checkc_queue_timew(ads);
checkc_queue_childw(ads);
checkc_queue_output(ads);
+
+ if (qu) {
+ switch (qu->state) {
+ case query_tosend:
+ case query_tcpwait:
+ case query_tcpsent:
+ DLIST_ASSERTON(qu, search, ads->timew, );
+ break;
+ case query_child:
+ DLIST_ASSERTON(qu, search, ads->childw, );
+ break;
+ case query_done:
+ DLIST_ASSERTON(qu, search, ads->output, );
+ break;
+ default:
+ assert(!"specific query state");
+ }
+ }
}
void adns_firsttimeout(adns_state ads,
struct timeval **tv_io, struct timeval *tvbuf,
struct timeval now) {
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
adns__timeouts(ads, 0, tv_io,tvbuf, now);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
void adns_processtimeouts(adns_state ads, const struct timeval *now) {
struct timeval tv_buf;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
adns__must_gettimeofday(ads,&now,&tv_buf);
if (now) adns__timeouts(ads, 1, 0,0, *now);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
/* fd handling functions. These are the top-level of the real work of
byte udpbuf[DNS_MAXUDP];
struct sockaddr_in udpaddr;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
switch (ads->tcpstate) {
case server_disconnected:
}
r= 0;
xit:
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
int adns_processwriteable(adns_state ads, int fd, const struct timeval *now) {
int r;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
switch (ads->tcpstate) {
case server_disconnected:
}
r= 0;
xit:
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
int adns_processexceptional(adns_state ads, int fd, const struct timeval *now) {
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
switch (ads->tcpstate) {
case server_disconnected:
break;
default:
abort();
}
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return 0;
}
struct pollfd pollfds[MAX_POLLFDS];
int i, fd, maxfd, npollfds;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
if (tv_mod && (!*tv_mod || (*tv_mod)->tv_sec || (*tv_mod)->tv_usec)) {
/* The caller is planning to sleep. */
*maxfd_io= maxfd;
xit:
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
void adns_afterselect(adns_state ads, int maxfd, const fd_set *readfds,
struct pollfd pollfds[MAX_POLLFDS];
int npollfds, i;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
adns__must_gettimeofday(ads,&now,&tv_buf);
if (!now) goto xit;
adns_processtimeouts(ads,now);
maxfd,readfds,writefds,exceptfds,
*now, 0);
xit:
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
/* General helpful functions. */
void adns_globalsystemfailure(adns_state ads) {
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
while (ads->timew.head) {
adns__query_fail(ads->timew.head, adns_s_systemfail);
default:
abort();
}
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
int adns_processany(adns_state ads) {
struct pollfd pollfds[MAX_POLLFDS];
int npollfds;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
r= gettimeofday(&now,0);
if (!r) adns_processtimeouts(ads,&now);
0,0,0,0,
now,&r);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
fd_set readfds, writefds, exceptfds;
struct timeval tvbuf, *tvp;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,*query_io,cc_entex);
for (;;) {
r= internal_check(ads,query_io,answer_r,context_r);
if (r != EWOULDBLOCK) break;
adns_afterselect(ads,maxfd,&readfds,&writefds,&exceptfds,0);
}
}
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
struct timeval now;
int r;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,*query_io,cc_entex);
r= gettimeofday(&now,0);
if (!r) adns__autosys(ads,now);
r= internal_check(ads,query_io,answer_r,context_r);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
/* From check.c: */
-void adns__consistency(adns_state ads, consistency_checks cc);
+void adns__consistency(adns_state ads, adns_query qu, consistency_checks cc);
/* Useful static inline functions: */
int space, found, timeout_ms, r;
struct pollfd fds_tmp[MAX_POLLFDS];
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
if (timeout_io) {
adns__must_gettimeofday(ads,&now,&tv_nowbuf);
}
r= 0;
xit:
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
const struct timeval *now) {
struct timeval tv_buf;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
adns__must_gettimeofday(ads,&now,&tv_buf);
if (now) {
adns__timeouts(ads, 1, 0,0, *now);
adns__fdevents(ads, fds,nfds, 0,0,0,0, *now,0);
}
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
#endif
adns_query qu;
const char *p;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
typei= adns__findtype(type);
if (!typei) return ENOSYS;
}
query_simple(ads,qu, owner,ol, typei,flags, now);
}
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,qu,cc_entex);
return 0;
x_adnsfail:
adns__query_fail(qu,stat);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,qu,cc_entex);
return 0;
x_errno:
r= errno;
assert(r);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
return r;
}
adns_state ads;
ads= qu->ads;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,qu,cc_entex);
switch (qu->state) {
case query_tosend: case query_tcpwait: case query_tcpsent:
LIST_UNLINK(ads->timew,qu);
free_query_allocs(qu);
free(qu->answer);
free(qu);
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
}
void adns__update_expires(adns_query qu, unsigned long ttl, struct timeval now) {
r= init_finish(ads);
if (r) return r;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
*ads_r= ads;
return 0;
}
}
r= init_finish(ads); if (r) return r;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
*ads_r= ads;
return 0;
}
void adns_finish(adns_state ads) {
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
for (;;) {
if (ads->timew.head) adns_cancel(ads->timew.head);
else if (ads->childw.head) adns_cancel(ads->childw.head);
}
void adns_forallqueries_begin(adns_state ads) {
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
ads->forallnext=
ads->timew.head ? ads->timew.head :
ads->childw.head ? ads->childw.head :
adns_query adns_forallqueries_next(adns_state ads, void **context_r) {
adns_query qu, nqu;
- adns__consistency(ads,cc_entex);
+ adns__consistency(ads,0,cc_entex);
nqu= ads->forallnext;
for (;;) {
qu= nqu;