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 #include "bin/utils.h" | 13 #include "bin/utils.h" |
14 | 14 |
15 | 15 |
16 namespace dart { | 16 namespace dart { |
17 namespace bin { | 17 namespace bin { |
18 | 18 |
19 SocketAddress::SocketAddress(struct sockaddr* sockaddr) { | 19 SocketAddress::SocketAddress(struct sockaddr* sockaddr) { |
20 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); | 20 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); |
21 RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr); | 21 RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr); |
22 | 22 |
23 // Clear the port before calling WSAAddressToString as WSAAddressToString | 23 // Clear the port before calling WSAAddressToString as WSAAddressToString |
24 // includes the port in the formatted string. | 24 // includes the port in the formatted string. |
25 DWORD len = INET6_ADDRSTRLEN; | 25 int err = Socket::FormatNumericAddress(raw, as_string_, INET6_ADDRSTRLEN); |
26 int err = WSAAddressToStringA(&raw->addr, | |
27 sizeof(RawAddr), | |
28 NULL, | |
29 as_string_, | |
30 &len); | |
31 | 26 |
32 if (err != 0) { | 27 if (err != 0) { |
33 as_string_[0] = 0; | 28 as_string_[0] = 0; |
34 } | 29 } |
35 memmove(reinterpret_cast<void *>(&addr_), | 30 memmove(reinterpret_cast<void *>(&addr_), |
36 sockaddr, | 31 sockaddr, |
37 SocketAddress::GetAddrLength(raw)); | 32 SocketAddress::GetAddrLength(raw)); |
38 } | 33 } |
39 | 34 |
| 35 |
| 36 bool Socket::FormatNumericAddress(RawAddr* addr, char* address, int len) { |
| 37 socklen_t salen = SocketAddress::GetAddrLength(addr); |
| 38 DWORD l = len; |
| 39 return WSAAddressToStringA(&addr->addr, |
| 40 salen, |
| 41 NULL, |
| 42 address, |
| 43 &l) != 0; |
| 44 } |
| 45 |
| 46 |
40 bool Socket::Initialize() { | 47 bool Socket::Initialize() { |
41 static bool socket_initialized = false; | 48 static bool socket_initialized = false; |
42 if (socket_initialized) return true; | 49 if (socket_initialized) return true; |
43 int err; | 50 int err; |
44 WSADATA winsock_data; | 51 WSADATA winsock_data; |
45 WORD version_requested = MAKEWORD(2, 2); | 52 WORD version_requested = MAKEWORD(2, 2); |
46 err = WSAStartup(version_requested, &winsock_data); | 53 err = WSAStartup(version_requested, &winsock_data); |
47 if (err == 0) { | 54 if (err == 0) { |
48 socket_initialized = true; | 55 socket_initialized = true; |
49 } else { | 56 } else { |
50 Log::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError()); | 57 Log::PrintErr("Unable to initialize Winsock: %d\n", WSAGetLastError()); |
51 } | 58 } |
52 return err == 0; | 59 return err == 0; |
53 } | 60 } |
54 | 61 |
55 intptr_t Socket::Available(intptr_t fd) { | 62 intptr_t Socket::Available(intptr_t fd) { |
56 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); | 63 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd); |
57 return client_socket->Available(); | 64 return client_socket->Available(); |
58 } | 65 } |
59 | 66 |
60 | 67 |
61 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { | 68 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { |
62 Handle* handle = reinterpret_cast<Handle*>(fd); | 69 Handle* handle = reinterpret_cast<Handle*>(fd); |
63 return handle->Read(buffer, num_bytes); | 70 return handle->Read(buffer, num_bytes); |
64 } | 71 } |
65 | 72 |
66 | 73 |
| 74 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes, |
| 75 RawAddr* addr) { |
| 76 Handle* handle = reinterpret_cast<Handle*>(fd); |
| 77 socklen_t addr_len = sizeof(addr->ss); |
| 78 return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len); |
| 79 } |
| 80 |
| 81 |
67 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { | 82 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { |
68 Handle* handle = reinterpret_cast<Handle*>(fd); | 83 Handle* handle = reinterpret_cast<Handle*>(fd); |
69 return handle->Write(buffer, num_bytes); | 84 return handle->Write(buffer, num_bytes); |
70 } | 85 } |
71 | 86 |
72 | 87 |
| 88 int Socket::SendTo( |
| 89 intptr_t fd, const void* buffer, intptr_t num_bytes, RawAddr addr) { |
| 90 Handle* handle = reinterpret_cast<Handle*>(fd); |
| 91 return handle->SendTo( |
| 92 buffer, num_bytes, &addr.addr, SocketAddress::GetAddrLength(&addr)); |
| 93 } |
| 94 |
| 95 |
73 intptr_t Socket::GetPort(intptr_t fd) { | 96 intptr_t Socket::GetPort(intptr_t fd) { |
74 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); | 97 ASSERT(reinterpret_cast<Handle*>(fd)->is_socket()); |
75 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); | 98 SocketHandle* socket_handle = reinterpret_cast<SocketHandle*>(fd); |
76 RawAddr raw; | 99 RawAddr raw; |
77 socklen_t size = sizeof(raw); | 100 socklen_t size = sizeof(raw); |
78 if (getsockname(socket_handle->socket(), | 101 if (getsockname(socket_handle->socket(), |
79 &raw.addr, | 102 &raw.addr, |
80 &size) == SOCKET_ERROR) { | 103 &size) == SOCKET_ERROR) { |
81 Log::PrintErr("Error getsockname: %d\n", WSAGetLastError()); | 104 Log::PrintErr("Error getsockname: %d\n", WSAGetLastError()); |
82 return 0; | 105 return 0; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 result = InetPton(AF_INET, system_address, &addr->in.sin_addr); | 298 result = InetPton(AF_INET, system_address, &addr->in.sin_addr); |
276 } else { | 299 } else { |
277 ASSERT(type == SocketAddress::TYPE_IPV6); | 300 ASSERT(type == SocketAddress::TYPE_IPV6); |
278 result = InetPton(AF_INET6, system_address, &addr->in6.sin6_addr); | 301 result = InetPton(AF_INET6, system_address, &addr->in6.sin6_addr); |
279 } | 302 } |
280 free(const_cast<wchar_t*>(system_address)); | 303 free(const_cast<wchar_t*>(system_address)); |
281 return result == 1; | 304 return result == 1; |
282 } | 305 } |
283 | 306 |
284 | 307 |
| 308 intptr_t Socket::CreateBindDatagram( |
| 309 RawAddr* addr, intptr_t port, bool reuseAddress) { |
| 310 SOCKET s = socket(addr->ss.ss_family, SOCK_DGRAM, IPPROTO_UDP); |
| 311 if (s == INVALID_SOCKET) { |
| 312 return -1; |
| 313 } |
| 314 |
| 315 int status; |
| 316 if (reuseAddress) { |
| 317 BOOL optval = true; |
| 318 status = setsockopt(s, |
| 319 SOL_SOCKET, |
| 320 SO_REUSEADDR, |
| 321 reinterpret_cast<const char*>(&optval), |
| 322 sizeof(optval)); |
| 323 if (status == SOCKET_ERROR) { |
| 324 DWORD rc = WSAGetLastError(); |
| 325 closesocket(s); |
| 326 SetLastError(rc); |
| 327 return -1; |
| 328 } |
| 329 } |
| 330 |
| 331 SocketAddress::SetAddrPort(addr, port); |
| 332 |
| 333 status = bind(s, |
| 334 &addr->addr, |
| 335 SocketAddress::GetAddrLength(addr)); |
| 336 if (status == SOCKET_ERROR) { |
| 337 DWORD rc = WSAGetLastError(); |
| 338 closesocket(s); |
| 339 SetLastError(rc); |
| 340 return -1; |
| 341 } |
| 342 |
| 343 DatagramSocket* datagram_socket = new DatagramSocket(s); |
| 344 datagram_socket->EnsureInitialized(EventHandler::delegate()); |
| 345 return reinterpret_cast<intptr_t>(datagram_socket); |
| 346 } |
| 347 |
| 348 |
285 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( | 349 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( |
286 int type, | 350 int type, |
287 OSError** os_error) { | 351 OSError** os_error) { |
288 Initialize(); | 352 Initialize(); |
289 | 353 |
290 ULONG size = 0; | 354 ULONG size = 0; |
291 DWORD flags = GAA_FLAG_SKIP_ANYCAST | | 355 DWORD flags = GAA_FLAG_SKIP_ANYCAST | |
292 GAA_FLAG_SKIP_MULTICAST | | 356 GAA_FLAG_SKIP_MULTICAST | |
293 GAA_FLAG_SKIP_DNS_SERVER; | 357 GAA_FLAG_SKIP_DNS_SERVER; |
294 // Query the size needed. | 358 // Query the size needed. |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 bool Socket::SetNonBlocking(intptr_t fd) { | 494 bool Socket::SetNonBlocking(intptr_t fd) { |
431 return SetBlockingHelper(fd, false); | 495 return SetBlockingHelper(fd, false); |
432 } | 496 } |
433 | 497 |
434 | 498 |
435 bool Socket::SetBlocking(intptr_t fd) { | 499 bool Socket::SetBlocking(intptr_t fd) { |
436 return SetBlockingHelper(fd, true); | 500 return SetBlockingHelper(fd, true); |
437 } | 501 } |
438 | 502 |
439 | 503 |
| 504 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { |
| 505 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 506 int on; |
| 507 socklen_t len = sizeof(on); |
| 508 int err = getsockopt(handle->socket(), |
| 509 IPPROTO_TCP, |
| 510 TCP_NODELAY, |
| 511 reinterpret_cast<char *>(&on), |
| 512 &len); |
| 513 if (err == 0) { |
| 514 *enabled = on == 1; |
| 515 } |
| 516 return err == 0; |
| 517 } |
| 518 |
| 519 |
440 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { | 520 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { |
441 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); | 521 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
442 int on = enabled ? 1 : 0; | 522 int on = enabled ? 1 : 0; |
443 return setsockopt(fd, | 523 return setsockopt(handle->socket(), |
444 IPPROTO_TCP, | 524 IPPROTO_TCP, |
445 TCP_NODELAY, | 525 TCP_NODELAY, |
446 reinterpret_cast<char *>(&on), | 526 reinterpret_cast<char *>(&on), |
447 sizeof(on)) == 0; | 527 sizeof(on)) == 0; |
448 } | 528 } |
449 | 529 |
| 530 |
| 531 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { |
| 532 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 533 uint8_t on; |
| 534 socklen_t len = sizeof(on); |
| 535 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 536 int optname = protocol == SocketAddress::TYPE_IPV4 |
| 537 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; |
| 538 if (getsockopt(handle->socket(), |
| 539 level, |
| 540 optname, |
| 541 reinterpret_cast<char *>(&on), |
| 542 &len) == 0) { |
| 543 *enabled = (on == 1); |
| 544 return true; |
| 545 } |
| 546 return false; |
| 547 } |
| 548 |
| 549 |
| 550 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { |
| 551 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 552 int on = enabled ? 1 : 0; |
| 553 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 554 int optname = protocol == SocketAddress::TYPE_IPV4 |
| 555 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; |
| 556 return setsockopt(handle->socket(), |
| 557 level, |
| 558 optname, |
| 559 reinterpret_cast<char *>(&on), |
| 560 sizeof(on)) == 0; |
| 561 return false; |
| 562 } |
| 563 |
| 564 |
| 565 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { |
| 566 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 567 uint8_t v; |
| 568 socklen_t len = sizeof(v); |
| 569 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 570 int optname = protocol == SocketAddress::TYPE_IPV4 |
| 571 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; |
| 572 if (getsockopt(handle->socket(), |
| 573 level, |
| 574 optname, |
| 575 reinterpret_cast<char *>(&v), |
| 576 &len) == 0) { |
| 577 *value = v; |
| 578 return true; |
| 579 } |
| 580 return false; |
| 581 } |
| 582 |
| 583 |
| 584 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { |
| 585 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 586 int v = value; |
| 587 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 588 int optname = protocol == SocketAddress::TYPE_IPV4 |
| 589 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; |
| 590 return setsockopt(handle->socket(), |
| 591 level, |
| 592 optname, |
| 593 reinterpret_cast<char *>(&v), |
| 594 sizeof(v)) == 0; |
| 595 } |
| 596 |
| 597 |
| 598 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { |
| 599 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 600 int on; |
| 601 socklen_t len = sizeof(on); |
| 602 int err = getsockopt(handle->socket(), |
| 603 SOL_SOCKET, |
| 604 SO_BROADCAST, |
| 605 reinterpret_cast<char *>(&on), |
| 606 &len); |
| 607 if (err == 0) { |
| 608 *enabled = on == 1; |
| 609 } |
| 610 return err == 0; |
| 611 } |
| 612 |
| 613 |
| 614 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { |
| 615 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 616 int on = enabled ? 1 : 0; |
| 617 return setsockopt(handle->socket(), |
| 618 SOL_SOCKET, |
| 619 SO_BROADCAST, |
| 620 reinterpret_cast<char *>(&on), |
| 621 sizeof(on)) == 0; |
| 622 } |
| 623 |
| 624 |
| 625 bool Socket::JoinMulticast( |
| 626 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { |
| 627 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 628 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 629 struct group_req mreq; |
| 630 mreq.gr_interface = interfaceIndex; |
| 631 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); |
| 632 return setsockopt(handle->socket(), |
| 633 proto, |
| 634 MCAST_JOIN_GROUP, |
| 635 reinterpret_cast<char *>(&mreq), |
| 636 sizeof(mreq)) == 0; |
| 637 } |
| 638 |
| 639 |
| 640 bool Socket::LeaveMulticast( |
| 641 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { |
| 642 SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd); |
| 643 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 644 struct group_req mreq; |
| 645 mreq.gr_interface = interfaceIndex; |
| 646 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); |
| 647 return setsockopt(handle->socket(), |
| 648 proto, |
| 649 MCAST_LEAVE_GROUP, |
| 650 reinterpret_cast<char *>(&mreq), |
| 651 sizeof(mreq)) == 0; |
| 652 } |
| 653 |
450 } // namespace bin | 654 } // namespace bin |
451 } // namespace dart | 655 } // namespace dart |
452 | 656 |
453 #endif // defined(TARGET_OS_WINDOWS) | 657 #endif // defined(TARGET_OS_WINDOWS) |
OLD | NEW |