Ejemplo n.º 1
0
/*
 * @implemented
 */
INT
WSAAPI
connect(IN SOCKET s,
        IN CONST struct sockaddr *name,
        IN INT namelen)
{
    PWSPROCESS Process;
    PWSTHREAD Thread;
    PWSSOCKET Socket;
    INT ErrorCode, OldErrorCode = ERROR_SUCCESS;
    INT Status;
    BOOLEAN TryAgain = TRUE;
    DPRINT("connect: %lx, %p, %lx\n", s, name, namelen);

    /* Enter prolog */
    ErrorCode = WsApiProlog(&Process, &Thread);
    if (ErrorCode == ERROR_SUCCESS)
    {
        /* Get the Socket Context */
        if ((Socket = WsSockGetSocket(s)))
        {
            while (TRUE)
            {
                /* Make the call */
                Status = Socket->Provider->Service.lpWSPConnect(s,
                                                                name,
                                                                namelen,
                                                                NULL,
                                                                NULL,
                                                                NULL,
                                                                NULL,
                                                                &ErrorCode);

                /* Check if error code was due to the host not being found */
                if ((Status == SOCKET_ERROR) &&
                    ((ErrorCode == WSAEHOSTUNREACH) ||
                     (ErrorCode == WSAENETUNREACH)))
                {
                    /* Check if we can try again */
                    if (TryAgain)
                    {
                        /* Save the old error code */
                        OldErrorCode = ErrorCode;

                        /* Make sure we don't retry 3 times */
                        TryAgain = FALSE;

                        /* Make the RAS Auto-dial attempt */
                        if (WSAttemptAutodialAddr(name, namelen)) continue;
                    }
                    else
                    {
                        /* Restore the error code */
                        ErrorCode = OldErrorCode;
                    }
                }

                /* Break out of the loop */
                break;
            }

            /* Deference the Socket Context */
            WsSockDereference(Socket);

            /* Return Provider Value */
            if (Status == ERROR_SUCCESS) return Status;

            /* If everything seemed fine, then the WSP call failed itself */
            if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
        }
        else
        {
            /* No Socket Context Found */
            ErrorCode = WSAENOTSOCK;
        }
    }

    /* If this is Winsock 1.1, normalize the error code */
    if ((ErrorCode == WSAEALREADY) && (LOBYTE(Process->Version) == 1))
    {
        /* WS 1.1 apps expect this */
        ErrorCode = WSAEINVAL;
    }

    /* Return with an Error */
    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}
Ejemplo n.º 2
0
int WSAAPI
connect(
    IN SOCKET s,
    IN const struct sockaddr FAR *name,
    IN int namelen
)
/*++
Routine Description:

    Establish a connection to a peer.

Arguments:

    s       - A descriptor identifying an unconnected socket.

    name    - The name of the peer to which the socket is to be connected.

    namelen - The length of the name.

Returns:

    Zero  on  success  else  SOCKET_ERROR.   The  error  code  is  stored  with
    SetLastError().

--*/
{

    INT                ReturnValue;
    PDPROCESS          Process;
    PDTHREAD           Thread;
    PDPROVIDER         Provider;
    INT                ErrorCode;
    PDSOCKET           Socket;
    BOOL               RetryConnect;
    INT				   SavedErrorCode;


    ErrorCode = PROLOG(&Process, &Thread);
    if (ErrorCode==ERROR_SUCCESS)
    {
        Socket = DSOCKET::GetCountedDSocketFromSocket(s);
        if(Socket != NULL) {
            Provider = Socket->GetDProvider();
#ifdef RASAUTODIAL
            RetryConnect = FALSE;
retry:
#endif // RASAUTODIAL
            ReturnValue = Provider->WSPConnect(s,
                                               name,
                                               namelen,
                                               NULL,
                                               NULL,
                                               NULL,
                                               NULL,
                                               &ErrorCode);
#ifdef RASAUTODIAL
            if (ReturnValue == SOCKET_ERROR &&
                    (ErrorCode == WSAEHOSTUNREACH || ErrorCode == WSAENETUNREACH))
            {
                if (!RetryConnect) {
                    //
                    // We preserve the original error
                    // so we can return it in case the
                    // second call to WSPConnect() fails
                    // also.
                    //
                    SavedErrorCode = ErrorCode;
                    //
                    // Only one retry per connect attempt.
                    //
                    RetryConnect = TRUE;
                    if (WSAttemptAutodialAddr(name, namelen))
                        goto retry;
                }
                else
                    ErrorCode = SavedErrorCode;
            }
#endif // RASAUTODIAL
            Socket->DropDSocketReference();
            if (ReturnValue==ERROR_SUCCESS)
                return ReturnValue;
            assert (ErrorCode!=NO_ERROR);
            if (ErrorCode==NO_ERROR)
                ErrorCode = WSASYSCALLFAILURE;
        }
        else {
            ErrorCode = WSAENOTSOCK;
        }
    }

    //
    // If this is a 1.x application and the service provider
    // failed the request with WSAEALREADY, map the error code
    // to WSAEINVAL to be consistent with MS's WinSock 1.1
    // implementations.
    //

    if( ErrorCode == WSAEALREADY &&
            Process->GetMajorVersion() == 1 ) {
        ErrorCode = WSAEINVAL;
    }

    SetLastError(ErrorCode);
    return SOCKET_ERROR;
}