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

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

Issue 85993002: Add UDP support to dart:io (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix Windows build Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/socket.cc ('k') | runtime/bin/socket_linux.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_ANDROID) 6 #if defined(TARGET_OS_ANDROID)
7 7
8 #include <errno.h> // NOLINT 8 #include <errno.h> // NOLINT
9 #include <stdio.h> // NOLINT 9 #include <stdio.h> // NOLINT
10 #include <stdlib.h> // NOLINT 10 #include <stdlib.h> // NOLINT
11 #include <string.h> // NOLINT 11 #include <string.h> // NOLINT
12 #include <sys/stat.h> // NOLINT 12 #include <sys/stat.h> // NOLINT
13 #include <unistd.h> // NOLINT 13 #include <unistd.h> // NOLINT
14 #include <netinet/tcp.h> // NOLINT 14 #include <netinet/tcp.h> // NOLINT
15 15
16 #include "bin/fdutils.h" 16 #include "bin/fdutils.h"
17 #include "bin/file.h" 17 #include "bin/file.h"
18 #include "bin/log.h" 18 #include "bin/log.h"
19 #include "bin/socket.h" 19 #include "bin/socket.h"
20 20
21 21
22 namespace dart { 22 namespace dart {
23 namespace bin { 23 namespace bin {
24 24
25 SocketAddress::SocketAddress(struct sockaddr* sa) { 25 SocketAddress::SocketAddress(struct sockaddr* sa) {
26 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); 26 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
27 socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa)); 27 if (!Socket::FormatNumericAddress(
28 if (TEMP_FAILURE_RETRY(getnameinfo(sa, 28 reinterpret_cast<RawAddr*>(sa), as_string_, INET6_ADDRSTRLEN)) {
29 salen,
30 as_string_,
31 INET6_ADDRSTRLEN,
32 NULL,
33 0,
34 NI_NUMERICHOST)) != 0) {
35 as_string_[0] = 0; 29 as_string_[0] = 0;
36 } 30 }
31 socklen_t salen = GetAddrLength(reinterpret_cast<RawAddr*>(sa));
37 memmove(reinterpret_cast<void *>(&addr_), sa, salen); 32 memmove(reinterpret_cast<void *>(&addr_), sa, salen);
38 } 33 }
39 34
40 35
36 bool Socket::FormatNumericAddress(RawAddr* addr, char* address, int len) {
37 socklen_t salen = SocketAddress::GetAddrLength(addr);
38 if (TEMP_FAILURE_RETRY(getnameinfo(&addr->addr,
39 salen,
40 address,
41 len,
42 NULL,
43 0,
44 NI_NUMERICHOST)) != 0) {
45 return false;
46 }
47 return true;
48 }
49
50
41 bool Socket::Initialize() { 51 bool Socket::Initialize() {
42 // Nothing to do on Android. 52 // Nothing to do on Android.
43 return true; 53 return true;
44 } 54 }
45 55
46 56
47 intptr_t Socket::Create(RawAddr addr) { 57 intptr_t Socket::Create(RawAddr addr) {
48 intptr_t fd; 58 intptr_t fd;
49 59
50 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0)); 60 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 ASSERT(EAGAIN == EWOULDBLOCK); 108 ASSERT(EAGAIN == EWOULDBLOCK);
99 if (read_bytes == -1 && errno == EWOULDBLOCK) { 109 if (read_bytes == -1 && errno == EWOULDBLOCK) {
100 // If the read would block we need to retry and therefore return 0 110 // If the read would block we need to retry and therefore return 0
101 // as the number of bytes written. 111 // as the number of bytes written.
102 read_bytes = 0; 112 read_bytes = 0;
103 } 113 }
104 return read_bytes; 114 return read_bytes;
105 } 115 }
106 116
107 117
118 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes,
119 RawAddr* addr) {
120 ASSERT(fd >= 0);
121 socklen_t addr_len = sizeof(addr->ss);
122 ssize_t read_bytes =
123 TEMP_FAILURE_RETRY(
124 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
125 if (read_bytes == -1 && errno == EWOULDBLOCK) {
126 // If the read would block we need to retry and therefore return 0
127 // as the number of bytes written.
128 read_bytes = 0;
129 }
130 return read_bytes;
131 }
132
133
108 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 134 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
109 ASSERT(fd >= 0); 135 ASSERT(fd >= 0);
110 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); 136 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
111 ASSERT(EAGAIN == EWOULDBLOCK); 137 ASSERT(EAGAIN == EWOULDBLOCK);
112 if (written_bytes == -1 && errno == EWOULDBLOCK) { 138 if (written_bytes == -1 && errno == EWOULDBLOCK) {
113 // If the would block we need to retry and therefore return 0 as 139 // If the would block we need to retry and therefore return 0 as
114 // the number of bytes written. 140 // the number of bytes written.
115 written_bytes = 0; 141 written_bytes = 0;
116 } 142 }
117 return written_bytes; 143 return written_bytes;
118 } 144 }
119 145
120 146
147 int Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes,
148 RawAddr addr) {
149 ASSERT(fd >= 0);
150 ssize_t written_bytes =
151 TEMP_FAILURE_RETRY(
152 sendto(fd, buffer, num_bytes, 0,
153 &addr.addr, SocketAddress::GetAddrLength(&addr)));
154 ASSERT(EAGAIN == EWOULDBLOCK);
155 if (written_bytes == -1 && errno == EWOULDBLOCK) {
156 // If the would block we need to retry and therefore return 0 as
157 // the number of bytes written.
158 written_bytes = 0;
159 }
160 return written_bytes;
161 }
162
163
121 intptr_t Socket::GetPort(intptr_t fd) { 164 intptr_t Socket::GetPort(intptr_t fd) {
122 ASSERT(fd >= 0); 165 ASSERT(fd >= 0);
123 RawAddr raw; 166 RawAddr raw;
124 socklen_t size = sizeof(raw); 167 socklen_t size = sizeof(raw);
125 if (TEMP_FAILURE_RETRY( 168 if (TEMP_FAILURE_RETRY(
126 getsockname(fd, 169 getsockname(fd,
127 &raw.addr, 170 &raw.addr,
128 &size))) { 171 &size))) {
129 const int kBufferSize = 1024; 172 const int kBufferSize = 1024;
130 char error_message[kBufferSize]; 173 char error_message[kBufferSize];
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (type == SocketAddress::TYPE_IPV4) { 292 if (type == SocketAddress::TYPE_IPV4) {
250 result = inet_pton(AF_INET, address, &addr->in.sin_addr); 293 result = inet_pton(AF_INET, address, &addr->in.sin_addr);
251 } else { 294 } else {
252 ASSERT(type == SocketAddress::TYPE_IPV6); 295 ASSERT(type == SocketAddress::TYPE_IPV6);
253 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 296 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
254 } 297 }
255 return result == 1; 298 return result == 1;
256 } 299 }
257 300
258 301
302 intptr_t Socket::CreateBindDatagram(
303 RawAddr* addr, intptr_t port, bool reuseAddress) {
304 intptr_t fd;
305
306 fd = TEMP_FAILURE_RETRY(
307 socket(addr->addr.sa_family, SOCK_DGRAM, IPPROTO_UDP));
308 if (fd < 0) return -1;
309
310 FDUtils::SetCloseOnExec(fd);
311
312 if (reuseAddress) {
313 int optval = 1;
314 TEMP_FAILURE_RETRY(
315 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
316 }
317
318 SocketAddress::SetAddrPort(addr, port);
319 if (TEMP_FAILURE_RETRY(
320 bind(fd,
321 &addr->addr,
322 SocketAddress::GetAddrLength(addr))) < 0) {
323 TEMP_FAILURE_RETRY(close(fd));
324 return -1;
325 }
326
327 Socket::SetNonBlocking(fd);
328 return fd;
329 }
330
331
259 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 332 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
260 int type, 333 int type,
261 OSError** os_error) { 334 OSError** os_error) {
262 // The ifaddrs.h header is not provided on Android. An Android 335 // The ifaddrs.h header is not provided on Android. An Android
263 // implementation would have to use IOCTL or netlink. 336 // implementation would have to use IOCTL or netlink.
264 return NULL; 337 return NULL;
265 } 338 }
266 339
267 340
268 intptr_t ServerSocket::CreateBindListen(RawAddr addr, 341 intptr_t ServerSocket::CreateBindListen(RawAddr addr,
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 bool Socket::SetNonBlocking(intptr_t fd) { 434 bool Socket::SetNonBlocking(intptr_t fd) {
362 return FDUtils::SetNonBlocking(fd); 435 return FDUtils::SetNonBlocking(fd);
363 } 436 }
364 437
365 438
366 bool Socket::SetBlocking(intptr_t fd) { 439 bool Socket::SetBlocking(intptr_t fd) {
367 return FDUtils::SetBlocking(fd); 440 return FDUtils::SetBlocking(fd);
368 } 441 }
369 442
370 443
444 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
445 int on;
446 socklen_t len = sizeof(on);
447 int err = TEMP_FAILURE_RETRY(getsockopt(fd,
448 IPPROTO_TCP,
449 TCP_NODELAY,
450 reinterpret_cast<void *>(&on),
451 &len));
452 if (err == 0) {
453 *enabled = on == 1;
454 }
455 return err == 0;
456 }
457
458
371 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 459 bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
372 int on = enabled ? 1 : 0; 460 int on = enabled ? 1 : 0;
373 return TEMP_FAILURE_RETRY(setsockopt(fd, 461 return TEMP_FAILURE_RETRY(setsockopt(fd,
374 IPPROTO_TCP, 462 IPPROTO_TCP,
375 TCP_NODELAY, 463 TCP_NODELAY,
376 reinterpret_cast<char *>(&on), 464 reinterpret_cast<char *>(&on),
377 sizeof(on))) == 0; 465 sizeof(on))) == 0;
378 } 466 }
379 467
468
469 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) {
470 uint8_t on;
471 socklen_t len = sizeof(on);
472 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
473 int optname = protocol == SocketAddress::TYPE_IPV4
474 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
475 if (TEMP_FAILURE_RETRY(getsockopt(fd,
476 level,
477 optname,
478 reinterpret_cast<char *>(&on),
479 &len)) == 0) {
480 *enabled = (on == 1);
481 return true;
482 }
483 return false;
484 }
485
486
487 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) {
488 int on = enabled ? 1 : 0;
489 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
490 int optname = protocol == SocketAddress::TYPE_IPV4
491 ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP;
492 return TEMP_FAILURE_RETRY(setsockopt(fd,
493 level,
494 optname,
495 reinterpret_cast<char *>(&on),
496 sizeof(on))) == 0;
497 }
498
499
500 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
501 uint8_t v;
502 socklen_t len = sizeof(v);
503 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
504 int optname = protocol == SocketAddress::TYPE_IPV4
505 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
506 if (TEMP_FAILURE_RETRY(getsockopt(fd,
507 level,
508 optname,
509 reinterpret_cast<char *>(&v),
510 &len)) == 0) {
511 *value = v;
512 return true;
513 }
514 return false;
515 }
516
517
518 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
519 int v = value;
520 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
521 int optname = protocol == SocketAddress::TYPE_IPV4
522 ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS;
523 return TEMP_FAILURE_RETRY(setsockopt(fd,
524 level,
525 optname,
526 reinterpret_cast<char *>(&v),
527 sizeof(v))) == 0;
528 }
529
530
531 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) {
532 int on;
533 socklen_t len = sizeof(on);
534 int err = TEMP_FAILURE_RETRY(getsockopt(fd,
535 SOL_SOCKET,
536 SO_BROADCAST,
537 reinterpret_cast<char *>(&on),
538 &len));
539 if (err == 0) {
540 *enabled = on == 1;
541 }
542 return err == 0;
543 }
544
545
546 bool Socket::SetBroadcast(intptr_t fd, bool enabled) {
547 int on = enabled ? 1 : 0;
548 return TEMP_FAILURE_RETRY(setsockopt(fd,
549 SOL_SOCKET,
550 SO_BROADCAST,
551 reinterpret_cast<char *>(&on),
552 sizeof(on))) == 0;
553 }
554
555
556 bool Socket::JoinMulticast(intptr_t fd, RawAddr* addr, int interfaceIndex) {
557 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
558 struct group_req mreq;
559 mreq.gr_interface = interfaceIndex;
560 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
561 return TEMP_FAILURE_RETRY(setsockopt(
562 fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
563 }
564
565
566 bool Socket::LeaveMulticast(intptr_t fd, RawAddr* addr, int interfaceIndex) {
567 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
568 struct group_req mreq;
569 mreq.gr_interface = interfaceIndex;
570 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
571 return TEMP_FAILURE_RETRY(setsockopt(
572 fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0;
573 }
574
380 } // namespace bin 575 } // namespace bin
381 } // namespace dart 576 } // namespace dart
382 577
383 #endif // defined(TARGET_OS_ANDROID) 578 #endif // defined(TARGET_OS_ANDROID)
OLDNEW
« no previous file with comments | « runtime/bin/socket.cc ('k') | runtime/bin/socket_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698