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

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

Issue 2791163004: Reverting until bots clear up. (Closed)
Patch Set: 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #if !defined(DART_IO_DISABLED)
6
7 #include "platform/globals.h"
8 #if defined(HOST_OS_WINDOWS)
9
10 #include "bin/socket_base.h"
11
12 #include "bin/builtin.h"
13 #include "bin/eventhandler.h"
14 #include "bin/file.h"
15 #include "bin/lockers.h"
16 #include "bin/log.h"
17 #include "bin/socket_base_win.h"
18 #include "bin/thread.h"
19 #include "bin/utils.h"
20 #include "bin/utils_win.h"
21
22 namespace dart {
23 namespace bin {
24
25 SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
26 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
27 RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
28
29 // Clear the port before calling WSAAddressToString as WSAAddressToString
30 // includes the port in the formatted string.
31 int err =
32 SocketBase::FormatNumericAddress(*raw, as_string_, INET6_ADDRSTRLEN);
33
34 if (err != 0) {
35 as_string_[0] = 0;
36 }
37 memmove(reinterpret_cast<void*>(&addr_), sockaddr,
38 SocketAddress::GetAddrLength(*raw));
39 }
40
41
42 bool SocketBase::FormatNumericAddress(const RawAddr& addr,
43 char* address,
44 int len) {
45 socklen_t salen = SocketAddress::GetAddrLength(addr);
46 DWORD l = len;
47 RawAddr& raw = const_cast<RawAddr&>(addr);
48 return WSAAddressToStringA(&raw.addr, salen, NULL, address, &l) != 0;
49 }
50
51
52 intptr_t SocketBase::Available(intptr_t fd) {
53 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
54 return client_socket->Available();
55 }
56
57
58 intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
59 Handle* handle = reinterpret_cast<Handle*>(fd);
60 return handle->Read(buffer, num_bytes);
61 }
62
63
64 intptr_t SocketBase::RecvFrom(intptr_t fd,
65 void* buffer,
66 intptr_t num_bytes,
67 RawAddr* addr) {
68 Handle* handle = reinterpret_cast<Handle*>(fd);
69 socklen_t addr_len = sizeof(addr->ss);
70 return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len);
71 }
72
73
74 intptr_t SocketBase::Write(intptr_t fd,
75 const void* buffer,
76 intptr_t num_bytes) {
77 Handle* handle = reinterpret_cast<Handle*>(fd);
78 return handle->Write(buffer, num_bytes);
79 }
80
81
82 intptr_t SocketBase::SendTo(intptr_t fd,
83 const void* buffer,
84 intptr_t num_bytes,
85 const RawAddr& addr) {
86 Handle* handle = reinterpret_cast<Handle*>(fd);
87 RawAddr& raw = const_cast<RawAddr&>(addr);
88 return handle->SendTo(buffer, num_bytes, &raw.addr,
89 SocketAddress::GetAddrLength(addr));
90 }
91
92
93 intptr_t SocketBase::GetPort(intptr_t fd) {
94 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
95 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
96 RawAddr raw;
97 socklen_t size = sizeof(raw);
98 if (getsockname(socket_handle->socket(), &raw.addr, &size) == SOCKET_ERROR) {
99 return 0;
100 }
101 return SocketAddress::GetAddrPort(raw);
102 }
103
104
105 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
106 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket());
107 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd);
108 RawAddr raw;
109 socklen_t size = sizeof(raw);
110 if (getpeername(socket_handle->socket(), &raw.addr, &size)) {
111 return NULL;
112 }
113 *port = SocketAddress::GetAddrPort(raw);
114 // Clear the port before calling WSAAddressToString as WSAAddressToString
115 // includes the port in the formatted string.
116 SocketAddress::SetAddrPort(&raw, 0);
117 return new SocketAddress(&raw.addr);
118 }
119
120
121 bool SocketBase::IsBindError(intptr_t error_number) {
122 return error_number == WSAEADDRINUSE || error_number == WSAEADDRNOTAVAIL ||
123 error_number == WSAEINVAL;
124 }
125
126
127 void SocketBase::GetError(intptr_t fd, OSError* os_error) {
128 Handle* handle = reinterpret_cast<Handle*>(fd);
129 os_error->SetCodeAndMessage(OSError::kSystem, handle->last_error());
130 }
131
132
133 int SocketBase::GetType(intptr_t fd) {
134 Handle* handle = reinterpret_cast<Handle*>(fd);
135 switch (GetFileType(handle->handle())) {
136 case FILE_TYPE_CHAR:
137 return File::kTerminal;
138 case FILE_TYPE_PIPE:
139 return File::kPipe;
140 case FILE_TYPE_DISK:
141 return File::kFile;
142 default:
143 return GetLastError == NO_ERROR ? File::kOther : -1;
144 }
145 }
146
147
148 intptr_t SocketBase::GetStdioHandle(intptr_t num) {
149 if (num != 0) {
150 return -1;
151 }
152 HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
153 if (handle == INVALID_HANDLE_VALUE) {
154 return -1;
155 }
156 StdHandle* std_handle = new StdHandle(handle);
157 std_handle->MarkDoesNotSupportOverlappedIO();
158 std_handle->EnsureInitialized(EventHandler::delegate());
159 return reinterpret_cast<intptr_t>(std_handle);
160 }
161
162
163 intptr_t ServerSocket::Accept(intptr_t fd) {
164 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(fd);
165 ClientSocket* client_socket = listen_socket->Accept();
166 if (client_socket != NULL) {
167 return reinterpret_cast<intptr_t>(client_socket);
168 } else {
169 return -1;
170 }
171 }
172
173
174 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
175 int type,
176 OSError** os_error) {
177 Initialize();
178
179 // Perform a name lookup for a host name.
180 struct addrinfo hints;
181 memset(&hints, 0, sizeof(hints));
182 hints.ai_family = SocketAddress::FromType(type);
183 hints.ai_socktype = SOCK_STREAM;
184 hints.ai_flags = AI_ADDRCONFIG;
185 hints.ai_protocol = IPPROTO_TCP;
186 struct addrinfo* info = NULL;
187 int status = getaddrinfo(host, 0, &hints, &info);
188 if (status != 0) {
189 // We failed, try without AI_ADDRCONFIG. This can happen when looking up
190 // e.g. '::1', when there are no global IPv6 addresses.
191 hints.ai_flags = 0;
192 status = getaddrinfo(host, 0, &hints, &info);
193 }
194 if (status != 0) {
195 ASSERT(*os_error == NULL);
196 DWORD error_code = WSAGetLastError();
197 SetLastError(error_code);
198 *os_error = new OSError();
199 return NULL;
200 }
201 intptr_t count = 0;
202 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
203 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
204 count++;
205 }
206 }
207 AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
208 intptr_t i = 0;
209 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
210 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
211 addresses->SetAt(i, new SocketAddress(c->ai_addr));
212 i++;
213 }
214 }
215 freeaddrinfo(info);
216 return addresses;
217 }
218
219
220 bool SocketBase::ReverseLookup(const RawAddr& addr,
221 char* host,
222 intptr_t host_len,
223 OSError** os_error) {
224 ASSERT(host_len >= NI_MAXHOST);
225 int status = getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
226 host_len, NULL, 0, NI_NAMEREQD);
227 if (status != 0) {
228 ASSERT(*os_error == NULL);
229 DWORD error_code = WSAGetLastError();
230 SetLastError(error_code);
231 *os_error = new OSError();
232 return false;
233 }
234 return true;
235 }
236
237
238 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
239 int result;
240 Utf8ToWideScope system_address(address);
241 if (type == SocketAddress::TYPE_IPV4) {
242 result = InetPton(AF_INET, system_address.wide(), &addr->in.sin_addr);
243 } else {
244 ASSERT(type == SocketAddress::TYPE_IPV6);
245 result = InetPton(AF_INET6, system_address.wide(), &addr->in6.sin6_addr);
246 }
247 return result == 1;
248 }
249
250
251 bool SocketBase::ListInterfacesSupported() {
252 return true;
253 }
254
255
256 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
257 int type,
258 OSError** os_error) {
259 Initialize();
260
261 ULONG size = 0;
262 DWORD flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
263 GAA_FLAG_SKIP_DNS_SERVER;
264 // Query the size needed.
265 int status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, NULL,
266 NULL, &size);
267 IP_ADAPTER_ADDRESSES* addrs = NULL;
268 if (status == ERROR_BUFFER_OVERFLOW) {
269 addrs = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(malloc(size));
270 // Get the addresses now we have the right buffer.
271 status = GetAdaptersAddresses(SocketAddress::FromType(type), flags, NULL,
272 addrs, &size);
273 }
274 if (status != NO_ERROR) {
275 ASSERT(*os_error == NULL);
276 DWORD error_code = WSAGetLastError();
277 SetLastError(error_code);
278 *os_error = new OSError();
279 return NULL;
280 }
281 intptr_t count = 0;
282 for (IP_ADAPTER_ADDRESSES* a = addrs; a != NULL; a = a->Next) {
283 for (IP_ADAPTER_UNICAST_ADDRESS* u = a->FirstUnicastAddress; u != NULL;
284 u = u->Next) {
285 count++;
286 }
287 }
288 AddressList<InterfaceSocketAddress>* addresses =
289 new AddressList<InterfaceSocketAddress>(count);
290 intptr_t i = 0;
291 for (IP_ADAPTER_ADDRESSES* a = addrs; a != NULL; a = a->Next) {
292 for (IP_ADAPTER_UNICAST_ADDRESS* u = a->FirstUnicastAddress; u != NULL;
293 u = u->Next) {
294 addresses->SetAt(
295 i, new InterfaceSocketAddress(
296 u->Address.lpSockaddr,
297 StringUtilsWin::WideToUtf8(a->FriendlyName), a->Ipv6IfIndex));
298 i++;
299 }
300 }
301 free(addrs);
302 return addresses;
303 }
304
305
306 void SocketBase::Close(intptr_t fd) {
307 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
308 client_socket->Close();
309 }
310
311
312 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
313 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
314 int on;
315 socklen_t len = sizeof(on);
316 int err = getsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY,
317 reinterpret_cast<char*>(&on), &len);
318 if (err == 0) {
319 *enabled = (on == 1);
320 }
321 return (err == 0);
322 }
323
324
325 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
326 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
327 int on = enabled ? 1 : 0;
328 return setsockopt(handle->socket(), IPPROTO_TCP, TCP_NODELAY,
329 reinterpret_cast<char*>(&on), sizeof(on)) == 0;
330 }
331
332
333 bool SocketBase::GetMulticastLoop(intptr_t fd,
334 intptr_t protocol,
335 bool* enabled) {
336 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
337 uint8_t on;
338 socklen_t len = sizeof(on);
339 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
340 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
341 : IPV6_MULTICAST_LOOP;
342 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&on),
343 &len) == 0) {
344 *enabled = (on == 1);
345 return true;
346 }
347 return false;
348 }
349
350
351 bool SocketBase::SetMulticastLoop(intptr_t fd,
352 intptr_t protocol,
353 bool enabled) {
354 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
355 int on = enabled ? 1 : 0;
356 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
357 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
358 : IPV6_MULTICAST_LOOP;
359 return setsockopt(handle->socket(), level, optname,
360 reinterpret_cast<char*>(&on), sizeof(on)) == 0;
361 }
362
363
364 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
365 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
366 uint8_t v;
367 socklen_t len = sizeof(v);
368 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
369 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
370 : IPV6_MULTICAST_HOPS;
371 if (getsockopt(handle->socket(), level, optname, reinterpret_cast<char*>(&v),
372 &len) == 0) {
373 *value = v;
374 return true;
375 }
376 return false;
377 }
378
379
380 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
381 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
382 int v = value;
383 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
384 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
385 : IPV6_MULTICAST_HOPS;
386 return setsockopt(handle->socket(), level, optname,
387 reinterpret_cast<char*>(&v), sizeof(v)) == 0;
388 }
389
390
391 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
392 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
393 int on;
394 socklen_t len = sizeof(on);
395 int err = getsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST,
396 reinterpret_cast<char*>(&on), &len);
397 if (err == 0) {
398 *enabled = (on == 1);
399 }
400 return (err == 0);
401 }
402
403
404 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
405 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
406 int on = enabled ? 1 : 0;
407 return setsockopt(handle->socket(), SOL_SOCKET, SO_BROADCAST,
408 reinterpret_cast<char*>(&on), sizeof(on)) == 0;
409 }
410
411
412 bool SocketBase::JoinMulticast(intptr_t fd,
413 const RawAddr& addr,
414 const RawAddr&,
415 int interfaceIndex) {
416 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
417 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
418 struct group_req mreq;
419 mreq.gr_interface = interfaceIndex;
420 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
421 return setsockopt(handle->socket(), proto, MCAST_JOIN_GROUP,
422 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
423 }
424
425
426 bool SocketBase::LeaveMulticast(intptr_t fd,
427 const RawAddr& addr,
428 const RawAddr&,
429 int interfaceIndex) {
430 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
431 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
432 struct group_req mreq;
433 mreq.gr_interface = interfaceIndex;
434 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
435 return setsockopt(handle->socket(), proto, MCAST_LEAVE_GROUP,
436 reinterpret_cast<char*>(&mreq), sizeof(mreq)) == 0;
437 }
438
439 } // namespace bin
440 } // namespace dart
441
442 #endif // defined(HOST_OS_WINDOWS)
443
444 #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