/* * @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; }
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; }