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