| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/builtin.h" | 8 #include "bin/builtin.h" |
| 9 #include "bin/eventhandler.h" | 9 #include "bin/eventhandler.h" |
| 10 #include "bin/file.h" | 10 #include "bin/file.h" |
| 11 #include "bin/log.h" | 11 #include "bin/log.h" |
| 12 #include "bin/socket.h" | 12 #include "bin/socket.h" |
| 13 | 13 |
| 14 |
| 15 SocketAddress::SocketAddress(struct addrinfo* addrinfo) { |
| 16 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); |
| 17 RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr); |
| 18 |
| 19 // Clear the port before calling WSAAddressToString as WSAAddressToString |
| 20 // includes the port in the formatted string. |
| 21 DWORD len = INET6_ADDRSTRLEN; |
| 22 int err = WSAAddressToStringA(&raw->addr, |
| 23 sizeof(RawAddr), |
| 24 NULL, |
| 25 as_string_, |
| 26 &len); |
| 27 |
| 28 if (err != 0) { |
| 29 as_string_[0] = 0; |
| 30 } |
| 31 memmove(reinterpret_cast<void *>(&addr_), |
| 32 addrinfo->ai_addr, |
| 33 addrinfo->ai_addrlen); |
| 34 } |
| 35 |
| 14 bool Socket::Initialize() { | 36 bool Socket::Initialize() { |
| 15 static bool socket_initialized = false; | 37 static bool socket_initialized = false; |
| 16 if (socket_initialized) return true; | 38 if (socket_initialized) return true; |
| 17 int err; | 39 int err; |
| 18 WSADATA winsock_data; | 40 WSADATA winsock_data; |
| 19 WORD version_requested = MAKEWORD(2, 2); | 41 WORD version_requested = MAKEWORD(2, 2); |
| 20 err = WSAStartup(version_requested, &winsock_data); | 42 err = WSAStartup(version_requested, &winsock_data); |
| 21 if (err == 0) { | 43 if (err == 0) { |
| 22 socket_initialized = true; | 44 socket_initialized = true; |
| 23 } else { | 45 } else { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 40 | 62 |
| 41 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { | 63 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { |
| 42 Handle* handle = reinterpret_cast<Handle*>(fd); | 64 Handle* handle = reinterpret_cast<Handle*>(fd); |
| 43 return handle->Write(buffer, num_bytes); | 65 return handle->Write(buffer, num_bytes); |
| 44 } | 66 } |
| 45 | 67 |
| 46 | 68 |
| 47 intptr_t Socket::GetPort(intptr_t fd) { | 69 intptr_t Socket::GetPort(intptr_t fd) { |
| 48 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); | 70 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); |
| 49 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); | 71 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); |
| 50 struct sockaddr_in socket_address; | 72 RawAddr raw; |
| 51 socklen_t size = sizeof(socket_address); | 73 socklen_t size = sizeof(raw); |
| 52 if (getsockname(socket_handle->socket(), | 74 if (getsockname(socket_handle->socket(), |
| 53 reinterpret_cast<struct sockaddr *>(&socket_address), | 75 &raw.addr, |
| 54 &size)) { | 76 &size) == SOCKET_ERROR) { |
| 55 Log::PrintErr("Error getsockname: %s\n", strerror(errno)); | 77 Log::PrintErr("Error getsockname: %d\n", WSAGetLastError()); |
| 56 return 0; | 78 return 0; |
| 57 } | 79 } |
| 58 return ntohs(socket_address.sin_port); | 80 return SocketAddress::GetAddrPort(&raw); |
| 59 } | 81 } |
| 60 | 82 |
| 61 | 83 |
| 62 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) { | 84 bool Socket::GetRemotePeer(intptr_t fd, char *host, intptr_t *port) { |
| 63 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); | 85 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); |
| 64 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); | 86 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); |
| 65 struct sockaddr_in socket_address; | 87 RawAddr raw; |
| 66 socklen_t size = sizeof(socket_address); | 88 socklen_t size = sizeof(raw); |
| 67 if (getpeername(socket_handle->socket(), | 89 if (getpeername(socket_handle->socket(), |
| 68 reinterpret_cast<struct sockaddr *>(&socket_address), | 90 &raw.addr, |
| 69 &size)) { | 91 &size)) { |
| 70 Log::PrintErr("Error getpeername: %s\n", strerror(errno)); | 92 Log::PrintErr("Error getpeername: %d\n", WSAGetLastError()); |
| 71 return false; | 93 return false; |
| 72 } | 94 } |
| 73 *port = ntohs(socket_address.sin_port); | 95 *port = SocketAddress::GetAddrPort(&raw); |
| 74 // Clear the port before calling WSAAddressToString as WSAAddressToString | 96 // Clear the port before calling WSAAddressToString as WSAAddressToString |
| 75 // includes the port in the formatted string. | 97 // includes the port in the formatted string. |
| 76 socket_address.sin_port = 0; | 98 SocketAddress::SetAddrPort(&raw, 0); |
| 77 DWORD len = INET_ADDRSTRLEN; | 99 DWORD len = INET6_ADDRSTRLEN; |
| 78 int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(&socket_address), | 100 int err = WSAAddressToStringA(&raw.addr, |
| 79 sizeof(socket_address), | 101 sizeof(raw), |
| 80 NULL, | 102 NULL, |
| 81 host, | 103 host, |
| 82 &len); | 104 &len); |
| 83 if (err != 0) { | 105 if (err != 0) { |
| 84 Log::PrintErr("Error WSAAddressToString: %d\n", WSAGetLastError()); | 106 Log::PrintErr("Error WSAAddressToString: %d\n", WSAGetLastError()); |
| 85 return false; | 107 return false; |
| 86 } | 108 } |
| 87 return true; | 109 return true; |
| 88 } | 110 } |
| 89 | 111 |
| 90 intptr_t Socket::CreateConnect(const char* host, const intptr_t port) { | 112 intptr_t Socket::CreateConnect(RawAddr addr, const intptr_t port) { |
| 91 SOCKET s = socket(AF_INET, SOCK_STREAM, 0); | 113 SOCKET s = socket(addr.ss_family, SOCK_STREAM, 0); |
| 92 if (s == INVALID_SOCKET) { | 114 if (s == INVALID_SOCKET) { |
| 93 return -1; | 115 return -1; |
| 94 } | 116 } |
| 95 | 117 |
| 96 linger l; | 118 linger l; |
| 97 l.l_onoff = 1; | 119 l.l_onoff = 1; |
| 98 l.l_linger = 10; | 120 l.l_linger = 10; |
| 99 int status = setsockopt(s, | 121 int status = setsockopt(s, |
| 100 SOL_SOCKET, | 122 SOL_SOCKET, |
| 101 SO_LINGER, | 123 SO_LINGER, |
| 102 reinterpret_cast<char*>(&l), | 124 reinterpret_cast<char*>(&l), |
| 103 sizeof(l)); | 125 sizeof(l)); |
| 104 if (status != NO_ERROR) { | 126 if (status != NO_ERROR) { |
| 105 FATAL("Failed setting SO_LINGER on socket"); | 127 FATAL("Failed setting SO_LINGER on socket"); |
| 106 } | 128 } |
| 107 | 129 |
| 108 // Perform a name lookup for an IPv4 address. | 130 SocketAddress::SetAddrPort(&addr, port); |
| 109 struct addrinfo hints; | |
| 110 memset(&hints, 0, sizeof(hints)); | |
| 111 hints.ai_family = AF_INET; | |
| 112 hints.ai_socktype = SOCK_STREAM; | |
| 113 hints.ai_protocol = IPPROTO_TCP; | |
| 114 struct addrinfo* result = NULL; | |
| 115 status = getaddrinfo(host, 0, &hints, &result); | |
| 116 if (status != NO_ERROR) { | |
| 117 return -1; | |
| 118 } | |
| 119 | |
| 120 // Copy IPv4 address and set the port. | |
| 121 struct sockaddr_in server_address; | |
| 122 memcpy(&server_address, | |
| 123 reinterpret_cast<sockaddr_in *>(result->ai_addr), | |
| 124 sizeof(server_address)); | |
| 125 server_address.sin_port = htons(port); | |
| 126 freeaddrinfo(result); // Free data allocated by getaddrinfo. | |
| 127 status = connect( | 131 status = connect( |
| 128 s, | 132 s, |
| 129 reinterpret_cast<struct sockaddr*>(&server_address), | 133 &addr.addr, |
| 130 sizeof(server_address)); | 134 SocketAddress::GetAddrLength(addr)); |
| 131 if (status == SOCKET_ERROR) { | 135 if (status == SOCKET_ERROR) { |
| 132 DWORD rc = WSAGetLastError(); | 136 DWORD rc = WSAGetLastError(); |
| 133 closesocket(s); | 137 closesocket(s); |
| 134 SetLastError(rc); | 138 SetLastError(rc); |
| 135 return -1; | 139 return -1; |
| 136 } | 140 } |
| 137 | 141 |
| 138 ClientSocket* client_socket = new ClientSocket(s); | 142 ClientSocket* client_socket = new ClientSocket(s); |
| 139 return reinterpret_cast<intptr_t>(client_socket); | 143 return reinterpret_cast<intptr_t>(client_socket); |
| 140 } | 144 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd); | 189 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd); |
| 186 ClientSocket* client_socket = listen_socket->Accept(); | 190 ClientSocket* client_socket = listen_socket->Accept(); |
| 187 if (client_socket != NULL) { | 191 if (client_socket != NULL) { |
| 188 return reinterpret_cast<intptr_t>(client_socket); | 192 return reinterpret_cast<intptr_t>(client_socket); |
| 189 } else { | 193 } else { |
| 190 return -1; | 194 return -1; |
| 191 } | 195 } |
| 192 } | 196 } |
| 193 | 197 |
| 194 | 198 |
| 195 const char* Socket::LookupIPv4Address(char* host, OSError** os_error) { | 199 SocketAddresses* Socket::LookupAddress(const char* host, |
| 196 // Perform a name lookup for an IPv4 address. | 200 int type, |
| 201 OSError** os_error) { |
| 197 Initialize(); | 202 Initialize(); |
| 203 |
| 204 // Perform a name lookup for a host name. |
| 198 struct addrinfo hints; | 205 struct addrinfo hints; |
| 199 memset(&hints, 0, sizeof(hints)); | 206 memset(&hints, 0, sizeof(hints)); |
| 200 hints.ai_family = AF_INET; | 207 hints.ai_family = SocketAddress::FromType(type); |
| 201 hints.ai_socktype = SOCK_STREAM; | 208 hints.ai_socktype = SOCK_STREAM; |
| 209 hints.ai_flags = 0; |
| 202 hints.ai_protocol = IPPROTO_TCP; | 210 hints.ai_protocol = IPPROTO_TCP; |
| 203 struct addrinfo* info = NULL; | 211 struct addrinfo* info = NULL; |
| 204 int status = getaddrinfo(host, 0, &hints, &info); | 212 int status = getaddrinfo(host, 0, &hints, &info); |
| 205 if (status != 0) { | 213 if (status != 0) { |
| 206 ASSERT(*os_error == NULL); | 214 ASSERT(*os_error == NULL); |
| 207 DWORD error_code = WSAGetLastError(); | 215 DWORD error_code = WSAGetLastError(); |
| 208 SetLastError(error_code); | 216 SetLastError(error_code); |
| 209 *os_error = new OSError(); | 217 *os_error = new OSError(); |
| 210 return NULL; | 218 return NULL; |
| 211 } | 219 } |
| 212 // Convert the address into IPv4 dotted decimal notation. | 220 intptr_t count = 0; |
| 213 char* buffer = reinterpret_cast<char*>(malloc(INET_ADDRSTRLEN)); | 221 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { |
| 214 sockaddr_in *sockaddr = reinterpret_cast<sockaddr_in *>(info->ai_addr); | 222 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++; |
| 215 | |
| 216 // Clear the port before calling WSAAddressToString as WSAAddressToString | |
| 217 // includes the port in the formatted string. | |
| 218 DWORD len = INET_ADDRSTRLEN; | |
| 219 int err = WSAAddressToStringA(reinterpret_cast<LPSOCKADDR>(sockaddr), | |
| 220 sizeof(sockaddr_in), | |
| 221 NULL, | |
| 222 buffer, | |
| 223 &len); | |
| 224 if (err != 0) { | |
| 225 free(buffer); | |
| 226 return NULL; | |
| 227 } | 223 } |
| 228 return buffer; | 224 SocketAddresses* addresses = new SocketAddresses(count); |
| 225 intptr_t i = 0; |
| 226 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { |
| 227 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) { |
| 228 addresses->SetAt(i, new SocketAddress(c)); |
| 229 i++; |
| 230 } |
| 231 } |
| 232 freeaddrinfo(info); |
| 233 return addresses; |
| 229 } | 234 } |
| 230 | 235 |
| 231 | 236 |
| 232 intptr_t ServerSocket::CreateBindListen(const char* host, | 237 intptr_t ServerSocket::CreateBindListen(RawAddr addr, |
| 233 intptr_t port, | 238 intptr_t port, |
| 234 intptr_t backlog) { | 239 intptr_t backlog) { |
| 235 unsigned long socket_addr = inet_addr(host); // NOLINT | 240 SOCKET s = socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP); |
| 236 if (socket_addr == INADDR_NONE) { | |
| 237 return -5; | |
| 238 } | |
| 239 | |
| 240 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | |
| 241 if (s == INVALID_SOCKET) { | 241 if (s == INVALID_SOCKET) { |
| 242 return -1; | 242 return -1; |
| 243 } | 243 } |
| 244 | 244 |
| 245 BOOL optval = true; | 245 BOOL optval = true; |
| 246 int status = setsockopt(s, | 246 int status = setsockopt(s, |
| 247 SOL_SOCKET, | 247 SOL_SOCKET, |
| 248 SO_REUSEADDR, | 248 SO_REUSEADDR, |
| 249 reinterpret_cast<const char*>(&optval), | 249 reinterpret_cast<const char*>(&optval), |
| 250 sizeof(optval)); | 250 sizeof(optval)); |
| 251 if (status == SOCKET_ERROR) { | 251 if (status == SOCKET_ERROR) { |
| 252 DWORD rc = WSAGetLastError(); | 252 DWORD rc = WSAGetLastError(); |
| 253 closesocket(s); | 253 closesocket(s); |
| 254 SetLastError(rc); | 254 SetLastError(rc); |
| 255 return -1; | 255 return -1; |
| 256 } | 256 } |
| 257 | 257 |
| 258 sockaddr_in addr; | 258 if (addr.ss_family == AF_INET6) { |
| 259 memset(&addr, 0, sizeof(addr)); | 259 optval = false; |
| 260 addr.sin_family = AF_INET; | 260 setsockopt(s, |
| 261 addr.sin_addr.s_addr = socket_addr; | 261 IPPROTO_IPV6, |
| 262 addr.sin_port = htons(port); | 262 IPV6_V6ONLY, |
| 263 reinterpret_cast<const char*>(&optval), |
| 264 sizeof(optval)); |
| 265 } |
| 266 |
| 267 SocketAddress::SetAddrPort(&addr, port); |
| 263 status = bind(s, | 268 status = bind(s, |
| 264 reinterpret_cast<struct sockaddr *>(&addr), | 269 &addr.addr, |
| 265 sizeof(addr)); | 270 SocketAddress::GetAddrLength(addr)); |
| 266 if (status == SOCKET_ERROR) { | 271 if (status == SOCKET_ERROR) { |
| 267 DWORD rc = WSAGetLastError(); | 272 DWORD rc = WSAGetLastError(); |
| 268 closesocket(s); | 273 closesocket(s); |
| 269 SetLastError(rc); | 274 SetLastError(rc); |
| 270 return -1; | 275 return -1; |
| 271 } | 276 } |
| 272 | 277 |
| 273 status = listen(s, backlog > 0 ? backlog : SOMAXCONN); | 278 status = listen(s, backlog > 0 ? backlog : SOMAXCONN); |
| 274 if (status == SOCKET_ERROR) { | 279 if (status == SOCKET_ERROR) { |
| 275 DWORD rc = WSAGetLastError(); | 280 DWORD rc = WSAGetLastError(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 320 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 316 int on = enabled ? 1 : 0; | 321 int on = enabled ? 1 : 0; |
| 317 return setsockopt(fd, | 322 return setsockopt(fd, |
| 318 IPPROTO_TCP, | 323 IPPROTO_TCP, |
| 319 TCP_NODELAY, | 324 TCP_NODELAY, |
| 320 reinterpret_cast<char *>(&on), | 325 reinterpret_cast<char *>(&on), |
| 321 sizeof(on)) == 0; | 326 sizeof(on)) == 0; |
| 322 } | 327 } |
| 323 | 328 |
| 324 #endif // defined(TARGET_OS_WINDOWS) | 329 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |