uadns (0.8) BETA; urgency=low
+ Bugfixes:
* Spurious `server failure on unidentifiable query' warning suppressed.
- * install-sh (from autoconf 2.12 Debian r13) included.
* adnslogres: cast chars to unsigned char before using ctype.h macros.
+ * In _beforeselect, global failure now means zero timeout, and in
+ tcp_events, really never try to do anything with the TCP connection if
+ act is zero. This might possibly cause an infinite delay (ie, lockup)
+ if things go badly wrong *and* a really unlikely race happens.
+ * Test suite `lines of syscall left' value is correct; !0 is failure.
+
+ Portability fixes:
+ * install-sh (from autoconf 2.12 Debian r13) included.
+
+ Documentation improvements:
* Security/performance note added, about local nameservers and DNSSEC.
* Documented that adns_rr_info _rr_hostaddr ( ) for address list
means permanent failure, and ? means temporary failure.
* Typo (*now for now in _beforeselect description) in adns.h fixed.
- * In _beforeselect, global system failure now produces zero timeout.
+
+ Changes to produce more defensive code:
+ * In adns_wait, assert that the timeout is not infinite.
+ * Make qu->id start out as -2 when initially allocated.
--
fd= atoi(fdstr);
Tinputfile= fdopen(fd,"r"); if (!Tinputfile) Tfailed("fdopen ADNS_TEST_IN_FD");
}
+ setvbuf(Tinputfile,0,_IONBF,0);
if (!adns__vbuf_ensure(&vb2,1000)) Tnomem();
fgets(vb2.buf,vb2.avail,Tinputfile); Pcheckinput();
then
:
else
- failed=true
+ failwhy="$failwhy WRONG OUTPUT"
fi
done
-if $failed
+cat >"$ocase.leftover"
+if egrep . /dev/null "$ocase.leftover"
then
- echo >&2 "FAILED $case - WRONG OUTPUT - lines of syscall remaining `wc -l`"
+ failwhy="$failwhy EXITED EARLY"
+fi
+
+if [ "x$failwhy" != x ]
+then
+ scremain="`wc -l <\"$ocase.leftover\"`"
+ echo >&2 "FAILED $case -$failwhy - lines of syscall remaining $scremain"
mrc=2
exit
fi
return;
}
+static void inter_immed(struct timeval **tv_io, struct timeval *tvbuf) {
+ struct timeval *rbuf;
+
+ if (!tv_io) return;
+
+ rbuf= *tv_io;
+ if (!rbuf) { *tv_io= rbuf= tvbuf; }
+
+ timerclear(rbuf);
+}
+
static void inter_maxto(struct timeval **tv_io, struct timeval *tvbuf,
struct timeval maxto) {
struct timeval *rbuf;
if (!timercmp(&now,&qu->timeout,>)) {
inter_maxtoabs(tv_io,tvbuf,now,qu->timeout);
} else {
- if (!act) {
- tvbuf->tv_sec= 0;
- tvbuf->tv_usec= 0;
- *tv_io= tvbuf;
- return;
- }
+ if (!act) { inter_immed(tv_io,tvbuf); return; }
LIST_UNLINK(*queue,qu);
if (qu->state != query_tosend) {
adns__query_fail(qu,adns_s_timeout);
for (;;) {
switch (ads->tcpstate) {
case server_broken:
+ if (!act) { inter_immed(tv_io,tvbuf); return; }
for (qu= ads->tcpw.head; qu; qu= nqu) {
nqu= qu->next;
assert(qu->state == query_tcpw);
ads->tcpstate= server_disconnected;
case server_disconnected: /* fall through */
if (!ads->tcpw.head) return;
+ if (!act) { inter_immed(tv_io,tvbuf); return; }
adns__tcp_tryconnect(ads,now);
break;
case server_ok:
timevaladd(&ads->tcptimeout,TCPIDLEMS);
}
case server_connecting: /* fall through */
- if (!timercmp(&now,&ads->tcptimeout,>)) {
+ if (!act || !timercmp(&now,&ads->tcptimeout,>)) {
inter_maxtoabs(tv_io,tvbuf,now,ads->tcptimeout);
return;
} {
abort();
}
}
+ return;
}
void adns__timeouts(adns_state ads, int act,
maxfd= 0; tvp= 0;
FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds);
adns_beforeselect(ads,&maxfd,&readfds,&writefds,&exceptfds,&tvp,&tvbuf,0);
+ assert(tvp);
rsel= select(maxfd,&readfds,&writefds,&exceptfds,tvp);
if (rsel==-1) {
if (errno == EINTR) {
server_ok, server_broken
} tcpstate;
struct timeval tcptimeout;
- /* This will have tv_sec==0 if it is not valid.
- * It will always be valid if tcpstate _connecting.
- * When _ok, it will be nonzero if we are idle
- * (ie, tcpw queue is empty) and counting down.
+ /* This will have tv_sec==0 if it is not valid. It will always be
+ * valid if tcpstate _connecting. When _ok, it will be nonzero if
+ * we are idle (ie, tcpw queue is empty), in which case it is the
+ * absolute time when we will close the connection.
*/
struct sigaction stdsigpipe;
sigset_t stdsigmask;
adns__vbuf_init(&qu->search_vb);
qu->search_origlen= qu->search_pos= qu->search_doneabs= 0;
- qu->id= 0;
+ qu->id= -2; /* will be overwritten with real id before we leave adns */
qu->flags= flags;
qu->retries= 0;
qu->udpnextserver= 0;