locked
WSAPoll and non-blocking connects to non-existent ports RRS feed

  • Question

  • WSAPoll() is supposed to be identical to BSD's poll() function, see http://blogs.msdn.com/wndp/archive/2006/10/26/WSAPoll.aspx and the MSDN docs. According to my test, it's not. It does not report failed connections!

    Example:
    1. Create a non-blocking socket.
    2. Connect to a address&port with no listener.
    3. Call WSAPoll() with any valid flags set in the events field (eg. POLLIN|POLLOUT but I've tried every bit set, except the invalid bits), and time out to -1.

    WSAPoll will never return!

    I've tried this on FreeBSD 7.0, Linux (CentOS 5.2), and OpenSolaris 2008.05. They all report failed connections. Here's the example code which fails (blocks in WSAPoll) on Windows Vista SP1:


    #include <stdio.h>
    #include <stdlib.h>
    #include <memory.h>

    #ifdef _WIN32
    #include <WinSock2.h>
    #include <ws2ipdef.h>
    typedef SOCKET sock_t;
    #define SOCKERR GetLastError()
    #define sockpoll WSAPoll
    #define SOCKCONNBLOCK WSAEWOULDBLOCK
    #define SOCKCONNREFUSED WSAECONNREFUSED
    #else
    #include <sys/ioctl.h>
    #include <sys/poll.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #define sockpoll poll
    #define SOCKCONNBLOCK EINPROGRESS
    #define SOCKCONNREFUSED ECONNREFUSED
    #define SOCKERR errno
    typedef int sock_t;
    #endif

    #define ASSERT(x) \
        do \
        {    \
            if (!(x))    \
            {    \
                printf("ASSERT(%s) failed\n", #x);    \
                exit(1);    \
            }    \
        } while (0)

    int main()
    {
    #ifdef _WIN32
        WSADATA wsaData;
        ASSERT(WSAStartup(0x202, &wsaData) == 0);
    #endif

        sock_t sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        ASSERT(sock != (sock_t)-1);

    #ifdef _WIN32
        ULONG on = 1;
        ASSERT(ioctlsocket(sock, FIONBIO, &on) != -1);
    #else
        int on = 1;
        ASSERT(ioctl(sock, FIONBIO, &on) != -1);
    #endif

        sockaddr_in sa;
        memset(&sa, 0, sizeof(sa));
        sa.sin_family = AF_INET;
        sa.sin_port = htons(0xFEFE);
        sa.sin_addr.s_addr = htonl(0x7F000001);

        int ret = connect(sock, (sockaddr*)&sa, sizeof(sa));
        ASSERT(ret == 0 || SOCKERR == SOCKCONNBLOCK ||
                            SOCKERR == SOCKCONNREFUSED);
        if (ret != 0 && SOCKERR == SOCKCONNBLOCK)
        {
            printf("Waiting for connect to succeed or fail...\n");
            pollfd fds;
            fds.fd = sock;
            /* Setting these flags will fail immediately: POLLPRI POLLWRBAND POLLERR POLLHUP POLLNVAL */
            fds.events = POLLRDNORM | POLLRDBAND | POLLIN /*| POLLPRI*/ | POLLWRNORM | POLLOUT /*| POLLWRBAND*/ /*| POLLERR*/ /*| POLLHUP*/ /*| POLLNVAL*/;
            fds.revents = -1;
            ret = sockpoll(&fds, 1, -1);
            printf("poll returned: %d\n", ret);
            if (ret == -1)
                printf("ERROR: %d\n", SOCKERR);
        }

        return 0;
    }

    Saturday, July 5, 2008 7:20 AM

All replies

  • I've got the same problem. Any ideas ? It looks like a Windows bug and it hasn't been fixed since 2008 ...
    Tuesday, September 14, 2010 7:34 PM
  • For Microsoft, it is a known issue:

    "Windows 8 Bugs 309411 - WSAPoll does not report failed connections
      8/3/2011 6:53 PM Resolved as Won't Fix by muraris
      Has been like this forever and people are already used to it."

    "The recommendation for now is to not use the WSAPoll function it in case you encounter this issue, but rather the other Net-API functions."

    See http://curl.haxx.se/mail/lib-2012-10/0038.html for a further discussion.

    Friday, October 5, 2012 12:57 PM