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