Index: runtime/bin/socket_win.cc |
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc |
index 05b2d865a7f6b6ce3f7fdae20d2b14a144cf1032..e366430a2d7f9ce1d05722d924fc20f1d6d06c83 100644 |
--- a/runtime/bin/socket_win.cc |
+++ b/runtime/bin/socket_win.cc |
@@ -129,7 +129,7 @@ SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { |
} |
-intptr_t Socket::Create(RawAddr addr) { |
+static intptr_t Create(RawAddr addr) { |
SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0); |
if (s == INVALID_SOCKET) { |
return -1; |
@@ -152,23 +152,17 @@ intptr_t Socket::Create(RawAddr addr) { |
} |
-intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { |
+static intptr_t Connect( |
+ intptr_t fd, RawAddr addr, const intptr_t port, RawAddr bind_addr) { |
ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket()); |
ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd); |
SOCKET s = handle->socket(); |
- 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(); |
+ handle->mark_closed(); // Destructor asserts that socket is marked closed. |
delete handle; |
closesocket(s); |
SetLastError(rc); |
@@ -223,13 +217,34 @@ intptr_t Socket::Connect(intptr_t fd, RawAddr addr, const intptr_t port) { |
} |
-intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { |
- intptr_t fd = Socket::Create(addr); |
+intptr_t Socket::CreateConnect(const RawAddr& addr, const intptr_t port) { |
+ intptr_t fd = Create(addr); |
+ if (fd < 0) { |
+ return fd; |
+ } |
+ |
+ 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; |
+ } |
+ |
+ return Connect(fd, addr, port, bind_addr); |
+} |
+ |
+ |
+intptr_t Socket::CreateBindConnect(const RawAddr& addr, |
+ const intptr_t port, |
+ const RawAddr& source_addr) { |
+ intptr_t fd = Create(addr); |
if (fd < 0) { |
return fd; |
} |
- return Socket::Connect(fd, addr, port); |
+ return Connect(fd, addr, port, source_addr); |
} |