NagiosEnterprises/nsca — pull request #1 by mbattersby (2014-10-06 07:47:17+00:00)
Title: Prevent a hang where accept returns a just-closed fd.

In SINGLE_PROCESS_DAEMON mode, the handle_events loop is logically faulty.
accept() can return a FD which is has recently been closed and is awaiting cleanup, detected by revents&POLLNVAL.

This can cause calling of the wrong handler, and doing recv() on a socket that hasn't been set O_NONBLOCK yet.

Example of the fault:

* a client FD is connected and set to events=POLLIN / handle_connection_read
* handle_connection_read gets an error/EOF and closes the fd
* a new connection comes in pending accept
* new handle_events() loop
* poll() called, listen_sock revents=POLLIN, client_fd revents=POLLNVAL
* accept() returns the same client_fd, sets events|=POLLOUT (+POLLIN from old connection)
* test (events&POLLIN)&&(revents&POLLNVAL) true
* run handle_connection_read on the new socket, calling recv() on blocking fd

This commit works around the problem by not calling the handler in case of POLLNVAL but the problem of accept() happening before POLLNVAL cleanup is handled remains.