When building the cURL library on Windows with _WIN32_WINNT=0x0600, cURL will 
use the WSAPoll API  function (available in Vista and higher).
However, cURL will suffer from a bug in WSAPoll.
When the cURL library is used to setup a connection to an incorrect port, 
normally the result is CURLE_COULDNT_CONNECT, /* 7 */, but due to the bug in 
WSAPoll, the result now is CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time 
was reached */.
See for example 
http://social.msdn.microsoft.com/Forums/hu/wsk/thread/18769abd-fca0-4d3c-9884-1a38ce27ae90
  ("WSAPoll and non-blocking connects to non-existent ports").
The bug in WSAPoll is also demonstrated in the attached program 
TestSocketConnect.cpp.
Adapt lines 141 and 142 to specify IP address and port number. In my case:
                TestSocketConnection("10.21.46.81", 443,  lTimeout);
                TestSocketConnection("10.21.46.81", 8443, lTimeout);
Port 443 is not available, port 8443 works fine.
Output of the program (specify timeout in ms on command line, default is 1000):
=============
Hello, world!
WSAStartup returned 0.


lSOCKET is 0x00000074.
ioctlsocket(FIONBIO, 1) returned 0.
connecting to 10.21.46.81, port 443.
connect() returned -1.
WSAGetLastError() returned 10035.

WSAPoll(timeout=1000ms) returned 0.
lWSAPOLLFD.revents is 0x00
getsockopt() returned 0, lError is 10061.

closesocket() returned 0.


lSOCKET is 0x00000074.
ioctlsocket(FIONBIO, 1) returned 0.
connecting to 10.21.46.81, port 8443.
connect() returned -1.
WSAGetLastError() returned 10035.

WSAPoll(timeout=1000ms) returned 1.
lWSAPOLLFD.revents is 0x10
getsockopt() returned 0, lError is 0.

closesocket() returned 0.

WSACleanup returned 0.
Bye, world!
=============

#include <stdio.h>
#include <WinSock2.h>

void    TestSocketConnection(
        const char *    aIPAddress,
        USHORT          aPortNumber,
        INT             aTimeout
)
{
        SOCKET  lSOCKET                 = socket(
                                                AF_INET,        // 2,   // 
family
                                                SOCK_STREAM,    // 1,   // type
                                                IPPROTO_IP      // 0    // 
protocol
                                        );

        printf( "\n"
                "\n"
                "lSOCKET is 0x%08X.\n",
                lSOCKET
        );

        unsigned long
                lFlags                  = 1;

        int     lReturnValue            = ioctlsocket(
                                                lSOCKET,
                                                FIONBIO,
                                                &lFlags
                                        );

        printf( "ioctlsocket(FIONBIO, 1) returned %d.\n",
                lReturnValue
        );

        printf( "connecting to %s, port %u.\n",
                aIPAddress,
                aPortNumber
        );

        sockaddr_in     lsockaddr_in;

        lsockaddr_in.sin_family         = AF_INET;
        lsockaddr_in.sin_addr.s_addr    = inet_addr(aIPAddress);
        lsockaddr_in.sin_port           = htons(aPortNumber);

        lReturnValue    = connect(
                                lSOCKET,
                                (sockaddr *)&lsockaddr_in,
                                sizeof(lsockaddr_in)
                        );

        printf( "connect() returned %d.\n",
                lReturnValue
        );

        int     lWSAError       = 0;

        if (lReturnValue == SOCKET_ERROR) {
                lWSAError       = WSAGetLastError();

                printf( "WSAGetLastError() returned %d.\n",
                        lWSAError
                );
        }

        if (lWSAError == WSAEWOULDBLOCK) {
                int     lError          = 0;
                int     lErrorSize      = sizeof(lError);
                int     lPollCount      = 0;

                while (lPollCount == 0 && lError == 0) {
                        WSAPOLLFD       lWSAPOLLFD;

                        lWSAPOLLFD.fd           = lSOCKET;
                        lWSAPOLLFD.events       = POLLWRNORM;
                        lWSAPOLLFD.revents      = 0;

                        lPollCount      = WSAPoll(
                                                &lWSAPOLLFD,
                                                1,
                                                aTimeout
                                        );

                        printf( "\n"
                                "WSAPoll(timeout=%dms) returned %d.\n"
                                "lWSAPOLLFD.revents is 0x%02X\n",
                                aTimeout,
                                lPollCount,
                                lWSAPOLLFD.revents
                        );

                        lReturnValue    = getsockopt(
                                                lSOCKET,
                                                SOL_SOCKET,
                                                SO_ERROR,
                                                (char *)&lError,
                                                &lErrorSize
                                        );

                        printf( "getsockopt() returned %d, lError is %d.\n",
                                lReturnValue,
                                lError
                        );
                }
        }

        lReturnValue    = closesocket(lSOCKET);

        printf( "\n"
                "closesocket() returned %d.\n",
                lReturnValue
        );
}

int     main(
        int     aArgumentCount,
        char *  aArgumentValue[]
)
{
        printf("Hello, world!\n");

        WORD    lRequestedVersion       = MAKEWORD(2, 2);

        WSADATA lWSADATA;

        int     lReturnValue            = WSAStartup(
                                                lRequestedVersion,
                                                &lWSADATA
                                        );

        printf( "WSAStartup returned %d.\n",
                lReturnValue
        );

        INT     lTimeout        = 1000;

        if (2 <= aArgumentCount) {
                lTimeout        = atoi(aArgumentValue[1]);
        }

        TestSocketConnection("10.21.46.81", 443,  lTimeout);
        TestSocketConnection("10.21.46.81", 8443, lTimeout);

        lReturnValue    = WSACleanup();

        printf( "\n"
                "WSACleanup returned %d.\n",
                lReturnValue
        );

        printf("Bye, world!\n");

        return 0;
}
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to