Our software (Nmap port scanner) needs to quickly determine the status of a non-blocking TCP socket connect()
. We use select()
to monitor a lot of sockets, and Windows is good at notifying us when one succeeds. But if the port is closed and the target sends a TCP RST, Windows will keep trying a few times before notifying the exceptfds
, and the socket error is WSAECONNREFUSED
as expected. Our application has its own timeout, though, and will usually mark the connection as timed-out before Windows gives up. We want to get as close as possible to the behavior of Linux, which is to notify with ECONNREFUSED
immediately upon receipt of the first RST.
We have tried using the TCP_MAXRT
socket option, and this works to get select()
to signal us right away, but the result (for closed ports) is always WSAETIMEDOUT
, which makes it impossible to distinguish closed (RST) from filtered/firewalled (network timeout), which puts us back at the original problem. Determining this distinction is a core feature of our application.
So what is the best way on Windows to find out if a non-blocking socket connect()
has received a connection reset?
EDITED TO ADD: A core problem here is this line from Microsoft's documentation on the SO_ERROR
socket option: "This per-socket error code is not always immediately set." If it were immediately set, we could check for it prior to the connect timeout.