dns_transmit bugdns_transmit implements a state-machine for sending
and retrying DNS queries over UDP and TCP. tcpstate == 2
indicates that the file descriptor d->s1 - 1 is
a TCP socket connected to a DNS cache and
that d->pos bytes of the DNS query have been sent over that socket
[see comments on lines 299–300 of
dns_transmit.c].
The state-machine arrives at tcpstate == 2 one of two
ways. connect(2) can return -1/EINPROGRESS,
and the state-machine will enter tcpstate == 1, which
will later transition to tcpstate == 2 if the connection
succeeds [lines 127–175,286–295]. Alternatively,
connect(2) may succeed immediately and the state-machine
will transition directly to tcpstate == 2 [lines
168–171].
When dns_transmit changes from tcpstate ==
1 to tcpstate == 2, it will reset
d->pos to 0. However, it does not do this when
connect(2) succeeds immediately.
--- dns_transmit.c.orig 2008-01-08 13:58:33.000000000 -0800
+++ dns_transmit.c 2008-01-08 13:57:56.000000000 -0800
@@ -166,6 +166,7 @@
taia_uint(&d->deadline,10);
taia_add(&d->deadline,&d->deadline,&now);
if (socket_connect4(d->s1 - 1,ip,53) == 0) {
+ d->pos = 0;
d->tcpstate = 2;
return 0;
}
This bug only affects operating systems where
connect(2) can return 0
when given a file descriptor for a non-blocking TCP socket.
I have confirmed that this affects OpenBSD 4.0 and 4.2
when connecting to local TCP address/ports.
Brief experimentation shows Linux 2.6.13 always returns
-1/EINPROGRESS.
On an OpenBSD 4.2 system with an unpatched installation of djbdns-1.05 and running dnscache according to http://cr.yp.to/djbdns/run-cache-x.html:
$ date Wed Jan 9 15:56:32 PST 2008 $ DNSCACHEIP=`cat /etc/dnscache/env/IP` dnstxt aol.com | wc -c 467 $ DNSCACHEIP=`cat /etc/dnscache/env/IP` dnstxt aol.com aol.com dnstxt: fatal: unable to find TXT records for aol.com: bad address
With the patch above applied:
$ DNSCACHEIP=`cat /etc/dnscache/env/IP` dnstxt aol.com aol.com v=spf1 ip4:152.163.225.0/24 ip4:205.188.139.0/24 ip4:205.188.144.0/24 ip4:205.188.156.0/23 ip4:205.188.159.0/24 ip4:64.12.136.0/23 ip4:64.12.138.0/24 ip4:64.12.143.99/32 ip4:64.12.143.100/32 ip4:64.12.143.101/32 ptr:mx.aol.com ?allspf2.0/pra ip4:152.163.225.0/24 ip4:205.188.139.0/24 ip4:205.188.144.0/24 ip4:205.188.156.0/23 ip4:205.188.159.0/24 ip4:64.12.136.0/23 ip4:64.12.138.0/24 ip4:64.12.143.99/32 ip4:64.12.143.100/32 ip4:64.12.143.101/32 ptr:mx.aol.com ?all v=spf1 ip4:152.163.225.0/24 ip4:205.188.139.0/24 ip4:205.188.144.0/24 ip4:205.188.156.0/23 ip4:205.188.159.0/24 ip4:64.12.136.0/23 ip4:64.12.138.0/24 ip4:64.12.143.99/32 ip4:64.12.143.100/32 ip4:64.12.143.101/32 ptr:mx.aol.com ?allspf2.0/pra ip4:152.163.225.0/24 ip4:205.188.139.0/24 ip4:205.188.144.0/24 ip4:205.188.156.0/23 ip4:205.188.159.0/24 ip4:64.12.136.0/23 ip4:64.12.138.0/24 ip4:64.12.143.99/32 ip4:64.12.143.100/32 ip4:64.12.143.101/32 ptr:mx.aol.com ?all