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

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

Issue 85993002: Add UDP support to dart:io (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
OLDNEW
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 #include "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_LINUX) 6 #if defined(TARGET_OS_LINUX)
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
(...skipping 21 matching lines...) Expand all
32 INET6_ADDRSTRLEN, 32 INET6_ADDRSTRLEN,
33 NULL, 33 NULL,
34 0, 34 0,
35 NI_NUMERICHOST)) != 0) { 35 NI_NUMERICHOST)) != 0) {
36 as_string_[0] = 0; 36 as_string_[0] = 0;
37 } 37 }
38 memmove(reinterpret_cast<void *>(&addr_), sa, salen); 38 memmove(reinterpret_cast<void *>(&addr_), sa, salen);
39 } 39 }
40 40
41 41
42 bool Socket::FormatNumericAddress(RawAddr* addr, char* address, int len) {
43 socklen_t salen = SocketAddress::GetAddrLength(addr);
44 if (TEMP_FAILURE_RETRY(getnameinfo(&addr->addr,
45 salen,
46 address,
47 len,
48 NULL,
49 0,
50 NI_NUMERICHOST)) != 0) {
51 return false;
52 }
53 return true;
54 }
55
56
42 bool Socket::Initialize() { 57 bool Socket::Initialize() {
43 // Nothing to do on Linux. 58 // Nothing to do on Linux.
44 return true; 59 return true;
45 } 60 }
46 61
47 62
48 intptr_t Socket::Create(RawAddr addr) { 63 intptr_t Socket::Create(RawAddr addr) {
49 intptr_t fd; 64 intptr_t fd;
50 65
51 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0)); 66 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 ASSERT(EAGAIN == EWOULDBLOCK); 114 ASSERT(EAGAIN == EWOULDBLOCK);
100 if (read_bytes == -1 && errno == EWOULDBLOCK) { 115 if (read_bytes == -1 && errno == EWOULDBLOCK) {
101 // If the read would block we need to retry and therefore return 0 116 // If the read would block we need to retry and therefore return 0
102 // as the number of bytes written. 117 // as the number of bytes written.
103 read_bytes = 0; 118 read_bytes = 0;
104 } 119 }
105 return read_bytes; 120 return read_bytes;
106 } 121 }
107 122
108 123
124 int Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes,
125 RawAddr* addr) {
126 ASSERT(fd >= 0);
127 socklen_t addr_len = sizeof(addr->addr);
128 ssize_t read_bytes =
129 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len);
130 if (read_bytes == -1 && errno == EWOULDBLOCK) {
131 // If the read would block we need to retry and therefore return 0
132 // as the number of bytes written.
133 read_bytes = 0;
134 }
135 return read_bytes;
136 }
137
138
109 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 139 int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
110 ASSERT(fd >= 0); 140 ASSERT(fd >= 0);
111 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); 141 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
112 ASSERT(EAGAIN == EWOULDBLOCK); 142 ASSERT(EAGAIN == EWOULDBLOCK);
113 if (written_bytes == -1 && errno == EWOULDBLOCK) { 143 if (written_bytes == -1 && errno == EWOULDBLOCK) {
114 // If the would block we need to retry and therefore return 0 as 144 // If the would block we need to retry and therefore return 0 as
115 // the number of bytes written. 145 // the number of bytes written.
116 written_bytes = 0; 146 written_bytes = 0;
117 } 147 }
118 return written_bytes; 148 return written_bytes;
119 } 149 }
120 150
121 151
152 int Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes,
153 RawAddr addr) {
154 ASSERT(fd >= 0);
155 ssize_t written_bytes =
156 TEMP_FAILURE_RETRY(
157 sendto(fd, buffer, num_bytes, 0,
158 &addr.addr, SocketAddress::GetAddrLength(&addr)));
159 ASSERT(EAGAIN == EWOULDBLOCK);
160 if (written_bytes == -1 && errno == EWOULDBLOCK) {
161 // If the would block we need to retry and therefore return 0 as
162 // the number of bytes written.
163 written_bytes = 0;
164 }
165 return written_bytes;
166 }
167
168
122 intptr_t Socket::GetPort(intptr_t fd) { 169 intptr_t Socket::GetPort(intptr_t fd) {
123 ASSERT(fd >= 0); 170 ASSERT(fd >= 0);
124 RawAddr raw; 171 RawAddr raw;
125 socklen_t size = sizeof(raw); 172 socklen_t size = sizeof(raw);
126 if (TEMP_FAILURE_RETRY( 173 if (TEMP_FAILURE_RETRY(
127 getsockname(fd, 174 getsockname(fd,
128 &raw.addr, 175 &raw.addr,
129 &size))) { 176 &size))) {
130 const int kBufferSize = 1024; 177 const int kBufferSize = 1024;
131 char error_buf[kBufferSize]; 178 char error_buf[kBufferSize];
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 if (type == SocketAddress::TYPE_IPV4) { 296 if (type == SocketAddress::TYPE_IPV4) {
250 result = inet_pton(AF_INET, address, &addr->in.sin_addr); 297 result = inet_pton(AF_INET, address, &addr->in.sin_addr);
251 } else { 298 } else {
252 ASSERT(type == SocketAddress::TYPE_IPV6); 299 ASSERT(type == SocketAddress::TYPE_IPV6);
253 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 300 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
254 } 301 }
255 return result == 1; 302 return result == 1;
256 } 303 }
257 304
258 305
306 intptr_t Socket::CreateBindDatagram(RawAddr* addr, intptr_t port) {
307 intptr_t fd;
308
309 fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
310 if (fd < 0) return -1;
311
312 FDUtils::SetCloseOnExec(fd);
313
314 if (addr != NULL) {
315 SocketAddress::SetAddrPort(addr, port);
316 if (TEMP_FAILURE_RETRY(
317 bind(fd,
318 &addr->addr,
319 SocketAddress::GetAddrLength(addr))) < 0) {
320 TEMP_FAILURE_RETRY(close(fd));
321 return -1;
322 }
323 }
324
325 Socket::SetNonBlocking(fd);
326 return fd;
327 }
328
329
259 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { 330 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
260 if (ifa->ifa_addr == NULL) { 331 if (ifa->ifa_addr == NULL) {
261 // OpenVPN's virtual device tun0. 332 // OpenVPN's virtual device tun0.
262 return false; 333 return false;
263 } 334 }
264 int family = ifa->ifa_addr->sa_family; 335 int family = ifa->ifa_addr->sa_family;
265 if (lookup_family == family) return true; 336 if (lookup_family == family) return true;
266 if (lookup_family == AF_UNSPEC && 337 if (lookup_family == AF_UNSPEC &&
267 (family == AF_INET || family == AF_INET6)) { 338 (family == AF_INET || family == AF_INET6)) {
268 return true; 339 return true;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 bool Socket::SetNonBlocking(intptr_t fd) { 473 bool Socket::SetNonBlocking(intptr_t fd) {
403 return FDUtils::SetNonBlocking(fd); 474 return FDUtils::SetNonBlocking(fd);
404 } 475 }
405 476
406 477
407 bool Socket::SetBlocking(intptr_t fd) { 478 bool Socket::SetBlocking(intptr_t fd) {
408 return FDUtils::SetBlocking(fd); 479 return FDUtils::SetBlocking(fd);
409 } 480 }
410 481
411 482
483 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) {
484 int on;
485 socklen_t len = sizeof(on);
486 int err = TEMP_FAILURE_RETRY(getsockopt(fd,
487 IPPROTO_TCP,
488 TCP_NODELAY,
489 reinterpret_cast<void *>(&on),
490 &len));
491 if (err == 0) {
492 *enabled = on == 1;
493 }
494 return err == 0;
495 }
496
497
412 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 498 bool Socket::SetNoDelay(intptr_t fd, bool enabled) {
413 int on = enabled ? 1 : 0; 499 int on = enabled ? 1 : 0;
414 return TEMP_FAILURE_RETRY(setsockopt(fd, 500 return TEMP_FAILURE_RETRY(setsockopt(fd,
415 IPPROTO_TCP, 501 IPPROTO_TCP,
416 TCP_NODELAY, 502 TCP_NODELAY,
417 reinterpret_cast<char *>(&on), 503 reinterpret_cast<char *>(&on),
418 sizeof(on))) == 0; 504 sizeof(on))) == 0;
419 } 505 }
420 506
507
508 bool Socket::GetMulticastLoop(intptr_t fd, bool* enabled) {
509 uint8_t on;
510 socklen_t len = sizeof(on);
511 int err = TEMP_FAILURE_RETRY(getsockopt(fd,
512 IPPROTO_IP,
513 IP_MULTICAST_LOOP,
514 reinterpret_cast<char *>(&on),
515 &len));
516 if (err == 0) {
517 *enabled = on == 1;
518 }
519 return err == 0;
520 }
521
522
523 bool Socket::SetMulticastLoop(intptr_t fd, bool enabled) {
524 uint8_t on = enabled ? 1 : 0;
525 return TEMP_FAILURE_RETRY(setsockopt(fd,
526 IPPROTO_IP,
527 IP_MULTICAST_LOOP,
528 reinterpret_cast<char *>(&on),
529 sizeof(on))) == 0;
530 }
531
532
533 bool Socket::GetMulticastTTL(intptr_t fd, int* value) {
534 uint8_t v;
535 socklen_t len = sizeof(v);
536 int err = TEMP_FAILURE_RETRY(getsockopt(fd,
537 IPPROTO_IP,
538 IP_MULTICAST_TTL,
539 reinterpret_cast<char *>(&v),
540 &len));
541 if (err == 0) {
542 *value = v;
543 }
544 return err == 0;
545 }
546
547
548 bool Socket::SetMulticastTTL(intptr_t fd, int value) {
549 uint8_t v = value;
550 return TEMP_FAILURE_RETRY(setsockopt(fd,
551 IPPROTO_IP,
552 IP_MULTICAST_TTL,
553 reinterpret_cast<char *>(&v),
554 sizeof(v))) == 0;
555 }
556
557
558 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) {
559 int on;
560 socklen_t len = sizeof(on);
561 int err = TEMP_FAILURE_RETRY(getsockopt(fd,
562 SOL_SOCKET,
563 SO_BROADCAST,
564 reinterpret_cast<char *>(&on),
565 &len));
566 if (err == 0) {
567 *enabled = on == 1;
568 }
569 return err == 0;
570 }
571
572
573 bool Socket::SetBroadcast(intptr_t fd, bool enabled) {
574 int on = enabled ? 1 : 0;
575 return TEMP_FAILURE_RETRY(setsockopt(fd,
576 SOL_SOCKET,
577 SO_BROADCAST,
578 reinterpret_cast<char *>(&on),
579 sizeof(on))) == 0;
580 }
581
582
583 bool Socket::JoinMulticast(intptr_t fd, RawAddr* addr, int interfaceIndex) {
584 struct group_req mreq;
585 mreq.gr_interface = interfaceIndex;
586 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
587 return TEMP_FAILURE_RETRY(setsockopt(
588 fd, IPPROTO_IP, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
589 }
590
591
592 bool Socket::LeaveMulticast(intptr_t fd, RawAddr* addr, int interfaceIndex) {
593 struct group_req mreq;
594 mreq.gr_interface = interfaceIndex;
595 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr));
596 return TEMP_FAILURE_RETRY(setsockopt(
597 fd, IPPROTO_IP, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0;
598 }
599
421 } // namespace bin 600 } // namespace bin
422 } // namespace dart 601 } // namespace dart
423 602
424 #endif // defined(TARGET_OS_LINUX) 603 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/socket.cc ('k') | runtime/bin/socket_patch.dart » ('j') | sdk/lib/io/socket.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698