Search code examples
c++csocketspolling

C Socket/Polling incorrectly returning POLLOUT event?


I'm trying to write a Port open test by using sockets and for some reason this is reporting "port open" for invalid IP addresses. I'm currently plugged into an access point that's not connected to the internet so this is incorrectly reporting port open for external IP addresses.

First I set up the socket and since this is nonblocking mode it's usually still in progress by the first if statement. Then I am polling the socket. However, for a socket on an external IP, I'm getting the POLLOUT event even though that doesn't seem possible...

What am I missing? Why does the poll received events contain POLLOUT? I've tried resetting the pollfd struct before calling poll again but that didn't change the result.

result = connect(sd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

if(result == 0) //woohoo! success
{
    //SUCCESS!
    return true;
}
else if (result < 0 && errno != EINPROGRESS) //real error
{
    //FAIL
    return false;
}

// poll the socket until it connects
struct pollfd fds[1];
fds[0].fd = sd;
fds[0].events = POLLOUT | POLLRDHUP | POLLERR | POLLNVAL;
fds[0].revents = 0;

while (1)
{
    result = poll(fds, 1, 1);

    if (result < 1)
    {
        //Poll failed, mark as FAIL
    }
    else
    {
        // see which event occurred
        if (fds[0].revents & POLLOUT || fds[0].revents & POLLRDHUP)
        {
           //SUCCESS
        }
        else if (fds[0].revents & POLLERR || fds[0].revents & POLLNVAL)
        {
            //FAIL
        }
    }
}

Solution

  • I needed to check SO_ERROR after receiving the POLLOUT event - POLLOUT by itself does not indicate success.

    //now read the error code of the socket
    int errorCode;
    uint len = sizeof(errorCode);
    result = getsockopt(fds[0].fd, SOL_SOCKET, SO_ERROR,
                   &errorCode, &len);