Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
socket_base_macos.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(DART_HOST_OS_MACOS)
7
8#include "bin/socket_base.h"
9
10#include <errno.h> // NOLINT
11#include <ifaddrs.h> // NOLINT
12#include <net/if.h> // NOLINT
13#include <netinet/tcp.h> // NOLINT
14#include <stdio.h> // NOLINT
15#include <stdlib.h> // NOLINT
16#include <string.h> // NOLINT
17#include <sys/stat.h> // NOLINT
18#include <unistd.h> // NOLINT
19
20#include "bin/fdutils.h"
21#include "bin/file.h"
24
25namespace dart {
26namespace bin {
27
28void SocketBase::GetError(intptr_t fd, OSError* os_error) {
29 int len = sizeof(errno);
30 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno,
31 reinterpret_cast<socklen_t*>(&len));
32 os_error->SetCodeAndMessage(OSError::kSystem, errno);
33}
34
35int SocketBase::GetType(intptr_t fd) {
36 struct stat buf;
37 int result = fstat(fd, &buf);
38 if (result == -1) {
39 return -1;
40 }
41 if (S_ISCHR(buf.st_mode)) {
42 return File::kTerminal;
43 }
44 if (S_ISFIFO(buf.st_mode)) {
45 return File::kPipe;
46 }
47 if (S_ISREG(buf.st_mode)) {
48 return File::kFile;
49 }
50 return File::kOther;
51}
52
53AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
54 int type,
55 OSError** os_error) {
56 // Perform a name lookup for a host name.
57 struct addrinfo hints;
58 memset(&hints, 0, sizeof(hints));
59 hints.ai_family = SocketAddress::FromType(type);
60 hints.ai_socktype = SOCK_STREAM;
61 hints.ai_flags = 0;
62 hints.ai_protocol = IPPROTO_TCP;
63 struct addrinfo* info = nullptr;
64 int status = getaddrinfo(host, nullptr, &hints, &info);
65 if (status != 0) {
66 ASSERT(*os_error == nullptr);
67 *os_error =
68 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
69 return nullptr;
70 }
71 intptr_t count = 0;
72 for (struct addrinfo* c = info; c != nullptr; c = c->ai_next) {
73 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
74 count++;
75 }
76 }
77 intptr_t i = 0;
78 AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count);
79 for (struct addrinfo* c = info; c != nullptr; c = c->ai_next) {
80 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
81 addresses->SetAt(i, new SocketAddress(c->ai_addr));
82 i++;
83 }
84 }
85 freeaddrinfo(info);
86 return addresses;
87}
88
89bool SocketBase::SetMulticastLoop(intptr_t fd,
90 intptr_t protocol,
91 bool enabled) {
92 u_int on = enabled ? 1 : 0;
93 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
94 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
95 : IPV6_MULTICAST_LOOP;
96 return NO_RETRY_EXPECTED(setsockopt(
97 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) ==
98 0;
99}
100
101bool SocketBase::GetOption(intptr_t fd,
102 int level,
103 int option,
104 char* data,
105 unsigned int* length) {
106 return NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, length)) == 0;
107}
108
109static bool JoinOrLeaveMulticast(intptr_t fd,
110 const RawAddr& addr,
111 const RawAddr& interface,
112 int interfaceIndex,
113 bool join) {
114 if (addr.addr.sa_family == AF_INET) {
115 ASSERT(interface.addr.sa_family == AF_INET);
116 struct ip_mreq mreq;
117 memmove(&mreq.imr_multiaddr, &addr.in.sin_addr,
119 memmove(&mreq.imr_interface, &interface.in.sin_addr,
121 if (join) {
122 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
123 &mreq, sizeof(mreq))) == 0;
124 } else {
125 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
126 &mreq, sizeof(mreq))) == 0;
127 }
128 } else {
129 ASSERT(addr.addr.sa_family == AF_INET6);
130 struct ipv6_mreq mreq;
131 memmove(&mreq.ipv6mr_multiaddr, &addr.in6.sin6_addr,
133 mreq.ipv6mr_interface = interfaceIndex;
134 if (join) {
135 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
136 &mreq, sizeof(mreq))) == 0;
137 } else {
138 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
139 &mreq, sizeof(mreq))) == 0;
140 }
141 }
142}
143
144bool SocketBase::JoinMulticast(intptr_t fd,
145 const RawAddr& addr,
146 const RawAddr& interface,
147 int interfaceIndex) {
148 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true);
149}
150
151bool SocketBase::LeaveMulticast(intptr_t fd,
152 const RawAddr& addr,
153 const RawAddr& interface,
154 int interfaceIndex) {
155 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false);
156}
157
158} // namespace bin
159} // namespace dart
160
161#endif // defined(DART_HOST_OS_MACOS)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
int count
static int16_t FromType(int type)
static intptr_t GetInAddrLength(const RawAddr &addr)
static bool LeaveMulticast(intptr_t fd, const RawAddr &addr, const RawAddr &interface, int interfaceIndex)
static int GetType(intptr_t fd)
static AddressList< SocketAddress > * LookupAddress(const char *host, int type, OSError **os_error)
static void GetError(intptr_t fd, OSError *os_error)
static bool SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled)
static bool GetOption(intptr_t fd, int level, int option, char *data, unsigned int *length)
static bool JoinMulticast(intptr_t fd, const RawAddr &addr, const RawAddr &interface, int interfaceIndex)
#define ASSERT(E)
GAsyncResult * result
size_t length
static int8_t data[kExtLength]
#define NO_RETRY_EXPECTED(expression)