| Index: runtime/bin/socket_win.cc
|
| diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
|
| index 7c27fde29cc6d64e71a6f62f6e2f255710db8c98..5ec7f1fa7c5c2c5052ef59e2613c3717914534d8 100644
|
| --- a/runtime/bin/socket_win.cc
|
| +++ b/runtime/bin/socket_win.cc
|
| @@ -155,19 +155,73 @@ intptr_t Socket::Create(RawAddr addr) {
|
|
|
|
|
| intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) {
|
| - ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
|
| - SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
|
| + ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket());
|
| + ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd);
|
| SOCKET s = handle->socket();
|
| - SocketAddress::SetAddrPort(&addr, port);
|
| - int status = connect(s, &addr.addr, SocketAddress::GetAddrLength(&addr));
|
| - if (status == SOCKET_ERROR) {
|
| - DWORD rc = WSAGetLastError();
|
| - ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
|
| - client_socket->Close();
|
| +
|
| + RawAddr bind_addr;
|
| + memset(&bind_addr, 0, sizeof(bind_addr));
|
| + bind_addr.ss.ss_family = addr.ss.ss_family;
|
| + if (addr.ss.ss_family == AF_INET) {
|
| + bind_addr.in.sin_addr.s_addr = INADDR_ANY;
|
| + } else {
|
| + bind_addr.in6.sin6_addr = in6addr_any;
|
| + }
|
| + int status = bind(
|
| + s, &bind_addr.addr, SocketAddress::GetAddrLength(&bind_addr));
|
| + if (status != NO_ERROR) {
|
| + int rc = WSAGetLastError();
|
| + delete handle;
|
| + closesocket(s);
|
| SetLastError(rc);
|
| return -1;
|
| }
|
| - return fd;
|
| +
|
| + SocketAddress::SetAddrPort(&addr, port);
|
| +
|
| + LPFN_CONNECTEX connectEx = NULL;
|
| + GUID guid_connect_ex = WSAID_CONNECTEX;
|
| + DWORD bytes;
|
| + status = WSAIoctl(s,
|
| + SIO_GET_EXTENSION_FUNCTION_POINTER,
|
| + &guid_connect_ex,
|
| + sizeof(guid_connect_ex),
|
| + &connectEx,
|
| + sizeof(connectEx),
|
| + &bytes,
|
| + NULL,
|
| + NULL);
|
| + DWORD rc;
|
| + if (status != SOCKET_ERROR) {
|
| + handle->EnsureInitialized(EventHandler::delegate());
|
| +
|
| + OverlappedBuffer* overlapped = OverlappedBuffer::AllocateConnectBuffer();
|
| +
|
| + status = connectEx(s,
|
| + &addr.addr,
|
| + SocketAddress::GetAddrLength(&addr),
|
| + NULL,
|
| + 0,
|
| + NULL,
|
| + overlapped->GetCleanOverlapped());
|
| +
|
| +
|
| + if (status == TRUE) {
|
| + handle->ConnectComplete(overlapped);
|
| + return fd;
|
| + } else if (WSAGetLastError() == ERROR_IO_PENDING) {
|
| + return fd;
|
| + }
|
| + rc = WSAGetLastError();
|
| + // Cleanup in case of error.
|
| + OverlappedBuffer::DisposeBuffer(overlapped);
|
| + } else {
|
| + rc = WSAGetLastError();
|
| + }
|
| + handle->Close();
|
| + delete handle;
|
| + SetLastError(rc);
|
| + return -1;
|
| }
|
|
|
|
|
|
|