Should O_NONBLOCK be copied from listening socket to accepting socket?

From: Michael Shields (shields@msrl.com)
Date: Mon Sep 04 2000 - 15:27:53 EST


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.


attached mail follows:


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.

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Sep 07 2000 - 21:00:19 EST