Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: runtime/bin/socket_base_win.cc

Issue 2797993005: Re-land socket refactor with fixes for Windows. (Closed)
Patch Set: Rebased + reverted original revert Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/socket_base_win.h ('k') | runtime/bin/socket_fuchsia.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(HOST_OS_WINDOWS) 8 #if defined(HOST_OS_WINDOWS)
9 9
10 #include "bin/socket.h" 10 #include "bin/socket_base.h"
11 #include "bin/socket_win.h"
12 11
13 #include "bin/builtin.h" 12 #include "bin/builtin.h"
14 #include "bin/eventhandler.h" 13 #include "bin/eventhandler.h"
15 #include "bin/file.h" 14 #include "bin/file.h"
16 #include "bin/lockers.h" 15 #include "bin/lockers.h"
17 #include "bin/log.h" 16 #include "bin/log.h"
17 #include "bin/socket_base_win.h"
18 #include "bin/thread.h" 18 #include "bin/thread.h"
19 #include "bin/utils.h" 19 #include "bin/utils.h"
20 #include "bin/utils_win.h" 20 #include "bin/utils_win.h"
21 21
22 namespace dart { 22 namespace dart {
23 namespace bin { 23 namespace bin {
24 24
25 SocketAddress::SocketAddress(struct sockaddr* sockaddr) { 25 SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
26 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); 26 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
27 RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr); 27 RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
28 28
29 // Clear the port before calling WSAAddressToString as WSAAddressToString 29 // Clear the port before calling WSAAddressToString as WSAAddressToString
30 // includes the port in the formatted string. 30 // includes the port in the formatted string.
31 int err = Socket::FormatNumericAddress(*raw, as_string_, INET6_ADDRSTRLEN); 31 int err =
32 SocketBase::FormatNumericAddress(*raw, as_string_, INET6_ADDRSTRLEN);
32 33
33 if (err != 0) { 34 if (err != 0) {
34 as_string_[0] = 0; 35 as_string_[0] = 0;
35 } 36 }
36 memmove(reinterpret_cast<void*>(&addr_), sockaddr, 37 memmove(reinterpret_cast<void*>(&addr_), sockaddr,
37 SocketAddress::GetAddrLength(*raw)); 38 SocketAddress::GetAddrLength(*raw));
38 } 39 }
39 40
40 41
41 bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) {
42 socklen_t salen = SocketAddress::GetAddrLength(addr);
43 DWORD l = len;
44 RawAddr& raw = const_cast<RawAddr&>(addr);
45 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0;
46 }
47
48
49 Socket::Socket(intptr_t fd) : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {
50 ASSERT(fd_ != kClosedFd);
51 Handle* handle = reinterpret_cast<Handle*>(fd_);
52 ASSERT(handle != NULL);
53 }
54
55
56 void Socket::SetClosedFd() {
57 ASSERT(fd_ != kClosedFd);
58 Handle* handle = reinterpret_cast<Handle*>(fd_);
59 ASSERT(handle != NULL);
60 handle->Release();
61 fd_ = kClosedFd;
62 }
63
64
65 static Mutex* init_mutex = new Mutex(); 42 static Mutex* init_mutex = new Mutex();
66 static bool socket_initialized = false; 43 static bool socket_initialized = false;
67 44
68 bool Socket::Initialize() { 45 bool SocketBase::Initialize() {
69 MutexLocker lock(init_mutex); 46 MutexLocker lock(init_mutex);
70 if (socket_initialized) { 47 if (socket_initialized) {
71 return true; 48 return true;
72 } 49 }
73 int err; 50 int err;
74 WSADATA winsock_data; 51 WSADATA winsock_data;
75 WORD version_requested = MAKEWORD(2, 2); 52 WORD version_requested = MAKEWORD(2, 2);
76 err = WSAStartup(version_requested, &winsock_data); 53 err = WSAStartup(version_requested, &winsock_data);
77 if (err == 0) { 54 if (err == 0) {
78 socket_initialized = true; 55 socket_initialized = true;
79 } else { 56 } else {
80 Log::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError()); 57 Log::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError());
81 } 58 }
82 return (err == 0); 59 return (err == 0);
83 } 60 }
84 61
85 62
86 intptr_t Socket::Available(intptr_t fd) { 63 bool SocketBase::FormatNumericAddress(const RawAddr& addr,
64 char* address,
65 int len) {
66 socklen_t salen = SocketAddress::GetAddrLength(addr);
67 DWORD l = len;
68 RawAddr& raw = const_cast<RawAddr&>(addr);
69 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0;
70 }
71
72
73 intptr_t SocketBase::Available(intptr_t fd) {
87 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); 74 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
88 return client_socket->Available(); 75 return client_socket->Available();
89 } 76 }
90 77
91 78
92 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 79 intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
93 Handle* handle = reinterpret_cast<Handle*>(fd); 80 Handle* handle = reinterpret_cast<Handle*>(fd);
94 return handle->Read(buffer, num_bytes); 81 return handle->Read(buffer, num_bytes);
95 } 82 }
96 83
97 84
98 intptr_t Socket::RecvFrom(intptr_t fd, 85 intptr_t SocketBase::RecvFrom(intptr_t fd,
99 void* buffer, 86 void* buffer,
100 intptr_t num_bytes, 87 intptr_t num_bytes,
101 RawAddr* addr) { 88 RawAddr* addr) {
102 Handle* handle = reinterpret_cast<Handle*>(fd); 89 Handle* handle = reinterpret_cast<Handle*>(fd);
103 socklen_t addr_len = sizeof(addr->ss); 90 socklen_t addr_len = sizeof(addr->ss);
104 return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len); 91 return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len);
105 } 92 }
106 93
107 94
108 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 95 intptr_t SocketBase::Write(intptr_t fd,
96 const void* buffer,
97 intptr_t num_bytes) {
109 Handle* handle = reinterpret_cast<Handle*>(fd); 98 Handle* handle = reinterpret_cast<Handle*>(fd);
110 return handle->Write(buffer, num_bytes); 99 return handle->Write(buffer, num_bytes);
111 } 100 }
112 101
113 102
114 intptr_t Socket::SendTo(intptr_t fd, 103 intptr_t SocketBase::SendTo(intptr_t fd,
115 const void* buffer, 104 const void* buffer,
116 intptr_t num_bytes, 105 intptr_t num_bytes,
117 const RawAddr& addr) { 106 const RawAddr& addr) {
118 Handle* handle = reinterpret_cast<Handle*>(fd); 107 Handle* handle = reinterpret_cast<Handle*>(fd);
119 RawAddr& raw = const_cast<RawAddr&>(addr); 108 RawAddr& raw = const_cast<RawAddr&>(addr);
120 return handle->SendTo(buffer, num_bytes, &raw.addr, 109 return handle->SendTo(buffer, num_bytes, &raw.addr,
121 SocketAddress::GetAddrLength(addr)); 110 SocketAddress::GetAddrLength(addr));
122 } 111 }
123 112
124 113
125 intptr_t Socket::GetPort(intptr_t fd) { 114 intptr_t SocketBase::GetPort(intptr_t fd) {
126 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); 115 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
127 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); 116 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
128 RawAddr raw; 117 RawAddr raw;
129 socklen_t size = sizeof(raw); 118 socklen_t size = sizeof(raw);
130 if (getsockname(socket_handle->socket(), &raw.addr, &size) == SOCKET_ERROR) { 119 if (getsockname(socket_handle->socket(), &raw.addr, &size) == SOCKET_ERROR) {
131 return 0; 120 return 0;
132 } 121 }
133 return SocketAddress::GetAddrPort(raw); 122 return SocketAddress::GetAddrPort(raw);
134 } 123 }
135 124
136 125
137 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { 126 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
138 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); 127 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
139 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); 128 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
140 RawAddr raw; 129 RawAddr raw;
141 socklen_t size = sizeof(raw); 130 socklen_t size = sizeof(raw);
142 if (getpeername(socket_handle->socket(), &raw.addr, &size)) { 131 if (getpeername(socket_handle->socket(), &raw.addr, &size)) {
143 return NULL; 132 return NULL;
144 } 133 }
145 *port = SocketAddress::GetAddrPort(raw); 134 *port = SocketAddress::GetAddrPort(raw);
146 // Clear the port before calling WSAAddressToString as WSAAddressToString 135 // Clear the port before calling WSAAddressToString as WSAAddressToString
147 // includes the port in the formatted string. 136 // includes the port in the formatted string.
148 SocketAddress::SetAddrPort(&raw, 0); 137 SocketAddress::SetAddrPort(&raw, 0);
149 return new SocketAddress(&raw.addr); 138 return new SocketAddress(&raw.addr);
150 } 139 }
151 140
152 141
153 static intptr_t Create(const RawAddr& addr) { 142 bool SocketBase::IsBindError(intptr_t error_number) {
154 SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0);
155 if (s == INVALID_SOCKET) {
156 return -1;
157 }
158
159 linger l;
160 l.l_onoff = 1;
161 l.l_linger = 10;
162 int status = setsockopt(s, SOL_SOCKET, SO_LINGER, reinterpret_cast<char*>(&l),
163 sizeof(l));
164 if (status != NO_ERROR) {
165 FATAL("Failed setting SO_LINGER on socket");
166 }
167
168 ClientSocket* client_socket = new ClientSocket(s);
169 return reinterpret_cast<intptr_t>(client_socket);
170 }
171
172
173 static intptr_t Connect(intptr_t fd,
174 const RawAddr& addr,
175 const RawAddr& bind_addr) {
176 ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket());
177 ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd);
178 SOCKET s = handle->socket();
179
180 int status =
181 bind(s, &bind_addr.addr, SocketAddress::GetAddrLength(bind_addr));
182 if (status != NO_ERROR) {
183 int rc = WSAGetLastError();
184 handle->mark_closed(); // Destructor asserts that socket is marked closed.
185 handle->Release();
186 closesocket(s);
187 SetLastError(rc);
188 return -1;
189 }
190
191 LPFN_CONNECTEX connectEx = NULL;
192 GUID guid_connect_ex = WSAID_CONNECTEX;
193 DWORD bytes;
194 status = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_connect_ex,
195 sizeof(guid_connect_ex), &connectEx, sizeof(connectEx),
196 &bytes, NULL, NULL);
197 DWORD rc;
198 if (status != SOCKET_ERROR) {
199 handle->EnsureInitialized(EventHandler::delegate());
200
201 OverlappedBuffer* overlapped = OverlappedBuffer::AllocateConnectBuffer();
202
203 status = connectEx(s, &addr.addr, SocketAddress::GetAddrLength(addr), NULL,
204 0, NULL, overlapped->GetCleanOverlapped());
205
206
207 if (status == TRUE) {
208 handle->ConnectComplete(overlapped);
209 return fd;
210 } else if (WSAGetLastError() == ERROR_IO_PENDING) {
211 return fd;
212 }
213 rc = WSAGetLastError();
214 // Cleanup in case of error.
215 OverlappedBuffer::DisposeBuffer(overlapped);
216 handle->Release();
217 } else {
218 rc = WSAGetLastError();
219 }
220 handle->Close();
221 handle->Release();
222 SetLastError(rc);
223 return -1;
224 }
225
226
227 intptr_t Socket::CreateConnect(const RawAddr& addr) {
228 intptr_t fd = Create(addr);
229 if (fd < 0) {
230 return fd;
231 }
232
233 RawAddr bind_addr;
234 memset(&bind_addr, 0, sizeof(bind_addr));
235 bind_addr.ss.ss_family = addr.ss.ss_family;
236 if (addr.ss.ss_family == AF_INET) {
237 bind_addr.in.sin_addr.s_addr = INADDR_ANY;
238 } else {
239 bind_addr.in6.sin6_addr = in6addr_any;
240 }
241
242 return Connect(fd, addr, bind_addr);
243 }
244
245
246 intptr_t Socket::CreateBindConnect(const RawAddr& addr,
247 const RawAddr& source_addr) {
248 intptr_t fd = Create(addr);
249 if (fd < 0) {
250 return fd;
251 }
252
253 return Connect(fd, addr, source_addr);
254 }
255
256
257 bool Socket::IsBindError(intptr_t error_number) {
258 return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL || 143 return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL ||
259 error_number == WSAEINVAL; 144 error_number == WSAEINVAL;
260 } 145 }
261 146
262 147
263 void Socket::GetError(intptr_t fd, OSError* os_error) { 148 void SocketBase::GetError(intptr_t fd, OSError* os_error) {
264 Handle* handle = reinterpret_cast<Handle*>(fd); 149 Handle* handle = reinterpret_cast<Handle*>(fd);
265 os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error()); 150 os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error());
266 } 151 }
267 152
268 153
269 int Socket::GetType(intptr_t fd) { 154 int SocketBase::GetType(intptr_t fd) {
270 Handle* handle = reinterpret_cast<Handle*>(fd); 155 Handle* handle = reinterpret_cast<Handle*>(fd);
271 switch (GetFileType(handle->handle())) { 156 switch (GetFileType(handle->handle())) {
272 case FILE_TYPE_CHAR: 157 case FILE_TYPE_CHAR:
273 return File::kTerminal; 158 return File::kTerminal;
274 case FILE_TYPE_PIPE: 159 case FILE_TYPE_PIPE:
275 return File::kPipe; 160 return File::kPipe;
276 case FILE_TYPE_DISK: 161 case FILE_TYPE_DISK:
277 return File::kFile; 162 return File::kFile;
278 default: 163 default:
279 return GetLastError == NO_ERROR ? File::kOther : -1; 164 return GetLastError == NO_ERROR ? File::kOther : -1;
280 } 165 }
281 } 166 }
282 167
283 168
284 intptr_t Socket::GetStdioHandle(intptr_t num) { 169 intptr_t SocketBase::GetStdioHandle(intptr_t num) {
285 if (num != 0) { 170 if (num != 0) {
286 return -1; 171 return -1;
287 } 172 }
288 HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); 173 HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
289 if (handle == INVALID_HANDLE_VALUE) { 174 if (handle == INVALID_HANDLE_VALUE) {
290 return -1; 175 return -1;
291 } 176 }
292 StdHandle* std_handle = StdHandle::Stdin(handle); 177 StdHandle* std_handle = new StdHandle(handle);
293 std_handle->Retain();
294 std_handle->MarkDoesNotSupportOverlappedIO(); 178 std_handle->MarkDoesNotSupportOverlappedIO();
295 std_handle->EnsureInitialized(EventHandler::delegate()); 179 std_handle->EnsureInitialized(EventHandler::delegate());
296 return reinterpret_cast<intptr_t>(std_handle); 180 return reinterpret_cast<intptr_t>(std_handle);
297 } 181 }
298 182
299 183
300 intptr_t ServerSocket::Accept(intptr_t fd) { 184 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
301 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd); 185 int type,
302 ClientSocket* client_socket = listen_socket->Accept(); 186 OSError** os_error) {
303 if (client_socket != NULL) {
304 return reinterpret_cast<intptr_t>(client_socket);
305 } else {
306 return -1;
307 }
308 }
309
310
311 AddressList<SocketAddress>* Socket::LookupAddress(const char* host,
312 int type,
313 OSError** os_error) {
314 Initialize(); 187 Initialize();
315 188
316 // Perform a name lookup for a host name. 189 // Perform a name lookup for a host name.
317 struct addrinfo hints; 190 struct addrinfo hints;
318 memset(&hints, 0, sizeof(hints)); 191 memset(&hints, 0, sizeof(hints));
319 hints.ai_family = SocketAddress::FromType(type); 192 hints.ai_family = SocketAddress::FromType(type);
320 hints.ai_socktype = SOCK_STREAM; 193 hints.ai_socktype = SOCK_STREAM;
321 hints.ai_flags = AI_ADDRCONFIG; 194 hints.ai_flags = AI_ADDRCONFIG;
322 hints.ai_protocol = IPPROTO_TCP; 195 hints.ai_protocol = IPPROTO_TCP;
323 struct addrinfo* info = NULL; 196 struct addrinfo* info = NULL;
(...skipping 23 matching lines...) Expand all
347 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { 220 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
348 addresses->SetAt(i, new SocketAddress(c->ai_addr)); 221 addresses->SetAt(i, new SocketAddress(c->ai_addr));
349 i++; 222 i++;
350 } 223 }
351 } 224 }
352 freeaddrinfo(info); 225 freeaddrinfo(info);
353 return addresses; 226 return addresses;
354 } 227 }
355 228
356 229
357 bool Socket::ReverseLookup(const RawAddr& addr, 230 bool SocketBase::ReverseLookup(const RawAddr& addr,
358 char* host, 231 char* host,
359 intptr_t host_len, 232 intptr_t host_len,
360 OSError** os_error) { 233 OSError** os_error) {
361 ASSERT(host_len >= NI_MAXHOST); 234 ASSERT(host_len >= NI_MAXHOST);
362 int status = getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, 235 int status = getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
363 host_len, NULL, 0, NI_NAMEREQD); 236 host_len, NULL, 0, NI_NAMEREQD);
364 if (status != 0) { 237 if (status != 0) {
365 ASSERT(*os_error == NULL); 238 ASSERT(*os_error == NULL);
366 DWORD error_code = WSAGetLastError(); 239 DWORD error_code = WSAGetLastError();
367 SetLastError(error_code); 240 SetLastError(error_code);
368 *os_error = new OSError(); 241 *os_error = new OSError();
369 return false; 242 return false;
370 } 243 }
371 return true; 244 return true;
372 } 245 }
373 246
374 247
375 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { 248 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
376 int result; 249 int result;
377 Utf8ToWideScope system_address(address); 250 Utf8ToWideScope system_address(address);
378 if (type == SocketAddress::TYPE_IPV4) { 251 if (type == SocketAddress::TYPE_IPV4) {
379 result = InetPton(AF_INET, system_address.wide(), &addr->in.sin_addr); 252 result = InetPton(AF_INET, system_address.wide(), &addr->in.sin_addr);
380 } else { 253 } else {
381 ASSERT(type == SocketAddress::TYPE_IPV6); 254 ASSERT(type == SocketAddress::TYPE_IPV6);
382 result = InetPton(AF_INET6, system_address.wide(), &addr->in6.sin6_addr); 255 result = InetPton(AF_INET6, system_address.wide(), &addr->in6.sin6_addr);
383 } 256 }
384 return result == 1; 257 return result == 1;
385 } 258 }
386 259
387 260
388 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { 261 bool SocketBase::ListInterfacesSupported() {
389 SOCKET s = socket(addr.ss.ss_family, SOCK_DGRAM, IPPROTO_UDP);
390 if (s == INVALID_SOCKET) {
391 return -1;
392 }
393
394 int status;
395 if (reuseAddress) {
396 BOOL optval = true;
397 status = setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
398 reinterpret_cast<const char*>(&optval), sizeof(optval));
399 if (status == SOCKET_ERROR) {
400 DWORD rc = WSAGetLastError();
401 closesocket(s);
402 SetLastError(rc);
403 return -1;
404 }
405 }
406
407 status = bind(s, &addr.addr, SocketAddress::GetAddrLength(addr));
408 if (status == SOCKET_ERROR) {
409 DWORD rc = WSAGetLastError();
410 closesocket(s);
411 SetLastError(rc);
412 return -1;
413 }
414
415 DatagramSocket* datagram_socket = new DatagramSocket(s);
416 datagram_socket->EnsureInitialized(EventHandler::delegate());
417 return reinterpret_cast<intptr_t>(datagram_socket);
418 }
419
420
421 bool Socket::ListInterfacesSupported() {
422 return true; 262 return true;
423 } 263 }
424 264
425 265
426 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 266 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
427 int type, 267 int type,
428 OSError** os_error) { 268 OSError** os_error) {
429 Initialize(); 269 Initialize();
430 270
431 ULONG size = 0; 271 ULONG size = 0;
432 DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | 272 DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
433 GAA_FLAG_SKIP_DNS_SERVER; 273 GAA_FLAG_SKIP_DNS_SERVER;
434 // Query the size needed. 274 // Query the size needed.
435 int status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, NULL, 275 int status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, NULL,
436 NULL, &size); 276 NULL, &size);
(...skipping 29 matching lines...) Expand all
466 u->Address.lpSockaddr, 306 u->Address.lpSockaddr,
467 StringUtilsWin::WideToUtf8(a->FriendlyName), a->Ipv6IfIndex)); 307 StringUtilsWin::WideToUtf8(a->FriendlyName), a->Ipv6IfIndex));
468 i++; 308 i++;
469 } 309 }
470 } 310 }
471 free(addrs); 311 free(addrs);
472 return addresses; 312 return addresses;
473 } 313 }
474 314
475 315
476 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, 316 void SocketBase::Close(intptr_t fd) {
477 intptr_t backlog,
478 bool v6_only) {
479 SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, IPPROTO_TCP);
480 if (s == INVALID_SOCKET) {
481 return -1;
482 }
483
484 BOOL optval = true;
485 int status =
486 setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
487 reinterpret_cast<const char*>(&optval), sizeof(optval));
488 if (status == SOCKET_ERROR) {
489 DWORD rc = WSAGetLastError();
490 closesocket(s);
491 SetLastError(rc);
492 return -1;
493 }
494
495 if (addr.ss.ss_family == AF_INET6) {
496 optval = v6_only;
497 setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
498 reinterpret_cast<const char*>(&optval), sizeof(optval));
499 }
500
501 status = bind(s, &addr.addr, SocketAddress::GetAddrLength(addr));
502 if (status == SOCKET_ERROR) {
503 DWORD rc = WSAGetLastError();
504 closesocket(s);
505 SetLastError(rc);
506 return -1;
507 }
508
509 ListenSocket* listen_socket = new ListenSocket(s);
510
511 // Test for invalid socket port 65535 (some browsers disallow it).
512 if ((SocketAddress::GetAddrPort(addr) == 0) &&
513 (Socket::GetPort(reinterpret_cast<intptr_t>(listen_socket)) == 65535)) {
514 // Don't close fd until we have created new. By doing that we ensure another
515 // port.
516 intptr_t new_s = CreateBindListen(addr, backlog, v6_only);
517 DWORD rc = WSAGetLastError();
518 closesocket(s);
519 listen_socket->Release();
520 SetLastError(rc);
521 return new_s;
522 }
523
524 status = listen(s, backlog > 0 ? backlog : SOMAXCONN);
525 if (status == SOCKET_ERROR) {
526 DWORD rc = WSAGetLastError();
527 closesocket(s);
528 listen_socket->Release();
529 SetLastError(rc);
530 return -1;
531 }
532
533 return reinterpret_cast<intptr_t>(listen_socket);
534 }
535
536
537 bool ServerSocket::StartAccept(intptr_t fd) {
538 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd);
539 listen_socket->EnsureInitialized(EventHandler::delegate());
540 // Always keep 5 outstanding accepts going, to enhance performance.
541 for (int i = 0; i < 5; i++) {
542 if (!listen_socket->IssueAccept()) {
543 DWORD rc = WSAGetLastError();
544 listen_socket->Close();
545 if (!listen_socket->HasPendingAccept()) {
546 // Delete socket now, if there are no pending accepts. Otherwise,
547 // the event-handler will take care of deleting it.
548 listen_socket->Release();
549 }
550 SetLastError(rc);
551 return false;
552 }
553 }
554 return true;
555 }
556
557
558 void Socket::Close(intptr_t fd) {
559 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); 317 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
560 client_socket->Close(); 318 client_socket->Close();
561 } 319 }
562 320
563 321
564 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 322 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
565 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 323 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
566 int on; 324 int on;
567 socklen_t len = sizeof(on); 325 socklen_t len = sizeof(on);
568 int err = getsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY, 326 int err = getsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY,
569 reinterpret_cast<char*>(&on), &len); 327 reinterpret_cast<char*>(&on), &len);
570 if (err == 0) { 328 if (err == 0) {
571 *enabled = (on == 1); 329 *enabled = (on == 1);
572 } 330 }
573 return (err == 0); 331 return (err == 0);
574 } 332 }
575 333
576 334
577 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 335 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
578 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 336 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
579 int on = enabled ? 1 : 0; 337 int on = enabled ? 1 : 0;
580 return setsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY, 338 return setsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY,
581 reinterpret_cast<char*>(&on), sizeof(on)) == 0; 339 reinterpret_cast<char*>(&on), sizeof(on)) == 0;
582 } 340 }
583 341
584 342
585 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 343 bool SocketBase::GetMulticastLoop(intptr_t fd,
344 intptr_t protocol,
345 bool* enabled) {
586 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 346 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
587 uint8_t on; 347 uint8_t on;
588 socklen_t len = sizeof(on); 348 socklen_t len = sizeof(on);
589 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 349 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
590 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 350 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
591 : IPV6_MULTICAST_LOOP; 351 : IPV6_MULTICAST_LOOP;
592 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&on), 352 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&on),
593 &len) == 0) { 353 &len) == 0) {
594 *enabled = (on == 1); 354 *enabled = (on == 1);
595 return true; 355 return true;
596 } 356 }
597 return false; 357 return false;
598 } 358 }
599 359
600 360
601 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 361 bool SocketBase::SetMulticastLoop(intptr_t fd,
362 intptr_t protocol,
363 bool enabled) {
602 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 364 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
603 int on = enabled ? 1 : 0; 365 int on = enabled ? 1 : 0;
604 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 366 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
605 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 367 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
606 : IPV6_MULTICAST_LOOP; 368 : IPV6_MULTICAST_LOOP;
607 return setsockopt(handle->socket(), level, optname, 369 return setsockopt(handle->socket(), level, optname,
608 reinterpret_cast<char*>(&on), sizeof(on)) == 0; 370 reinterpret_cast<char*>(&on), sizeof(on)) == 0;
609 } 371 }
610 372
611 373
612 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 374 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
613 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 375 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
614 uint8_t v; 376 uint8_t v;
615 socklen_t len = sizeof(v); 377 socklen_t len = sizeof(v);
616 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 378 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
617 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 379 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
618 : IPV6_MULTICAST_HOPS; 380 : IPV6_MULTICAST_HOPS;
619 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&v), 381 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&v),
620 &len) == 0) { 382 &len) == 0) {
621 *value = v; 383 *value = v;
622 return true; 384 return true;
623 } 385 }
624 return false; 386 return false;
625 } 387 }
626 388
627 389
628 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 390 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
629 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 391 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
630 int v = value; 392 int v = value;
631 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 393 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
632 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 394 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
633 : IPV6_MULTICAST_HOPS; 395 : IPV6_MULTICAST_HOPS;
634 return setsockopt(handle->socket(), level, optname, 396 return setsockopt(handle->socket(), level, optname,
635 reinterpret_cast<char*>(&v), sizeof(v)) == 0; 397 reinterpret_cast<char*>(&v), sizeof(v)) == 0;
636 } 398 }
637 399
638 400
639 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 401 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
640 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 402 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
641 int on; 403 int on;
642 socklen_t len = sizeof(on); 404 socklen_t len = sizeof(on);
643 int err = getsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST, 405 int err = getsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST,
644 reinterpret_cast<char*>(&on), &len); 406 reinterpret_cast<char*>(&on), &len);
645 if (err == 0) { 407 if (err == 0) {
646 *enabled = (on == 1); 408 *enabled = (on == 1);
647 } 409 }
648 return (err == 0); 410 return (err == 0);
649 } 411 }
650 412
651 413
652 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 414 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
653 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 415 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
654 int on = enabled ? 1 : 0; 416 int on = enabled ? 1 : 0;
655 return setsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST, 417 return setsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST,
656 reinterpret_cast<char*>(&on), sizeof(on)) == 0; 418 reinterpret_cast<char*>(&on), sizeof(on)) == 0;
657 } 419 }
658 420
659 421
660 bool Socket::JoinMulticast(intptr_t fd, 422 bool SocketBase::JoinMulticast(intptr_t fd,
661 const RawAddr& addr, 423 const RawAddr& addr,
662 const RawAddr&, 424 const RawAddr&,
663 int interfaceIndex) { 425 int interfaceIndex) {
664 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 426 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
665 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 427 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
666 struct group_req mreq; 428 struct group_req mreq;
667 mreq.gr_interface = interfaceIndex; 429 mreq.gr_interface = interfaceIndex;
668 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); 430 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
669 return setsockopt(handle->socket(), proto, MCAST_JOIN_GROUP, 431 return setsockopt(handle->socket(), proto, MCAST_JOIN_GROUP,
670 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; 432 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
671 } 433 }
672 434
673 435
674 bool Socket::LeaveMulticast(intptr_t fd, 436 bool SocketBase::LeaveMulticast(intptr_t fd,
675 const RawAddr& addr, 437 const RawAddr& addr,
676 const RawAddr&, 438 const RawAddr&,
677 int interfaceIndex) { 439 int interfaceIndex) {
678 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); 440 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
679 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 441 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
680 struct group_req mreq; 442 struct group_req mreq;
681 mreq.gr_interface = interfaceIndex; 443 mreq.gr_interface = interfaceIndex;
682 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); 444 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
683 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP, 445 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP,
684 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0; 446 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
685 } 447 }
686 448
687 } // namespace bin 449 } // namespace bin
688 } // namespace dart 450 } // namespace dart
689 451
690 #endif // defined(HOST_OS_WINDOWS) 452 #endif // defined(HOST_OS_WINDOWS)
691 453
692 #endif // !defined(DART_IO_DISABLED) 454 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/socket_base_win.h ('k') | runtime/bin/socket_fuchsia.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698