Date: Fri, 12 May 2006 04:02:23 -0700 (PDT) From: Aaron Hopkins To: nsd-users@NLnetLabs.nl Subject: 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. diff -ur nsd-2.3.4/server.c nsd-2.3.4.safer/server.c --- nsd-2.3.4/server.c 2006-04-06 07:26:35.000000000 -0700 +++ nsd-2.3.4.safer/server.c 2006-05-12 03:44:50.000000000 -0700 @@ -308,6 +308,11 @@ } #endif + if (fcntl(nsd->tcp[i].s, F_SETFL, O_NONBLOCK) == -1) { + log_msg(LOG_ERR, "fcntl failed: %s", strerror(errno)); + return -1; + } + /* Bind it... */ if (bind(nsd->tcp[i].s, (struct sockaddr *) nsd->tcp[i].addr->ai_addr, nsd->tcp[i].addr->ai_addrlen) != 0) { log_msg(LOG_ERR, "can't bind the socket: %s", strerror(errno));