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