Making accept() not block

NSD currently assumes that selecting on a TCP listen() socket will always
result in accept() not blocking. However, it doesn't mark its TCP listen()
sockets as non-blocking, so there is probably a race condition at least on
some OSes with either the -N flag (number of servers to fork) set to 2 or
more, or if someone opens a connection and closes it by the time NSD tries
to accept(). This may result in NSD not answering any requests until it
receives its next TCP connection.

There is a simple fix to this, which is to just mark the listen() socket as
non-blocking. An example patch against NSD 2.3.4 is attached below. Or you
may download it from:

     https://www.die.net/tmp/5301574a642cbb78/nsd-2.3.4-nonblockingaccept.patch

                                     -- Aaron

Oh, I didn't notice it since my select()-reduction patch makes UDP sockets
non-blocking, but this race condition is present for UDP in NSD 2.3.4 as
well if -N is > 1.

The sequence would go something like:

1) Both processes select().

2) select() in both processes shows data to read on the same UDP socket, so
    both processes recvfrom().

3) recvfrom() in one socket gets the new packet, while the other process
    blocks until the next packet is available on that socket.

If you have more than one UDP socket open (multiple -a flags passed) and are
blocking on a socket that is very infrequently used, this could result in
all but one child process being unable to answer requests. If you are on a
multi-processor machine, this would cause a significant reduction of NSD's
peak throughput on that machine.

The fix is straightforward: If you are going to be using select() or similar
for multiplexing, all network sockets you might pass to it need to be marked
as non-blocking.

                                     -- Aaron

Unpatched NSD 2.3.4 started with -N 2, strace attached to each child
process, then one query packet sent with dig:

The first child gets the query, sends the result, and goes back to select():

     Process 11499 attached - interrupt to quit
     select(5, [3 4], [], [], NULL) = 1 (in [3])
     recvfrom(3, "j\331\1\0\0\1\0\0\0\0\0\0\3die\3net\0\0\1\0\1", 131337, 0, {sa_family=AF_INET, sin_port=htons(56031), sin_addr=inet_addr("209.151.236.4")}, [16]) = 25
     sendto(3, "j\331\205\0\0\1\0\1\0\2\0\2\3die\3net\0\0\1\0\1\300\f\0"..., 109, 0, {sa_family=AF_INET, sin_port=htons(56031), sin_addr=inet_addr("209.151.236.4")}, 16) = 109
     select(5, [3 4], [], [], NULL

The second child wakes up and blocks in recvfrom():

     Process 11498 attached - interrupt to quit
     select(5, [3 4], [], [], NULL) = 1 (in [3])
     recvfrom(3,

If this were a socket that gets little or no real traffic, this child
becomes useless.

Same steps, but running NSD 2.3.4 patched to set O_NONBLOCK on the UDP
socket:

The first child acts the same:

     Process 12722 attached - interrupt to quit
     select(5, [3 4], [], [], NULL) = 1 (in [3])
     recvfrom(3, "Dy\1\0\0\1\0\0\0\0\0\0\3die\3net\0\0\1\0\1", 131337, 0, {sa_family=AF_INET, sin_port=htons(56035), sin_addr=inet_addr("209.151.236.4")}, [16]) = 25sendto(3, "Dy\205\0\0\1\0\1\0\2\0\2\3die\3net\0\0\1\0\1\300\f\0\1"..., 109, 0, {sa_family=AF_INET, sin_port=htons(56035), sin_addr=inet_addr("209.151.236.4")}, 16) = 109
     select(5, [3 4], [], [], NULL

The second wakes up, gets EAGAIN from recvfrom() and goes back to select():

     Process 12723 attached - interrupt to quit
     select(5, [3 4], [], [], NULL) = 1 (in [3])
     recvfrom(3, 0xbf5df008, 131337, 0, 0x8c6a71c, 0x8c6a79c) = -1 EAGAIN (Resource temporarily unavailable)
     select(5, [3 4], [], [], NULL

It still does unnecessary work here but at least it goes back to answering
other requests when it finds there is nothing to do.

                                     -- Aaron