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 #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_MACOS) | 8 #if defined(HOST_OS_MACOS) |
9 | 9 |
10 #include "bin/socket_base.h" | 10 #include "bin/socket_base.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 SocketAddress::SocketAddress(struct sockaddr* sa) { | 30 SocketAddress::SocketAddress(struct sockaddr* sa) { |
31 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); | 31 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); |
32 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), | 32 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), |
33 as_string_, INET6_ADDRSTRLEN)) { | 33 as_string_, INET6_ADDRSTRLEN)) { |
34 as_string_[0] = 0; | 34 as_string_[0] = 0; |
35 } | 35 } |
36 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); | 36 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); |
37 memmove(reinterpret_cast<void*>(&addr_), sa, salen); | 37 memmove(reinterpret_cast<void*>(&addr_), sa, salen); |
38 } | 38 } |
39 | 39 |
40 | |
41 bool SocketBase::Initialize() { | 40 bool SocketBase::Initialize() { |
42 // Nothing to do on Mac OS. | 41 // Nothing to do on Mac OS. |
43 return true; | 42 return true; |
44 } | 43 } |
45 | 44 |
46 | |
47 bool SocketBase::FormatNumericAddress(const RawAddr& addr, | 45 bool SocketBase::FormatNumericAddress(const RawAddr& addr, |
48 char* address, | 46 char* address, |
49 int len) { | 47 int len) { |
50 socklen_t salen = SocketAddress::GetAddrLength(addr); | 48 socklen_t salen = SocketAddress::GetAddrLength(addr); |
51 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, | 49 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, |
52 0, NI_NUMERICHOST)) == 0); | 50 0, NI_NUMERICHOST)) == 0); |
53 } | 51 } |
54 | 52 |
55 | |
56 bool SocketBase::IsBindError(intptr_t error_number) { | 53 bool SocketBase::IsBindError(intptr_t error_number) { |
57 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || | 54 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || |
58 error_number == EINVAL; | 55 error_number == EINVAL; |
59 } | 56 } |
60 | 57 |
61 | |
62 intptr_t SocketBase::Available(intptr_t fd) { | 58 intptr_t SocketBase::Available(intptr_t fd) { |
63 return FDUtils::AvailableBytes(fd); | 59 return FDUtils::AvailableBytes(fd); |
64 } | 60 } |
65 | 61 |
66 | |
67 intptr_t SocketBase::Read(intptr_t fd, | 62 intptr_t SocketBase::Read(intptr_t fd, |
68 void* buffer, | 63 void* buffer, |
69 intptr_t num_bytes, | 64 intptr_t num_bytes, |
70 SocketOpKind sync) { | 65 SocketOpKind sync) { |
71 ASSERT(fd >= 0); | 66 ASSERT(fd >= 0); |
72 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); | 67 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); |
73 ASSERT(EAGAIN == EWOULDBLOCK); | 68 ASSERT(EAGAIN == EWOULDBLOCK); |
74 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { | 69 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { |
75 // If the read would block we need to retry and therefore return 0 | 70 // If the read would block we need to retry and therefore return 0 |
76 // as the number of bytes written. | 71 // as the number of bytes written. |
77 read_bytes = 0; | 72 read_bytes = 0; |
78 } | 73 } |
79 return read_bytes; | 74 return read_bytes; |
80 } | 75 } |
81 | 76 |
82 | |
83 intptr_t SocketBase::RecvFrom(intptr_t fd, | 77 intptr_t SocketBase::RecvFrom(intptr_t fd, |
84 void* buffer, | 78 void* buffer, |
85 intptr_t num_bytes, | 79 intptr_t num_bytes, |
86 RawAddr* addr, | 80 RawAddr* addr, |
87 SocketOpKind sync) { | 81 SocketOpKind sync) { |
88 ASSERT(fd >= 0); | 82 ASSERT(fd >= 0); |
89 socklen_t addr_len = sizeof(addr->ss); | 83 socklen_t addr_len = sizeof(addr->ss); |
90 ssize_t read_bytes = TEMP_FAILURE_RETRY( | 84 ssize_t read_bytes = TEMP_FAILURE_RETRY( |
91 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); | 85 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); |
92 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { | 86 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { |
93 // If the read would block we need to retry and therefore return 0 | 87 // If the read would block we need to retry and therefore return 0 |
94 // as the number of bytes written. | 88 // as the number of bytes written. |
95 read_bytes = 0; | 89 read_bytes = 0; |
96 } | 90 } |
97 return read_bytes; | 91 return read_bytes; |
98 } | 92 } |
99 | 93 |
100 | |
101 intptr_t SocketBase::Write(intptr_t fd, | 94 intptr_t SocketBase::Write(intptr_t fd, |
102 const void* buffer, | 95 const void* buffer, |
103 intptr_t num_bytes, | 96 intptr_t num_bytes, |
104 SocketOpKind sync) { | 97 SocketOpKind sync) { |
105 ASSERT(fd >= 0); | 98 ASSERT(fd >= 0); |
106 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); | 99 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); |
107 ASSERT(EAGAIN == EWOULDBLOCK); | 100 ASSERT(EAGAIN == EWOULDBLOCK); |
108 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { | 101 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { |
109 // If the would block we need to retry and therefore return 0 as | 102 // If the would block we need to retry and therefore return 0 as |
110 // the number of bytes written. | 103 // the number of bytes written. |
111 written_bytes = 0; | 104 written_bytes = 0; |
112 } | 105 } |
113 return written_bytes; | 106 return written_bytes; |
114 } | 107 } |
115 | 108 |
116 | |
117 intptr_t SocketBase::SendTo(intptr_t fd, | 109 intptr_t SocketBase::SendTo(intptr_t fd, |
118 const void* buffer, | 110 const void* buffer, |
119 intptr_t num_bytes, | 111 intptr_t num_bytes, |
120 const RawAddr& addr, | 112 const RawAddr& addr, |
121 SocketOpKind sync) { | 113 SocketOpKind sync) { |
122 ASSERT(fd >= 0); | 114 ASSERT(fd >= 0); |
123 ssize_t written_bytes = | 115 ssize_t written_bytes = |
124 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, | 116 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, |
125 SocketAddress::GetAddrLength(addr))); | 117 SocketAddress::GetAddrLength(addr))); |
126 ASSERT(EAGAIN == EWOULDBLOCK); | 118 ASSERT(EAGAIN == EWOULDBLOCK); |
127 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { | 119 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { |
128 // If the would block we need to retry and therefore return 0 as | 120 // If the would block we need to retry and therefore return 0 as |
129 // the number of bytes written. | 121 // the number of bytes written. |
130 written_bytes = 0; | 122 written_bytes = 0; |
131 } | 123 } |
132 return written_bytes; | 124 return written_bytes; |
133 } | 125 } |
134 | 126 |
135 | |
136 intptr_t SocketBase::GetPort(intptr_t fd) { | 127 intptr_t SocketBase::GetPort(intptr_t fd) { |
137 ASSERT(fd >= 0); | 128 ASSERT(fd >= 0); |
138 RawAddr raw; | 129 RawAddr raw; |
139 socklen_t size = sizeof(raw); | 130 socklen_t size = sizeof(raw); |
140 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { | 131 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { |
141 return 0; | 132 return 0; |
142 } | 133 } |
143 return SocketAddress::GetAddrPort(raw); | 134 return SocketAddress::GetAddrPort(raw); |
144 } | 135 } |
145 | 136 |
146 | |
147 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { | 137 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { |
148 ASSERT(fd >= 0); | 138 ASSERT(fd >= 0); |
149 RawAddr raw; | 139 RawAddr raw; |
150 socklen_t size = sizeof(raw); | 140 socklen_t size = sizeof(raw); |
151 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { | 141 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { |
152 return NULL; | 142 return NULL; |
153 } | 143 } |
154 *port = SocketAddress::GetAddrPort(raw); | 144 *port = SocketAddress::GetAddrPort(raw); |
155 return new SocketAddress(&raw.addr); | 145 return new SocketAddress(&raw.addr); |
156 } | 146 } |
157 | 147 |
158 | |
159 void SocketBase::GetError(intptr_t fd, OSError* os_error) { | 148 void SocketBase::GetError(intptr_t fd, OSError* os_error) { |
160 int len = sizeof(errno); | 149 int len = sizeof(errno); |
161 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, | 150 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, |
162 reinterpret_cast<socklen_t*>(&len)); | 151 reinterpret_cast<socklen_t*>(&len)); |
163 os_error->SetCodeAndMessage(OSError::kSystem, errno); | 152 os_error->SetCodeAndMessage(OSError::kSystem, errno); |
164 } | 153 } |
165 | 154 |
166 | |
167 int SocketBase::GetType(intptr_t fd) { | 155 int SocketBase::GetType(intptr_t fd) { |
168 struct stat buf; | 156 struct stat buf; |
169 int result = fstat(fd, &buf); | 157 int result = fstat(fd, &buf); |
170 if (result == -1) { | 158 if (result == -1) { |
171 return -1; | 159 return -1; |
172 } | 160 } |
173 if (S_ISCHR(buf.st_mode)) { | 161 if (S_ISCHR(buf.st_mode)) { |
174 return File::kTerminal; | 162 return File::kTerminal; |
175 } | 163 } |
176 if (S_ISFIFO(buf.st_mode)) { | 164 if (S_ISFIFO(buf.st_mode)) { |
177 return File::kPipe; | 165 return File::kPipe; |
178 } | 166 } |
179 if (S_ISREG(buf.st_mode)) { | 167 if (S_ISREG(buf.st_mode)) { |
180 return File::kFile; | 168 return File::kFile; |
181 } | 169 } |
182 return File::kOther; | 170 return File::kOther; |
183 } | 171 } |
184 | 172 |
185 | |
186 intptr_t SocketBase::GetStdioHandle(intptr_t num) { | 173 intptr_t SocketBase::GetStdioHandle(intptr_t num) { |
187 return num; | 174 return num; |
188 } | 175 } |
189 | 176 |
190 | |
191 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, | 177 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, |
192 int type, | 178 int type, |
193 OSError** os_error) { | 179 OSError** os_error) { |
194 // Perform a name lookup for a host name. | 180 // Perform a name lookup for a host name. |
195 struct addrinfo hints; | 181 struct addrinfo hints; |
196 memset(&hints, 0, sizeof(hints)); | 182 memset(&hints, 0, sizeof(hints)); |
197 hints.ai_family = SocketAddress::FromType(type); | 183 hints.ai_family = SocketAddress::FromType(type); |
198 hints.ai_socktype = SOCK_STREAM; | 184 hints.ai_socktype = SOCK_STREAM; |
199 hints.ai_flags = 0; | 185 hints.ai_flags = 0; |
200 hints.ai_protocol = IPPROTO_TCP; | 186 hints.ai_protocol = IPPROTO_TCP; |
(...skipping 16 matching lines...) Expand all Loading... |
217 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { | 203 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { |
218 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { | 204 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { |
219 addresses->SetAt(i, new SocketAddress(c->ai_addr)); | 205 addresses->SetAt(i, new SocketAddress(c->ai_addr)); |
220 i++; | 206 i++; |
221 } | 207 } |
222 } | 208 } |
223 freeaddrinfo(info); | 209 freeaddrinfo(info); |
224 return addresses; | 210 return addresses; |
225 } | 211 } |
226 | 212 |
227 | |
228 bool SocketBase::ReverseLookup(const RawAddr& addr, | 213 bool SocketBase::ReverseLookup(const RawAddr& addr, |
229 char* host, | 214 char* host, |
230 intptr_t host_len, | 215 intptr_t host_len, |
231 OSError** os_error) { | 216 OSError** os_error) { |
232 ASSERT(host_len >= NI_MAXHOST); | 217 ASSERT(host_len >= NI_MAXHOST); |
233 int status = NO_RETRY_EXPECTED( | 218 int status = NO_RETRY_EXPECTED( |
234 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, | 219 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, |
235 host_len, NULL, 0, NI_NAMEREQD)); | 220 host_len, NULL, 0, NI_NAMEREQD)); |
236 if (status != 0) { | 221 if (status != 0) { |
237 ASSERT(*os_error == NULL); | 222 ASSERT(*os_error == NULL); |
238 *os_error = | 223 *os_error = |
239 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); | 224 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); |
240 return false; | 225 return false; |
241 } | 226 } |
242 return true; | 227 return true; |
243 } | 228 } |
244 | 229 |
245 | |
246 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { | 230 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { |
247 int result; | 231 int result; |
248 if (type == SocketAddress::TYPE_IPV4) { | 232 if (type == SocketAddress::TYPE_IPV4) { |
249 result = inet_pton(AF_INET, address, &addr->in.sin_addr); | 233 result = inet_pton(AF_INET, address, &addr->in.sin_addr); |
250 } else { | 234 } else { |
251 ASSERT(type == SocketAddress::TYPE_IPV6); | 235 ASSERT(type == SocketAddress::TYPE_IPV6); |
252 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); | 236 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); |
253 } | 237 } |
254 return (result == 1); | 238 return (result == 1); |
255 } | 239 } |
256 | 240 |
257 | |
258 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { | 241 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { |
259 if (ifa->ifa_addr == NULL) { | 242 if (ifa->ifa_addr == NULL) { |
260 // OpenVPN's virtual device tun0. | 243 // OpenVPN's virtual device tun0. |
261 return false; | 244 return false; |
262 } | 245 } |
263 int family = ifa->ifa_addr->sa_family; | 246 int family = ifa->ifa_addr->sa_family; |
264 return ((lookup_family == family) || | 247 return ((lookup_family == family) || |
265 ((lookup_family == AF_UNSPEC) && | 248 ((lookup_family == AF_UNSPEC) && |
266 ((family == AF_INET) || (family == AF_INET6)))); | 249 ((family == AF_INET) || (family == AF_INET6)))); |
267 } | 250 } |
268 | 251 |
269 | |
270 bool SocketBase::ListInterfacesSupported() { | 252 bool SocketBase::ListInterfacesSupported() { |
271 return true; | 253 return true; |
272 } | 254 } |
273 | 255 |
274 | |
275 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( | 256 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( |
276 int type, | 257 int type, |
277 OSError** os_error) { | 258 OSError** os_error) { |
278 struct ifaddrs* ifaddr; | 259 struct ifaddrs* ifaddr; |
279 | 260 |
280 int status = getifaddrs(&ifaddr); | 261 int status = getifaddrs(&ifaddr); |
281 if (status != 0) { | 262 if (status != 0) { |
282 ASSERT(*os_error == NULL); | 263 ASSERT(*os_error == NULL); |
283 *os_error = | 264 *os_error = |
284 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); | 265 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); |
(...skipping 18 matching lines...) Expand all Loading... |
303 addresses->SetAt( | 284 addresses->SetAt( |
304 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, | 285 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, |
305 if_nametoindex(ifa->ifa_name))); | 286 if_nametoindex(ifa->ifa_name))); |
306 i++; | 287 i++; |
307 } | 288 } |
308 } | 289 } |
309 freeifaddrs(ifaddr); | 290 freeifaddrs(ifaddr); |
310 return addresses; | 291 return addresses; |
311 } | 292 } |
312 | 293 |
313 | |
314 void SocketBase::Close(intptr_t fd) { | 294 void SocketBase::Close(intptr_t fd) { |
315 ASSERT(fd >= 0); | 295 ASSERT(fd >= 0); |
316 VOID_TEMP_FAILURE_RETRY(close(fd)); | 296 VOID_TEMP_FAILURE_RETRY(close(fd)); |
317 } | 297 } |
318 | 298 |
319 | |
320 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { | 299 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { |
321 int on; | 300 int on; |
322 socklen_t len = sizeof(on); | 301 socklen_t len = sizeof(on); |
323 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, | 302 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, |
324 reinterpret_cast<void*>(&on), &len)); | 303 reinterpret_cast<void*>(&on), &len)); |
325 if (err == 0) { | 304 if (err == 0) { |
326 *enabled = (on == 1); | 305 *enabled = (on == 1); |
327 } | 306 } |
328 return (err == 0); | 307 return (err == 0); |
329 } | 308 } |
330 | 309 |
331 | |
332 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { | 310 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { |
333 int on = enabled ? 1 : 0; | 311 int on = enabled ? 1 : 0; |
334 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, | 312 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, |
335 reinterpret_cast<char*>(&on), | 313 reinterpret_cast<char*>(&on), |
336 sizeof(on))) == 0; | 314 sizeof(on))) == 0; |
337 } | 315 } |
338 | 316 |
339 | |
340 bool SocketBase::GetMulticastLoop(intptr_t fd, | 317 bool SocketBase::GetMulticastLoop(intptr_t fd, |
341 intptr_t protocol, | 318 intptr_t protocol, |
342 bool* enabled) { | 319 bool* enabled) { |
343 uint8_t on; | 320 uint8_t on; |
344 socklen_t len = sizeof(on); | 321 socklen_t len = sizeof(on); |
345 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 322 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
346 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 323 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
347 : IPV6_MULTICAST_LOOP; | 324 : IPV6_MULTICAST_LOOP; |
348 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, | 325 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, |
349 reinterpret_cast<char*>(&on), &len)) == 0) { | 326 reinterpret_cast<char*>(&on), &len)) == 0) { |
350 *enabled = (on == 1); | 327 *enabled = (on == 1); |
351 return true; | 328 return true; |
352 } | 329 } |
353 return false; | 330 return false; |
354 } | 331 } |
355 | 332 |
356 | |
357 bool SocketBase::SetMulticastLoop(intptr_t fd, | 333 bool SocketBase::SetMulticastLoop(intptr_t fd, |
358 intptr_t protocol, | 334 intptr_t protocol, |
359 bool enabled) { | 335 bool enabled) { |
360 u_int on = enabled ? 1 : 0; | 336 u_int on = enabled ? 1 : 0; |
361 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 337 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
362 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 338 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
363 : IPV6_MULTICAST_LOOP; | 339 : IPV6_MULTICAST_LOOP; |
364 return NO_RETRY_EXPECTED(setsockopt( | 340 return NO_RETRY_EXPECTED(setsockopt( |
365 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == | 341 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == |
366 0; | 342 0; |
367 } | 343 } |
368 | 344 |
369 | |
370 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { | 345 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { |
371 uint8_t v; | 346 uint8_t v; |
372 socklen_t len = sizeof(v); | 347 socklen_t len = sizeof(v); |
373 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 348 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
374 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 349 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
375 : IPV6_MULTICAST_HOPS; | 350 : IPV6_MULTICAST_HOPS; |
376 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, | 351 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, |
377 reinterpret_cast<char*>(&v), &len)) == 0) { | 352 reinterpret_cast<char*>(&v), &len)) == 0) { |
378 *value = v; | 353 *value = v; |
379 return true; | 354 return true; |
380 } | 355 } |
381 return false; | 356 return false; |
382 } | 357 } |
383 | 358 |
384 | |
385 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { | 359 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { |
386 int v = value; | 360 int v = value; |
387 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 361 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
388 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 362 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
389 : IPV6_MULTICAST_HOPS; | 363 : IPV6_MULTICAST_HOPS; |
390 return NO_RETRY_EXPECTED(setsockopt( | 364 return NO_RETRY_EXPECTED(setsockopt( |
391 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; | 365 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; |
392 } | 366 } |
393 | 367 |
394 | |
395 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { | 368 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { |
396 int on; | 369 int on; |
397 socklen_t len = sizeof(on); | 370 socklen_t len = sizeof(on); |
398 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, | 371 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, |
399 reinterpret_cast<char*>(&on), &len)); | 372 reinterpret_cast<char*>(&on), &len)); |
400 if (err == 0) { | 373 if (err == 0) { |
401 *enabled = (on == 1); | 374 *enabled = (on == 1); |
402 } | 375 } |
403 return (err == 0); | 376 return (err == 0); |
404 } | 377 } |
405 | 378 |
406 | |
407 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { | 379 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { |
408 int on = enabled ? 1 : 0; | 380 int on = enabled ? 1 : 0; |
409 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, | 381 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, |
410 reinterpret_cast<char*>(&on), | 382 reinterpret_cast<char*>(&on), |
411 sizeof(on))) == 0; | 383 sizeof(on))) == 0; |
412 } | 384 } |
413 | 385 |
414 | |
415 static bool JoinOrLeaveMulticast(intptr_t fd, | 386 static bool JoinOrLeaveMulticast(intptr_t fd, |
416 const RawAddr& addr, | 387 const RawAddr& addr, |
417 const RawAddr& interface, | 388 const RawAddr& interface, |
418 int interfaceIndex, | 389 int interfaceIndex, |
419 bool join) { | 390 bool join) { |
420 if (addr.addr.sa_family == AF_INET) { | 391 if (addr.addr.sa_family == AF_INET) { |
421 ASSERT(interface.addr.sa_family == AF_INET); | 392 ASSERT(interface.addr.sa_family == AF_INET); |
422 struct ip_mreq mreq; | 393 struct ip_mreq mreq; |
423 memmove(&mreq.imr_multiaddr, &addr.in.sin_addr, | 394 memmove(&mreq.imr_multiaddr, &addr.in.sin_addr, |
424 SocketAddress::GetInAddrLength(addr)); | 395 SocketAddress::GetInAddrLength(addr)); |
(...skipping 22 matching lines...) Expand all Loading... |
447 } | 418 } |
448 } | 419 } |
449 | 420 |
450 bool SocketBase::JoinMulticast(intptr_t fd, | 421 bool SocketBase::JoinMulticast(intptr_t fd, |
451 const RawAddr& addr, | 422 const RawAddr& addr, |
452 const RawAddr& interface, | 423 const RawAddr& interface, |
453 int interfaceIndex) { | 424 int interfaceIndex) { |
454 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); | 425 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); |
455 } | 426 } |
456 | 427 |
457 | |
458 bool SocketBase::LeaveMulticast(intptr_t fd, | 428 bool SocketBase::LeaveMulticast(intptr_t fd, |
459 const RawAddr& addr, | 429 const RawAddr& addr, |
460 const RawAddr& interface, | 430 const RawAddr& interface, |
461 int interfaceIndex) { | 431 int interfaceIndex) { |
462 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); | 432 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); |
463 } | 433 } |
464 | 434 |
465 } // namespace bin | 435 } // namespace bin |
466 } // namespace dart | 436 } // namespace dart |
467 | 437 |
468 #endif // defined(HOST_OS_MACOS) | 438 #endif // defined(HOST_OS_MACOS) |
469 | 439 |
470 #endif // !defined(DART_IO_DISABLED) | 440 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |