Chromium Code Reviews| Index: runtime/bin/socket_win.cc |
| diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc |
| index 7f1de2d94c4b97994551d90f09514306bad348db..b58b81d8140f0406681e18faf01d5d8b062c2b65 100644 |
| --- a/runtime/bin/socket_win.cc |
| +++ b/runtime/bin/socket_win.cc |
| @@ -146,6 +146,25 @@ intptr_t Socket::Create(RawAddr addr) { |
| FATAL("Failed setting SO_LINGER on socket"); |
| } |
| + if (addr.ss.ss_family == AF_INET) { |
| + struct sockaddr_in a; |
| + memset(&a, 0, sizeof(a)); |
| + a.sin_family = AF_INET; |
| + a.sin_addr.s_addr = INADDR_ANY; |
| + a.sin_port = 0; |
| + status = bind(s, reinterpret_cast<SOCKADDR*>(&a), sizeof(a)); |
| + } else { |
| + struct sockaddr_in6 a; |
| + memset(&a, 0, sizeof(a)); |
| + a.sin6_family = AF_INET6; |
| + a.sin6_addr = in6addr_any; |
| + a.sin6_port = 0; |
| + status = bind(s, reinterpret_cast<SOCKADDR*>(&a), sizeof(a)); |
| + } |
|
Søren Gjesse
2014/05/01 07:19:26
Can't you use the same code as is used for the oth
Anders Johnsen
2014/05/01 08:05:11
Done.
|
| + if (status != NO_ERROR) { |
|
Søren Gjesse
2014/05/01 07:19:26
This should not be fatal.
Anders Johnsen
2014/05/01 08:05:11
Done.
|
| + FATAL("Failed binding socket"); |
| + } |
| + |
| ClientSocket* client_socket = new ClientSocket(s); |
| return reinterpret_cast<intptr_t>(client_socket); |
| } |
| @@ -153,18 +172,53 @@ 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); |
| + 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(); |
| - SetLastError(rc); |
| - return -1; |
| + |
| + LPFN_CONNECTEX connectEx = NULL; |
| + GUID guid_connect_ex = WSAID_CONNECTEX; |
| + DWORD bytes; |
| + int status = WSAIoctl(s, |
|
Søren Gjesse
2014/05/01 07:19:26
Are you sure you cannot just load this once like i
Anders Johnsen
2014/05/01 08:05:11
No, it's using the socket as an argument. Also, it
Søren Gjesse
2014/05/01 09:42:38
Of cause you are right.
|
| + 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(); |
| } |
| - return fd; |
| + handle->Close(); |
| + delete handle; |
| + SetLastError(rc); |
| + return -1; |
| } |