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

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

Issue 2780063002: Pulled a significant portion of Socket implementation into BaseSocket in order to prepare for the s… (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
OLDNEW
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(TARGET_OS_ANDROID) 8 #if defined(TARGET_OS_ANDROID)
9 9
10 #include "bin/socket.h" 10 #include "bin/socket.h"
11 #include "bin/socket_android.h" 11 #include "bin/socket_common_android.h"
12 12
13 #include <errno.h> // NOLINT 13 #include <errno.h> // NOLINT
14 #include <netinet/tcp.h> // NOLINT 14 #include <netinet/tcp.h> // NOLINT
15 #include <stdio.h> // NOLINT 15 #include <stdio.h> // NOLINT
16 #include <stdlib.h> // NOLINT 16 #include <stdlib.h> // NOLINT
17 #include <string.h> // NOLINT 17 #include <string.h> // NOLINT
18 #include <sys/stat.h> // NOLINT 18 #include <sys/stat.h> // NOLINT
19 #include <unistd.h> // NOLINT 19 #include <unistd.h> // NOLINT
20 20
21 #include "bin/fdutils.h" 21 #include "bin/fdutils.h"
22 #include "bin/file.h" 22 #include "bin/file.h"
23 #include "platform/signal_blocker.h" 23 #include "platform/signal_blocker.h"
24 24
25 namespace dart { 25 namespace dart {
26 namespace bin { 26 namespace bin {
27 27
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 (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_, 30 if (!BaseSocket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa),
31 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 38
39 bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) { 39 bool BaseSocket::FormatNumericAddress(const RawAddr& addr,
40 char* address,
41 int len) {
40 socklen_t salen = SocketAddress::GetAddrLength(addr); 42 socklen_t salen = SocketAddress::GetAddrLength(addr);
41 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, 43 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
42 0, NI_NUMERICHOST)) == 0); 44 0, NI_NUMERICHOST)) == 0);
43 } 45 }
44 46
45 47
46 bool Socket::Initialize() { 48 bool BaseSocket::Initialize() {
47 // Nothing to do on Android. 49 // Nothing to do on Android.
48 return true; 50 return true;
49 } 51 }
50 52
51 53
52 static intptr_t Create(const RawAddr& addr) { 54 static intptr_t Create(const RawAddr& addr) {
53 intptr_t fd; 55 intptr_t fd;
54 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0)); 56 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0));
55 if (fd < 0) { 57 if (fd < 0) {
56 return -1; 58 return -1;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); 101 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr)));
100 if ((result != 0) && (errno != EINPROGRESS)) { 102 if ((result != 0) && (errno != EINPROGRESS)) {
101 FDUtils::SaveErrorAndClose(fd); 103 FDUtils::SaveErrorAndClose(fd);
102 return -1; 104 return -1;
103 } 105 }
104 106
105 return Connect(fd, addr); 107 return Connect(fd, addr);
106 } 108 }
107 109
108 110
109 bool Socket::IsBindError(intptr_t error_number) { 111 bool BaseSocket::IsBindError(intptr_t error_number) {
110 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || 112 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
111 error_number == EINVAL; 113 error_number == EINVAL;
112 } 114 }
113 115
114 116
115 intptr_t Socket::Available(intptr_t fd) { 117 intptr_t BaseSocket::Available(intptr_t fd) {
116 return FDUtils::AvailableBytes(fd); 118 return FDUtils::AvailableBytes(fd);
117 } 119 }
118 120
119 121
120 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 122 intptr_t BaseSocket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
121 ASSERT(fd >= 0); 123 ASSERT(fd >= 0);
122 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); 124 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
123 ASSERT(EAGAIN == EWOULDBLOCK); 125 ASSERT(EAGAIN == EWOULDBLOCK);
124 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) { 126 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
125 // If the read would block we need to retry and therefore return 0 127 // If the read would block we need to retry and therefore return 0
126 // as the number of bytes written. 128 // as the number of bytes written.
127 read_bytes = 0; 129 read_bytes = 0;
128 } 130 }
129 return read_bytes; 131 return read_bytes;
130 } 132 }
131 133
132 134
133 intptr_t Socket::RecvFrom(intptr_t fd, 135 intptr_t BaseSocket::RecvFrom(intptr_t fd,
134 void* buffer, 136 void* buffer,
135 intptr_t num_bytes, 137 intptr_t num_bytes,
136 RawAddr* addr) { 138 RawAddr* addr) {
137 ASSERT(fd >= 0); 139 ASSERT(fd >= 0);
138 socklen_t addr_len = sizeof(addr->ss); 140 socklen_t addr_len = sizeof(addr->ss);
139 ssize_t read_bytes = TEMP_FAILURE_RETRY( 141 ssize_t read_bytes = TEMP_FAILURE_RETRY(
140 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); 142 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
141 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) { 143 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
142 // If the read would block we need to retry and therefore return 0 144 // If the read would block we need to retry and therefore return 0
143 // as the number of bytes written. 145 // as the number of bytes written.
144 read_bytes = 0; 146 read_bytes = 0;
145 } 147 }
146 return read_bytes; 148 return read_bytes;
147 } 149 }
148 150
149 151
150 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 152 intptr_t BaseSocket::Write(intptr_t fd,
153 const void* buffer,
154 intptr_t num_bytes) {
151 ASSERT(fd >= 0); 155 ASSERT(fd >= 0);
152 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); 156 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
153 ASSERT(EAGAIN == EWOULDBLOCK); 157 ASSERT(EAGAIN == EWOULDBLOCK);
154 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) { 158 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
155 // If the would block we need to retry and therefore return 0 as 159 // If the would block we need to retry and therefore return 0 as
156 // the number of bytes written. 160 // the number of bytes written.
157 written_bytes = 0; 161 written_bytes = 0;
158 } 162 }
159 return written_bytes; 163 return written_bytes;
160 } 164 }
161 165
162 166
163 intptr_t Socket::SendTo(intptr_t fd, 167 intptr_t BaseSocket::SendTo(intptr_t fd,
164 const void* buffer, 168 const void* buffer,
165 intptr_t num_bytes, 169 intptr_t num_bytes,
166 const RawAddr& addr) { 170 const RawAddr& addr) {
167 ASSERT(fd >= 0); 171 ASSERT(fd >= 0);
168 ssize_t written_bytes = 172 ssize_t written_bytes =
169 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, 173 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
170 SocketAddress::GetAddrLength(addr))); 174 SocketAddress::GetAddrLength(addr)));
171 ASSERT(EAGAIN == EWOULDBLOCK); 175 ASSERT(EAGAIN == EWOULDBLOCK);
172 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) { 176 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
173 // If the would block we need to retry and therefore return 0 as 177 // If the would block we need to retry and therefore return 0 as
174 // the number of bytes written. 178 // the number of bytes written.
175 written_bytes = 0; 179 written_bytes = 0;
176 } 180 }
177 return written_bytes; 181 return written_bytes;
178 } 182 }
179 183
180 184
181 intptr_t Socket::GetPort(intptr_t fd) { 185 intptr_t BaseSocket::GetPort(intptr_t fd) {
182 ASSERT(fd >= 0); 186 ASSERT(fd >= 0);
183 RawAddr raw; 187 RawAddr raw;
184 socklen_t size = sizeof(raw); 188 socklen_t size = sizeof(raw);
185 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { 189 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
186 return 0; 190 return 0;
187 } 191 }
188 return SocketAddress::GetAddrPort(raw); 192 return SocketAddress::GetAddrPort(raw);
189 } 193 }
190 194
191 195
192 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { 196 SocketAddress* BaseSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
193 ASSERT(fd >= 0); 197 ASSERT(fd >= 0);
194 RawAddr raw; 198 RawAddr raw;
195 socklen_t size = sizeof(raw); 199 socklen_t size = sizeof(raw);
196 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { 200 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
197 return NULL; 201 return NULL;
198 } 202 }
199 *port = SocketAddress::GetAddrPort(raw); 203 *port = SocketAddress::GetAddrPort(raw);
200 return new SocketAddress(&raw.addr); 204 return new SocketAddress(&raw.addr);
201 } 205 }
202 206
203 207
204 void Socket::GetError(intptr_t fd, OSError* os_error) { 208 void BaseSocket::GetError(intptr_t fd, OSError* os_error) {
205 int errorNumber; 209 int errorNumber;
206 socklen_t len = sizeof(errorNumber); 210 socklen_t len = sizeof(errorNumber);
207 getsockopt(fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&errorNumber), 211 getsockopt(fd, SOL_SOCKET, SO_ERROR, reinterpret_cast<void*>(&errorNumber),
208 &len); 212 &len);
209 os_error->SetCodeAndMessage(OSError::kSystem, errorNumber); 213 os_error->SetCodeAndMessage(OSError::kSystem, errorNumber);
210 } 214 }
211 215
212 216
213 int Socket::GetType(intptr_t fd) { 217 int BaseSocket::GetType(intptr_t fd) {
214 struct stat buf; 218 struct stat buf;
215 int result = fstat(fd, &buf); 219 int result = fstat(fd, &buf);
216 if (result == -1) { 220 if (result == -1) {
217 return -1; 221 return -1;
218 } 222 }
219 if (S_ISCHR(buf.st_mode)) { 223 if (S_ISCHR(buf.st_mode)) {
220 return File::kTerminal; 224 return File::kTerminal;
221 } 225 }
222 if (S_ISFIFO(buf.st_mode)) { 226 if (S_ISFIFO(buf.st_mode)) {
223 return File::kPipe; 227 return File::kPipe;
224 } 228 }
225 if (S_ISREG(buf.st_mode)) { 229 if (S_ISREG(buf.st_mode)) {
226 return File::kFile; 230 return File::kFile;
227 } 231 }
228 return File::kOther; 232 return File::kOther;
229 } 233 }
230 234
231 235
232 intptr_t Socket::GetStdioHandle(intptr_t num) { 236 intptr_t BaseSocket::GetStdioHandle(intptr_t num) {
233 return num; 237 return num;
234 } 238 }
235 239
236 240
237 AddressList<SocketAddress>* Socket::LookupAddress(const char* host, 241 AddressList<SocketAddress>* BaseSocket::LookupAddress(const char* host,
238 int type, 242 int type,
239 OSError** os_error) { 243 OSError** os_error) {
240 // Perform a name lookup for a host name. 244 // Perform a name lookup for a host name.
241 struct addrinfo hints; 245 struct addrinfo hints;
242 memset(&hints, 0, sizeof(hints)); 246 memset(&hints, 0, sizeof(hints));
243 hints.ai_family = SocketAddress::FromType(type); 247 hints.ai_family = SocketAddress::FromType(type);
244 hints.ai_socktype = SOCK_STREAM; 248 hints.ai_socktype = SOCK_STREAM;
245 hints.ai_flags = AI_ADDRCONFIG; 249 hints.ai_flags = AI_ADDRCONFIG;
246 hints.ai_protocol = IPPROTO_TCP; 250 hints.ai_protocol = IPPROTO_TCP;
247 struct addrinfo* info = NULL; 251 struct addrinfo* info = NULL;
248 int status = getaddrinfo(host, 0, &hints, &info); 252 int status = getaddrinfo(host, 0, &hints, &info);
249 if (status != 0) { 253 if (status != 0) {
(...skipping 20 matching lines...) Expand all
270 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { 274 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
271 addresses->SetAt(i, new SocketAddress(c->ai_addr)); 275 addresses->SetAt(i, new SocketAddress(c->ai_addr));
272 i++; 276 i++;
273 } 277 }
274 } 278 }
275 freeaddrinfo(info); 279 freeaddrinfo(info);
276 return addresses; 280 return addresses;
277 } 281 }
278 282
279 283
280 bool Socket::ReverseLookup(const RawAddr& addr, 284 bool BaseSocket::ReverseLookup(const RawAddr& addr,
281 char* host, 285 char* host,
282 intptr_t host_len, 286 intptr_t host_len,
283 OSError** os_error) { 287 OSError** os_error) {
284 ASSERT(host_len >= NI_MAXHOST); 288 ASSERT(host_len >= NI_MAXHOST);
285 int status = NO_RETRY_EXPECTED( 289 int status = NO_RETRY_EXPECTED(
286 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, 290 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
287 host_len, NULL, 0, NI_NAMEREQD)); 291 host_len, NULL, 0, NI_NAMEREQD));
288 if (status != 0) { 292 if (status != 0) {
289 ASSERT(*os_error == NULL); 293 ASSERT(*os_error == NULL);
290 *os_error = 294 *os_error =
291 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); 295 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
292 return false; 296 return false;
293 } 297 }
294 return true; 298 return true;
295 } 299 }
296 300
297 301
298 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { 302 bool BaseSocket::ParseAddress(int type, const char* address, RawAddr* addr) {
299 int result; 303 int result;
300 if (type == SocketAddress::TYPE_IPV4) { 304 if (type == SocketAddress::TYPE_IPV4) {
301 result = inet_pton(AF_INET, address, &addr->in.sin_addr); 305 result = inet_pton(AF_INET, address, &addr->in.sin_addr);
302 } else { 306 } else {
303 ASSERT(type == SocketAddress::TYPE_IPV6); 307 ASSERT(type == SocketAddress::TYPE_IPV6);
304 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 308 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
305 } 309 }
306 return (result == 1); 310 return (result == 1);
307 } 311 }
308 312
(...skipping 24 matching lines...) Expand all
333 } 337 }
334 338
335 if (!FDUtils::SetNonBlocking(fd)) { 339 if (!FDUtils::SetNonBlocking(fd)) {
336 FDUtils::SaveErrorAndClose(fd); 340 FDUtils::SaveErrorAndClose(fd);
337 return -1; 341 return -1;
338 } 342 }
339 return fd; 343 return fd;
340 } 344 }
341 345
342 346
343 bool Socket::ListInterfacesSupported() { 347 bool BaseSocket::ListInterfacesSupported() {
344 return false; 348 return false;
345 } 349 }
346 350
347 351
348 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 352 AddressList<InterfaceSocketAddress>* BaseSocket::ListInterfaces(
349 int type, 353 int type,
350 OSError** os_error) { 354 OSError** os_error) {
351 // The ifaddrs.h header is not provided on Android. An Android 355 // The ifaddrs.h header is not provided on Android. An Android
352 // implementation would have to use IOCTL or netlink. 356 // implementation would have to use IOCTL or netlink.
353 ASSERT(*os_error == NULL); 357 ASSERT(*os_error == NULL);
354 *os_error = new OSError(-1, 358 *os_error = new OSError(-1,
355 "Listing interfaces is not supported " 359 "Listing interfaces is not supported "
356 "on this platform", 360 "on this platform",
357 OSError::kSystem); 361 OSError::kSystem);
358 return NULL; 362 return NULL;
(...skipping 26 matching lines...) Expand all
385 } 389 }
386 390
387 if (NO_RETRY_EXPECTED( 391 if (NO_RETRY_EXPECTED(
388 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { 392 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) {
389 FDUtils::SaveErrorAndClose(fd); 393 FDUtils::SaveErrorAndClose(fd);
390 return -1; 394 return -1;
391 } 395 }
392 396
393 // Test for invalid socket port 65535 (some browsers disallow it). 397 // Test for invalid socket port 65535 (some browsers disallow it).
394 if ((SocketAddress::GetAddrPort(addr)) == 0 && 398 if ((SocketAddress::GetAddrPort(addr)) == 0 &&
395 (Socket::GetPort(fd) == 65535)) { 399 (BaseSocket::GetPort(fd) == 65535)) {
396 // Don't close the socket until we have created a new socket, ensuring 400 // Don't close the socket until we have created a new socket, ensuring
397 // that we do not get the bad port number again. 401 // that we do not get the bad port number again.
398 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); 402 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only);
399 FDUtils::SaveErrorAndClose(fd); 403 FDUtils::SaveErrorAndClose(fd);
400 return new_fd; 404 return new_fd;
401 } 405 }
402 406
403 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { 407 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
404 FDUtils::SaveErrorAndClose(fd); 408 FDUtils::SaveErrorAndClose(fd);
405 return -1; 409 return -1;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 } 453 }
450 if (!FDUtils::SetNonBlocking(socket)) { 454 if (!FDUtils::SetNonBlocking(socket)) {
451 FDUtils::SaveErrorAndClose(socket); 455 FDUtils::SaveErrorAndClose(socket);
452 return -1; 456 return -1;
453 } 457 }
454 } 458 }
455 return socket; 459 return socket;
456 } 460 }
457 461
458 462
459 void Socket::Close(intptr_t fd) { 463 void BaseSocket::Close(intptr_t fd) {
460 ASSERT(fd >= 0); 464 ASSERT(fd >= 0);
461 VOID_TEMP_FAILURE_RETRY(close(fd)); 465 VOID_TEMP_FAILURE_RETRY(close(fd));
462 } 466 }
463 467
464 468
465 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 469 bool BaseSocket::GetNoDelay(intptr_t fd, bool* enabled) {
466 int on; 470 int on;
467 socklen_t len = sizeof(on); 471 socklen_t len = sizeof(on);
468 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 472 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
469 reinterpret_cast<void*>(&on), &len)); 473 reinterpret_cast<void*>(&on), &len));
470 if (err == 0) { 474 if (err == 0) {
471 *enabled = (on == 1); 475 *enabled = (on == 1);
472 } 476 }
473 return (err == 0); 477 return (err == 0);
474 } 478 }
475 479
476 480
477 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 481 bool BaseSocket::SetNoDelay(intptr_t fd, bool enabled) {
478 int on = enabled ? 1 : 0; 482 int on = enabled ? 1 : 0;
479 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 483 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
480 reinterpret_cast<char*>(&on), 484 reinterpret_cast<char*>(&on),
481 sizeof(on))) == 0; 485 sizeof(on))) == 0;
482 } 486 }
483 487
484 488
485 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 489 bool BaseSocket::GetMulticastLoop(intptr_t fd,
490 intptr_t protocol,
491 bool* enabled) {
486 uint8_t on; 492 uint8_t on;
487 socklen_t len = sizeof(on); 493 socklen_t len = sizeof(on);
488 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 494 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
489 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 495 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
490 : IPV6_MULTICAST_LOOP; 496 : IPV6_MULTICAST_LOOP;
491 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, 497 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
492 reinterpret_cast<char*>(&on), &len)) == 0) { 498 reinterpret_cast<char*>(&on), &len)) == 0) {
493 *enabled = (on == 1); 499 *enabled = (on == 1);
494 return true; 500 return true;
495 } 501 }
496 return false; 502 return false;
497 } 503 }
498 504
499 505
500 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 506 bool BaseSocket::SetMulticastLoop(intptr_t fd,
507 intptr_t protocol,
508 bool enabled) {
501 int on = enabled ? 1 : 0; 509 int on = enabled ? 1 : 0;
502 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 510 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
503 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 511 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
504 : IPV6_MULTICAST_LOOP; 512 : IPV6_MULTICAST_LOOP;
505 return NO_RETRY_EXPECTED(setsockopt( 513 return NO_RETRY_EXPECTED(setsockopt(
506 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == 514 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) ==
507 0; 515 0;
508 } 516 }
509 517
510 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 518 bool BaseSocket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
511 uint8_t v; 519 uint8_t v;
512 socklen_t len = sizeof(v); 520 socklen_t len = sizeof(v);
513 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 521 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
514 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 522 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
515 : IPV6_MULTICAST_HOPS; 523 : IPV6_MULTICAST_HOPS;
516 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, 524 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
517 reinterpret_cast<char*>(&v), &len)) == 0) { 525 reinterpret_cast<char*>(&v), &len)) == 0) {
518 *value = v; 526 *value = v;
519 return true; 527 return true;
520 } 528 }
521 return false; 529 return false;
522 } 530 }
523 531
524 532
525 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 533 bool BaseSocket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
526 int v = value; 534 int v = value;
527 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 535 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
528 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 536 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
529 : IPV6_MULTICAST_HOPS; 537 : IPV6_MULTICAST_HOPS;
530 return NO_RETRY_EXPECTED(setsockopt( 538 return NO_RETRY_EXPECTED(setsockopt(
531 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; 539 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0;
532 } 540 }
533 541
534 542
535 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 543 bool BaseSocket::GetBroadcast(intptr_t fd, bool* enabled) {
536 int on; 544 int on;
537 socklen_t len = sizeof(on); 545 socklen_t len = sizeof(on);
538 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, 546 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST,
539 reinterpret_cast<char*>(&on), &len)); 547 reinterpret_cast<char*>(&on), &len));
540 if (err == 0) { 548 if (err == 0) {
541 *enabled = (on == 1); 549 *enabled = (on == 1);
542 } 550 }
543 return (err == 0); 551 return (err == 0);
544 } 552 }
545 553
546 554
547 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 555 bool BaseSocket::SetBroadcast(intptr_t fd, bool enabled) {
548 int on = enabled ? 1 : 0; 556 int on = enabled ? 1 : 0;
549 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, 557 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
550 reinterpret_cast<char*>(&on), 558 reinterpret_cast<char*>(&on),
551 sizeof(on))) == 0; 559 sizeof(on))) == 0;
552 } 560 }
553 561
554 562
555 bool Socket::JoinMulticast(intptr_t fd, 563 bool BaseSocket::JoinMulticast(intptr_t fd,
556 const RawAddr& addr, 564 const RawAddr& addr,
557 const RawAddr&, 565 const RawAddr&,
558 int interfaceIndex) { 566 int interfaceIndex) {
559 int proto = (addr.addr.sa_family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6; 567 int proto = (addr.addr.sa_family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6;
560 struct group_req mreq; 568 struct group_req mreq;
561 mreq.gr_interface = interfaceIndex; 569 mreq.gr_interface = interfaceIndex;
562 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); 570 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
563 return NO_RETRY_EXPECTED( 571 return NO_RETRY_EXPECTED(
564 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; 572 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
565 } 573 }
566 574
567 575
568 bool Socket::LeaveMulticast(intptr_t fd, 576 bool BaseSocket::LeaveMulticast(intptr_t fd,
569 const RawAddr& addr, 577 const RawAddr& addr,
570 const RawAddr&, 578 const RawAddr&,
571 int interfaceIndex) { 579 int interfaceIndex) {
572 int proto = (addr.addr.sa_family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6; 580 int proto = (addr.addr.sa_family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6;
573 struct group_req mreq; 581 struct group_req mreq;
574 mreq.gr_interface = interfaceIndex; 582 mreq.gr_interface = interfaceIndex;
575 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); 583 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
576 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, 584 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq,
577 sizeof(mreq))) == 0; 585 sizeof(mreq))) == 0;
578 } 586 }
579 587
580 } // namespace bin 588 } // namespace bin
581 } // namespace dart 589 } // namespace dart
582 590
583 #endif // defined(TARGET_OS_ANDROID) 591 #endif // defined(TARGET_OS_ANDROID)
584 592
585 #endif // !defined(DART_IO_DISABLED) 593 #endif // !defined(DART_IO_DISABLED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698