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

Side by Side Diff: runtime/bin/socket_common_linux.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) 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(TARGET_OS_LINUX) 8 #if defined(TARGET_OS_LINUX)
9 9
10 #include "bin/socket.h" 10 #include "bin/socket.h"
11 #include "bin/socket_linux.h" 11 #include "bin/socket_common_linux.h"
12 12
13 #include <errno.h> // NOLINT 13 #include <errno.h> // NOLINT
14 #include <ifaddrs.h> // NOLINT 14 #include <ifaddrs.h> // NOLINT
15 #include <net/if.h> // NOLINT 15 #include <net/if.h> // NOLINT
16 #include <netinet/tcp.h> // NOLINT 16 #include <netinet/tcp.h> // NOLINT
17 #include <stdio.h> // NOLINT 17 #include <stdio.h> // NOLINT
18 #include <stdlib.h> // NOLINT 18 #include <stdlib.h> // NOLINT
19 #include <string.h> // NOLINT 19 #include <string.h> // NOLINT
20 #include <sys/stat.h> // NOLINT 20 #include <sys/stat.h> // NOLINT
21 #include <unistd.h> // NOLINT 21 #include <unistd.h> // NOLINT
(...skipping 10 matching lines...) Expand all
32 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); 32 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
33 if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_, 33 if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_,
34 INET6_ADDRSTRLEN)) { 34 INET6_ADDRSTRLEN)) {
35 as_string_[0] = 0; 35 as_string_[0] = 0;
36 } 36 }
37 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); 37 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa));
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(const RawAddr& addr, char* address, int len) { 42 bool BaseSocket::FormatNumericAddress(const RawAddr& addr,
43 char* address,
44 int len) {
43 socklen_t salen = SocketAddress::GetAddrLength(addr); 45 socklen_t salen = SocketAddress::GetAddrLength(addr);
44 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, 46 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
45 0, NI_NUMERICHOST) == 0)); 47 0, NI_NUMERICHOST) == 0));
46 } 48 }
47 49
48 50
49 bool Socket::Initialize() { 51 bool BaseSocket::Initialize() {
50 // Nothing to do on Linux. 52 // Nothing to do on Linux.
51 return true; 53 return true;
52 } 54 }
53 55
54 56
55 static intptr_t Create(const RawAddr& addr) { 57 static intptr_t Create(const RawAddr& addr) {
56 intptr_t fd; 58 intptr_t fd;
57 fd = NO_RETRY_EXPECTED( 59 intptr_t type = SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC;
58 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); 60 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, type, 0));
59 if (fd < 0) { 61 if (fd < 0) {
60 return -1; 62 return -1;
61 } 63 }
62 return fd; 64 return fd;
63 } 65 }
64 66
65 67
66 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { 68 static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
67 intptr_t result = TEMP_FAILURE_RETRY( 69 intptr_t result = TEMP_FAILURE_RETRY(
68 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); 70 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr)));
(...skipping 25 matching lines...) Expand all
94 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); 96 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr)));
95 if ((result != 0) && (errno != EINPROGRESS)) { 97 if ((result != 0) && (errno != EINPROGRESS)) {
96 FDUtils::SaveErrorAndClose(fd); 98 FDUtils::SaveErrorAndClose(fd);
97 return -1; 99 return -1;
98 } 100 }
99 101
100 return Connect(fd, addr); 102 return Connect(fd, addr);
101 } 103 }
102 104
103 105
104 bool Socket::IsBindError(intptr_t error_number) { 106 bool BaseSocket::IsBindError(intptr_t error_number) {
105 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || 107 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
106 error_number == EINVAL; 108 error_number == EINVAL;
107 } 109 }
108 110
109 111
110 intptr_t Socket::Available(intptr_t fd) { 112 intptr_t BaseSocket::Available(intptr_t fd) {
111 return FDUtils::AvailableBytes(fd); 113 return FDUtils::AvailableBytes(fd);
112 } 114 }
113 115
114 116
115 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 117 intptr_t BaseSocket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
116 ASSERT(fd >= 0); 118 ASSERT(fd >= 0);
117 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); 119 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
118 ASSERT(EAGAIN == EWOULDBLOCK); 120 ASSERT(EAGAIN == EWOULDBLOCK);
119 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) { 121 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
120 // If the read would block we need to retry and therefore return 0 122 // If the read would block we need to retry and therefore return 0
121 // as the number of bytes written. 123 // as the number of bytes written.
122 read_bytes = 0; 124 read_bytes = 0;
123 } 125 }
124 return read_bytes; 126 return read_bytes;
125 } 127 }
126 128
127 129
128 intptr_t Socket::RecvFrom(intptr_t fd, 130 intptr_t BaseSocket::RecvFrom(intptr_t fd,
129 void* buffer, 131 void* buffer,
130 intptr_t num_bytes, 132 intptr_t num_bytes,
131 RawAddr* addr) { 133 RawAddr* addr) {
132 ASSERT(fd >= 0); 134 ASSERT(fd >= 0);
133 socklen_t addr_len = sizeof(addr->ss); 135 socklen_t addr_len = sizeof(addr->ss);
134 ssize_t read_bytes = TEMP_FAILURE_RETRY( 136 ssize_t read_bytes = TEMP_FAILURE_RETRY(
135 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); 137 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
136 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) { 138 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
137 // If the read would block we need to retry and therefore return 0 139 // If the read would block we need to retry and therefore return 0
138 // as the number of bytes written. 140 // as the number of bytes written.
139 read_bytes = 0; 141 read_bytes = 0;
140 } 142 }
141 return read_bytes; 143 return read_bytes;
142 } 144 }
143 145
144 146
145 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 147 intptr_t BaseSocket::Write(intptr_t fd,
148 const void* buffer,
149 intptr_t num_bytes) {
146 ASSERT(fd >= 0); 150 ASSERT(fd >= 0);
147 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); 151 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
148 ASSERT(EAGAIN == EWOULDBLOCK); 152 ASSERT(EAGAIN == EWOULDBLOCK);
149 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) { 153 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
150 // If the would block we need to retry and therefore return 0 as 154 // If the would block we need to retry and therefore return 0 as
151 // the number of bytes written. 155 // the number of bytes written.
152 written_bytes = 0; 156 written_bytes = 0;
153 } 157 }
154 return written_bytes; 158 return written_bytes;
155 } 159 }
156 160
157 161
158 intptr_t Socket::SendTo(intptr_t fd, 162 intptr_t BaseSocket::SendTo(intptr_t fd,
159 const void* buffer, 163 const void* buffer,
160 intptr_t num_bytes, 164 intptr_t num_bytes,
161 const RawAddr& addr) { 165 const RawAddr& addr) {
162 ASSERT(fd >= 0); 166 ASSERT(fd >= 0);
163 ssize_t written_bytes = 167 ssize_t written_bytes =
164 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, 168 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
165 SocketAddress::GetAddrLength(addr))); 169 SocketAddress::GetAddrLength(addr)));
166 ASSERT(EAGAIN == EWOULDBLOCK); 170 ASSERT(EAGAIN == EWOULDBLOCK);
167 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) { 171 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
168 // If the would block we need to retry and therefore return 0 as 172 // If the would block we need to retry and therefore return 0 as
169 // the number of bytes written. 173 // the number of bytes written.
170 written_bytes = 0; 174 written_bytes = 0;
171 } 175 }
172 return written_bytes; 176 return written_bytes;
173 } 177 }
174 178
175 179
176 intptr_t Socket::GetPort(intptr_t fd) { 180 intptr_t BaseSocket::GetPort(intptr_t fd) {
177 ASSERT(fd >= 0); 181 ASSERT(fd >= 0);
178 RawAddr raw; 182 RawAddr raw;
179 socklen_t size = sizeof(raw); 183 socklen_t size = sizeof(raw);
180 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { 184 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
181 return 0; 185 return 0;
182 } 186 }
183 return SocketAddress::GetAddrPort(raw); 187 return SocketAddress::GetAddrPort(raw);
184 } 188 }
185 189
186 190
187 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { 191 SocketAddress* BaseSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
188 ASSERT(fd >= 0); 192 ASSERT(fd >= 0);
189 RawAddr raw; 193 RawAddr raw;
190 socklen_t size = sizeof(raw); 194 socklen_t size = sizeof(raw);
191 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { 195 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
192 return NULL; 196 return NULL;
193 } 197 }
194 *port = SocketAddress::GetAddrPort(raw); 198 *port = SocketAddress::GetAddrPort(raw);
195 return new SocketAddress(&raw.addr); 199 return new SocketAddress(&raw.addr);
196 } 200 }
197 201
198 202
199 void Socket::GetError(intptr_t fd, OSError* os_error) { 203 void BaseSocket::GetError(intptr_t fd, OSError* os_error) {
200 int len = sizeof(errno); 204 int len = sizeof(errno);
201 int err = 0; 205 int err = 0;
202 VOID_NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, 206 VOID_NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_ERROR, &err,
203 reinterpret_cast<socklen_t*>(&len))); 207 reinterpret_cast<socklen_t*>(&len)));
204 errno = err; 208 errno = err;
205 os_error->SetCodeAndMessage(OSError::kSystem, errno); 209 os_error->SetCodeAndMessage(OSError::kSystem, errno);
206 } 210 }
207 211
208 212
209 int Socket::GetType(intptr_t fd) { 213 int BaseSocket::GetType(intptr_t fd) {
210 struct stat64 buf; 214 struct stat64 buf;
211 int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf)); 215 int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf));
212 if (result == -1) { 216 if (result == -1) {
213 return -1; 217 return -1;
214 } 218 }
215 if (S_ISCHR(buf.st_mode)) { 219 if (S_ISCHR(buf.st_mode)) {
216 return File::kTerminal; 220 return File::kTerminal;
217 } 221 }
218 if (S_ISFIFO(buf.st_mode)) { 222 if (S_ISFIFO(buf.st_mode)) {
219 return File::kPipe; 223 return File::kPipe;
220 } 224 }
221 if (S_ISREG(buf.st_mode)) { 225 if (S_ISREG(buf.st_mode)) {
222 return File::kFile; 226 return File::kFile;
223 } 227 }
224 return File::kOther; 228 return File::kOther;
225 } 229 }
226 230
227 231
228 intptr_t Socket::GetStdioHandle(intptr_t num) { 232 intptr_t BaseSocket::GetStdioHandle(intptr_t num) {
229 return num; 233 return num;
230 } 234 }
231 235
232 236
233 AddressList<SocketAddress>* Socket::LookupAddress(const char* host, 237 AddressList<SocketAddress>* BaseSocket::LookupAddress(const char* host,
234 int type, 238 int type,
235 OSError** os_error) { 239 OSError** os_error) {
236 // Perform a name lookup for a host name. 240 // Perform a name lookup for a host name.
237 struct addrinfo hints; 241 struct addrinfo hints;
238 memset(&hints, 0, sizeof(hints)); 242 memset(&hints, 0, sizeof(hints));
239 hints.ai_family = SocketAddress::FromType(type); 243 hints.ai_family = SocketAddress::FromType(type);
240 hints.ai_socktype = SOCK_STREAM; 244 hints.ai_socktype = SOCK_STREAM;
241 hints.ai_flags = AI_ADDRCONFIG; 245 hints.ai_flags = AI_ADDRCONFIG;
242 hints.ai_protocol = IPPROTO_TCP; 246 hints.ai_protocol = IPPROTO_TCP;
243 struct addrinfo* info = NULL; 247 struct addrinfo* info = NULL;
244 int status = NO_RETRY_EXPECTED(getaddrinfo(host, 0, &hints, &info)); 248 int status = NO_RETRY_EXPECTED(getaddrinfo(host, 0, &hints, &info));
245 if (status != 0) { 249 if (status != 0) {
(...skipping 20 matching lines...) Expand all
266 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { 270 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
267 addresses->SetAt(i, new SocketAddress(c->ai_addr)); 271 addresses->SetAt(i, new SocketAddress(c->ai_addr));
268 i++; 272 i++;
269 } 273 }
270 } 274 }
271 freeaddrinfo(info); 275 freeaddrinfo(info);
272 return addresses; 276 return addresses;
273 } 277 }
274 278
275 279
276 bool Socket::ReverseLookup(const RawAddr& addr, 280 bool BaseSocket::ReverseLookup(const RawAddr& addr,
277 char* host, 281 char* host,
278 intptr_t host_len, 282 intptr_t host_len,
279 OSError** os_error) { 283 OSError** os_error) {
280 ASSERT(host_len >= NI_MAXHOST); 284 ASSERT(host_len >= NI_MAXHOST);
281 int status = NO_RETRY_EXPECTED( 285 int status = NO_RETRY_EXPECTED(
282 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, 286 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
283 host_len, NULL, 0, NI_NAMEREQD)); 287 host_len, NULL, 0, NI_NAMEREQD));
284 if (status != 0) { 288 if (status != 0) {
285 ASSERT(*os_error == NULL); 289 ASSERT(*os_error == NULL);
286 *os_error = 290 *os_error =
287 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); 291 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
288 return false; 292 return false;
289 } 293 }
290 return true; 294 return true;
291 } 295 }
292 296
293 297
294 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { 298 bool BaseSocket::ParseAddress(int type, const char* address, RawAddr* addr) {
295 int result; 299 int result;
296 if (type == SocketAddress::TYPE_IPV4) { 300 if (type == SocketAddress::TYPE_IPV4) {
297 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); 301 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr));
298 } else { 302 } else {
299 ASSERT(type == SocketAddress::TYPE_IPV6); 303 ASSERT(type == SocketAddress::TYPE_IPV6);
300 result = 304 result =
301 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); 305 NO_RETRY_EXPECTED(inet_pton(AF_INET6, address, &addr->in6.sin6_addr));
302 } 306 }
303 return (result == 1); 307 return (result == 1);
304 } 308 }
(...skipping 29 matching lines...) Expand all
334 // OpenVPN's virtual device tun0. 338 // OpenVPN's virtual device tun0.
335 return false; 339 return false;
336 } 340 }
337 int family = ifa->ifa_addr->sa_family; 341 int family = ifa->ifa_addr->sa_family;
338 return ((lookup_family == family) || 342 return ((lookup_family == family) ||
339 (((lookup_family == AF_UNSPEC) && 343 (((lookup_family == AF_UNSPEC) &&
340 ((family == AF_INET) || (family == AF_INET6))))); 344 ((family == AF_INET) || (family == AF_INET6)))));
341 } 345 }
342 346
343 347
344 bool Socket::ListInterfacesSupported() { 348 bool BaseSocket::ListInterfacesSupported() {
345 return true; 349 return true;
346 } 350 }
347 351
348 352
349 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 353 AddressList<InterfaceSocketAddress>* BaseSocket::ListInterfaces(
350 int type, 354 int type,
351 OSError** os_error) { 355 OSError** os_error) {
352 struct ifaddrs* ifaddr; 356 struct ifaddrs* ifaddr;
353 357
354 int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr)); 358 int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr));
355 if (status != 0) { 359 if (status != 0) {
356 ASSERT(*os_error == NULL); 360 ASSERT(*os_error == NULL);
357 *os_error = 361 *os_error =
358 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); 362 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
359 return NULL; 363 return NULL;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } 471 }
468 if (!FDUtils::SetNonBlocking(socket)) { 472 if (!FDUtils::SetNonBlocking(socket)) {
469 FDUtils::SaveErrorAndClose(socket); 473 FDUtils::SaveErrorAndClose(socket);
470 return -1; 474 return -1;
471 } 475 }
472 } 476 }
473 return socket; 477 return socket;
474 } 478 }
475 479
476 480
477 void Socket::Close(intptr_t fd) { 481 void BaseSocket::Close(intptr_t fd) {
478 ASSERT(fd >= 0); 482 ASSERT(fd >= 0);
479 VOID_TEMP_FAILURE_RETRY(close(fd)); 483 VOID_TEMP_FAILURE_RETRY(close(fd));
480 } 484 }
481 485
482 486
483 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 487 bool BaseSocket::GetNoDelay(intptr_t fd, bool* enabled) {
484 int on; 488 int on;
485 socklen_t len = sizeof(on); 489 socklen_t len = sizeof(on);
486 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 490 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
487 reinterpret_cast<void*>(&on), &len)); 491 reinterpret_cast<void*>(&on), &len));
488 if (err == 0) { 492 if (err == 0) {
489 *enabled = (on == 1); 493 *enabled = (on == 1);
490 } 494 }
491 return (err == 0); 495 return (err == 0);
492 } 496 }
493 497
494 498
495 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 499 bool BaseSocket::SetNoDelay(intptr_t fd, bool enabled) {
496 int on = enabled ? 1 : 0; 500 int on = enabled ? 1 : 0;
497 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 501 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
498 reinterpret_cast<char*>(&on), 502 reinterpret_cast<char*>(&on),
499 sizeof(on))) == 0; 503 sizeof(on))) == 0;
500 } 504 }
501 505
502 506
503 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 507 bool BaseSocket::GetMulticastLoop(intptr_t fd,
508 intptr_t protocol,
509 bool* enabled) {
504 uint8_t on; 510 uint8_t on;
505 socklen_t len = sizeof(on); 511 socklen_t len = sizeof(on);
506 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 512 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
507 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 513 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
508 : IPV6_MULTICAST_LOOP; 514 : IPV6_MULTICAST_LOOP;
509 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, 515 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
510 reinterpret_cast<char*>(&on), &len)) == 0) { 516 reinterpret_cast<char*>(&on), &len)) == 0) {
511 *enabled = (on == 1); 517 *enabled = (on == 1);
512 return true; 518 return true;
513 } 519 }
514 return false; 520 return false;
515 } 521 }
516 522
517 523
518 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 524 bool BaseSocket::SetMulticastLoop(intptr_t fd,
525 intptr_t protocol,
526 bool enabled) {
519 int on = enabled ? 1 : 0; 527 int on = enabled ? 1 : 0;
520 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 528 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
521 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 529 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
522 : IPV6_MULTICAST_LOOP; 530 : IPV6_MULTICAST_LOOP;
523 return NO_RETRY_EXPECTED(setsockopt( 531 return NO_RETRY_EXPECTED(setsockopt(
524 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == 532 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) ==
525 0; 533 0;
526 } 534 }
527 535
528 536
529 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 537 bool BaseSocket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
530 uint8_t v; 538 uint8_t v;
531 socklen_t len = sizeof(v); 539 socklen_t len = sizeof(v);
532 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 540 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
533 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 541 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
534 : IPV6_MULTICAST_HOPS; 542 : IPV6_MULTICAST_HOPS;
535 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, 543 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
536 reinterpret_cast<char*>(&v), &len)) == 0) { 544 reinterpret_cast<char*>(&v), &len)) == 0) {
537 *value = v; 545 *value = v;
538 return true; 546 return true;
539 } 547 }
540 return false; 548 return false;
541 } 549 }
542 550
543 551
544 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 552 bool BaseSocket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
545 int v = value; 553 int v = value;
546 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 554 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
547 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 555 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
548 : IPV6_MULTICAST_HOPS; 556 : IPV6_MULTICAST_HOPS;
549 return NO_RETRY_EXPECTED(setsockopt( 557 return NO_RETRY_EXPECTED(setsockopt(
550 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; 558 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0;
551 } 559 }
552 560
553 561
554 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 562 bool BaseSocket::GetBroadcast(intptr_t fd, bool* enabled) {
555 int on; 563 int on;
556 socklen_t len = sizeof(on); 564 socklen_t len = sizeof(on);
557 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, 565 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST,
558 reinterpret_cast<char*>(&on), &len)); 566 reinterpret_cast<char*>(&on), &len));
559 if (err == 0) { 567 if (err == 0) {
560 *enabled = (on == 1); 568 *enabled = (on == 1);
561 } 569 }
562 return (err == 0); 570 return (err == 0);
563 } 571 }
564 572
565 573
566 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 574 bool BaseSocket::SetBroadcast(intptr_t fd, bool enabled) {
567 int on = enabled ? 1 : 0; 575 int on = enabled ? 1 : 0;
568 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, 576 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
569 reinterpret_cast<char*>(&on), 577 reinterpret_cast<char*>(&on),
570 sizeof(on))) == 0; 578 sizeof(on))) == 0;
571 } 579 }
572 580
573 581
574 bool Socket::JoinMulticast(intptr_t fd, 582 bool BaseSocket::JoinMulticast(intptr_t fd,
575 const RawAddr& addr, 583 const RawAddr& addr,
576 const RawAddr&, 584 const RawAddr&,
577 int interfaceIndex) { 585 int interfaceIndex) {
578 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 586 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
579 struct group_req mreq; 587 struct group_req mreq;
580 mreq.gr_interface = interfaceIndex; 588 mreq.gr_interface = interfaceIndex;
581 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); 589 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
582 return NO_RETRY_EXPECTED( 590 return NO_RETRY_EXPECTED(
583 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; 591 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0;
584 } 592 }
585 593
586 594
587 bool Socket::LeaveMulticast(intptr_t fd, 595 bool BaseSocket::LeaveMulticast(intptr_t fd,
588 const RawAddr& addr, 596 const RawAddr& addr,
589 const RawAddr&, 597 const RawAddr&,
590 int interfaceIndex) { 598 int interfaceIndex) {
591 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 599 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
592 struct group_req mreq; 600 struct group_req mreq;
593 mreq.gr_interface = interfaceIndex; 601 mreq.gr_interface = interfaceIndex;
594 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); 602 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr));
595 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, 603 return NO_RETRY_EXPECTED(setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq,
596 sizeof(mreq))) == 0; 604 sizeof(mreq))) == 0;
597 } 605 }
598 606
599 } // namespace bin 607 } // namespace bin
600 } // namespace dart 608 } // namespace dart
601 609
602 #endif // defined(TARGET_OS_LINUX) 610 #endif // defined(TARGET_OS_LINUX)
603 611
604 #endif // !defined(DART_IO_DISABLED) 612 #endif // !defined(DART_IO_DISABLED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698