Is it required that the O_NONBLOCK flag be copied from a listening socket to an accepted socket? Dan Bernstein believes this is a bug.
Pavel Kankovsky writes: > What happens when x->tcpstate == 1 (i.e. waiting for the first byte of TCP > request length), x->io->revents == 0 (i.e. not ready for i/o), and > !taia_less(stamp, &x->timeout) (i.e. the timeout has expired)? What happens on working kernels is that the read() returns -1/35, because that descriptor is nonblocking. For example, under OpenBSD: % time telnet 127.0.0.1 53 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. Connection closed by foreign host. 0.0u 0.0s 0:10.02 0.0% 0+0k 0+3io 0pf+0w Apparently Linux 2.2 fails to copy O_NONBLOCK from the listening socket to the accepted socket, so the same test will block dnscache after 10 seconds; you'll have to close the connection manually. I'd appreciate hearing exactly which kernel versions have this bug. Obvious workaround #1: add if (ndelay_on(x->tcp) == -1) { close(x->tcp); return; } /* Linux bug */ two lines after the accept4() in dnscache.c. Obvious workaround #2: use a system with the BSD networking stack. (Can't beat the Real Thing.) Thanks to Pavel for tracking this down. No thanks to Ray for giving us a bogus diagnosis instead of the crucial logs. ---Dan
-- Shields.