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

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

Issue 2797993005: Re-land socket refactor with fixes for Windows. (Closed)
Patch Set: Rebased + reverted original revert 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
« no previous file with comments | « runtime/bin/socket_base_macos.h ('k') | runtime/bin/socket_base_unsupported.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) 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(HOST_OS_MACOS) 8 #if defined(HOST_OS_MACOS)
9 9
10 #include "bin/socket.h" 10 #include "bin/socket_base.h"
11 #include "bin/socket_macos.h"
12 11
13 #include <errno.h> // NOLINT 12 #include <errno.h> // NOLINT
14 #include <ifaddrs.h> // NOLINT 13 #include <ifaddrs.h> // NOLINT
15 #include <net/if.h> // NOLINT 14 #include <net/if.h> // NOLINT
16 #include <netinet/tcp.h> // NOLINT 15 #include <netinet/tcp.h> // NOLINT
17 #include <stdio.h> // NOLINT 16 #include <stdio.h> // NOLINT
18 #include <stdlib.h> // NOLINT 17 #include <stdlib.h> // NOLINT
19 #include <string.h> // NOLINT 18 #include <string.h> // NOLINT
20 #include <sys/stat.h> // NOLINT 19 #include <sys/stat.h> // NOLINT
21 #include <unistd.h> // NOLINT 20 #include <unistd.h> // NOLINT
22 21
23 #include "bin/fdutils.h" 22 #include "bin/fdutils.h"
24 #include "bin/file.h" 23 #include "bin/file.h"
24 #include "bin/socket_base_macos.h"
25 #include "platform/signal_blocker.h" 25 #include "platform/signal_blocker.h"
26 26
27 namespace dart { 27 namespace dart {
28 namespace bin { 28 namespace bin {
29 29
30 SocketAddress::SocketAddress(struct sockaddr* sa) { 30 SocketAddress::SocketAddress(struct sockaddr* sa) {
31 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN); 31 ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
32 if (!Socket::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), as_string_, 32 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa),
33 INET6_ADDRSTRLEN)) { 33 as_string_, INET6_ADDRSTRLEN)) {
34 as_string_[0] = 0; 34 as_string_[0] = 0;
35 } 35 }
36 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa)); 36 socklen_t salen = GetAddrLength(*reinterpret_cast<RawAddr*>(sa));
37 memmove(reinterpret_cast<void*>(&addr_), sa, salen); 37 memmove(reinterpret_cast<void*>(&addr_), sa, salen);
38 } 38 }
39 39
40 40
41 bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) { 41 bool SocketBase::Initialize() {
42 // Nothing to do on Mac OS.
43 return true;
44 }
45
46
47 bool SocketBase::FormatNumericAddress(const RawAddr& addr,
48 char* address,
49 int len) {
42 socklen_t salen = SocketAddress::GetAddrLength(addr); 50 socklen_t salen = SocketAddress::GetAddrLength(addr);
43 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, 51 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL,
44 0, NI_NUMERICHOST)) == 0); 52 0, NI_NUMERICHOST)) == 0);
45 } 53 }
46 54
47 55
48 Socket::Socket(intptr_t fd) 56 bool SocketBase::IsBindError(intptr_t error_number) {
49 : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {}
50
51
52 void Socket::SetClosedFd() {
53 fd_ = kClosedFd;
54 }
55
56
57 bool Socket::Initialize() {
58 // Nothing to do on Mac OS.
59 return true;
60 }
61
62
63 static intptr_t Create(const RawAddr& addr) {
64 intptr_t fd;
65 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0));
66 if (fd < 0) {
67 return -1;
68 }
69 if (!FDUtils::SetCloseOnExec(fd)) {
70 FDUtils::SaveErrorAndClose(fd);
71 return -1;
72 }
73 if (!FDUtils::SetNonBlocking(fd)) {
74 FDUtils::SaveErrorAndClose(fd);
75 return -1;
76 }
77 return fd;
78 }
79
80
81 static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
82 intptr_t result = TEMP_FAILURE_RETRY(
83 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr)));
84 if ((result == 0) || (errno == EINPROGRESS)) {
85 return fd;
86 }
87 FDUtils::SaveErrorAndClose(fd);
88 return -1;
89 }
90
91
92 intptr_t Socket::CreateConnect(const RawAddr& addr) {
93 intptr_t fd = Create(addr);
94 if (fd < 0) {
95 return fd;
96 }
97
98 return Connect(fd, addr);
99 }
100
101
102 intptr_t Socket::CreateBindConnect(const RawAddr& addr,
103 const RawAddr& source_addr) {
104 intptr_t fd = Create(addr);
105 if (fd < 0) {
106 return fd;
107 }
108
109 intptr_t result = TEMP_FAILURE_RETRY(
110 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr)));
111 if ((result != 0) && (errno != EINPROGRESS)) {
112 FDUtils::SaveErrorAndClose(fd);
113 return -1;
114 }
115
116 return Connect(fd, addr);
117 }
118
119
120 bool Socket::IsBindError(intptr_t error_number) {
121 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || 57 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL ||
122 error_number == EINVAL; 58 error_number == EINVAL;
123 } 59 }
124 60
125 61
126 intptr_t Socket::Available(intptr_t fd) { 62 intptr_t SocketBase::Available(intptr_t fd) {
127 return FDUtils::AvailableBytes(fd); 63 return FDUtils::AvailableBytes(fd);
128 } 64 }
129 65
130 66
131 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { 67 intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
132 ASSERT(fd >= 0); 68 ASSERT(fd >= 0);
133 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); 69 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
134 ASSERT(EAGAIN == EWOULDBLOCK); 70 ASSERT(EAGAIN == EWOULDBLOCK);
135 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) { 71 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
136 // If the read would block we need to retry and therefore return 0 72 // If the read would block we need to retry and therefore return 0
137 // as the number of bytes written. 73 // as the number of bytes written.
138 read_bytes = 0; 74 read_bytes = 0;
139 } 75 }
140 return read_bytes; 76 return read_bytes;
141 } 77 }
142 78
143 79
144 intptr_t Socket::RecvFrom(intptr_t fd, 80 intptr_t SocketBase::RecvFrom(intptr_t fd,
145 void* buffer, 81 void* buffer,
146 intptr_t num_bytes, 82 intptr_t num_bytes,
147 RawAddr* addr) { 83 RawAddr* addr) {
148 ASSERT(fd >= 0); 84 ASSERT(fd >= 0);
149 socklen_t addr_len = sizeof(addr->ss); 85 socklen_t addr_len = sizeof(addr->ss);
150 ssize_t read_bytes = TEMP_FAILURE_RETRY( 86 ssize_t read_bytes = TEMP_FAILURE_RETRY(
151 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); 87 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
152 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) { 88 if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
153 // If the read would block we need to retry and therefore return 0 89 // If the read would block we need to retry and therefore return 0
154 // as the number of bytes written. 90 // as the number of bytes written.
155 read_bytes = 0; 91 read_bytes = 0;
156 } 92 }
157 return read_bytes; 93 return read_bytes;
158 } 94 }
159 95
160 96
161 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { 97 intptr_t SocketBase::Write(intptr_t fd,
98 const void* buffer,
99 intptr_t num_bytes) {
162 ASSERT(fd >= 0); 100 ASSERT(fd >= 0);
163 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); 101 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
164 ASSERT(EAGAIN == EWOULDBLOCK); 102 ASSERT(EAGAIN == EWOULDBLOCK);
165 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) { 103 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
166 // If the would block we need to retry and therefore return 0 as 104 // If the would block we need to retry and therefore return 0 as
167 // the number of bytes written. 105 // the number of bytes written.
168 written_bytes = 0; 106 written_bytes = 0;
169 } 107 }
170 return written_bytes; 108 return written_bytes;
171 } 109 }
172 110
173 111
174 intptr_t Socket::SendTo(intptr_t fd, 112 intptr_t SocketBase::SendTo(intptr_t fd,
175 const void* buffer, 113 const void* buffer,
176 intptr_t num_bytes, 114 intptr_t num_bytes,
177 const RawAddr& addr) { 115 const RawAddr& addr) {
178 ASSERT(fd >= 0); 116 ASSERT(fd >= 0);
179 ssize_t written_bytes = 117 ssize_t written_bytes =
180 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, 118 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
181 SocketAddress::GetAddrLength(addr))); 119 SocketAddress::GetAddrLength(addr)));
182 ASSERT(EAGAIN == EWOULDBLOCK); 120 ASSERT(EAGAIN == EWOULDBLOCK);
183 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) { 121 if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
184 // If the would block we need to retry and therefore return 0 as 122 // If the would block we need to retry and therefore return 0 as
185 // the number of bytes written. 123 // the number of bytes written.
186 written_bytes = 0; 124 written_bytes = 0;
187 } 125 }
188 return written_bytes; 126 return written_bytes;
189 } 127 }
190 128
191 129
192 intptr_t Socket::GetPort(intptr_t fd) { 130 intptr_t SocketBase::GetPort(intptr_t fd) {
193 ASSERT(fd >= 0); 131 ASSERT(fd >= 0);
194 RawAddr raw; 132 RawAddr raw;
195 socklen_t size = sizeof(raw); 133 socklen_t size = sizeof(raw);
196 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { 134 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) {
197 return 0; 135 return 0;
198 } 136 }
199 return SocketAddress::GetAddrPort(raw); 137 return SocketAddress::GetAddrPort(raw);
200 } 138 }
201 139
202 140
203 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { 141 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) {
204 ASSERT(fd >= 0); 142 ASSERT(fd >= 0);
205 RawAddr raw; 143 RawAddr raw;
206 socklen_t size = sizeof(raw); 144 socklen_t size = sizeof(raw);
207 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { 145 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) {
208 return NULL; 146 return NULL;
209 } 147 }
210 *port = SocketAddress::GetAddrPort(raw); 148 *port = SocketAddress::GetAddrPort(raw);
211 return new SocketAddress(&raw.addr); 149 return new SocketAddress(&raw.addr);
212 } 150 }
213 151
214 152
215 void Socket::GetError(intptr_t fd, OSError* os_error) { 153 void SocketBase::GetError(intptr_t fd, OSError* os_error) {
216 int len = sizeof(errno); 154 int len = sizeof(errno);
217 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, 155 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno,
218 reinterpret_cast<socklen_t*>(&len)); 156 reinterpret_cast<socklen_t*>(&len));
219 os_error->SetCodeAndMessage(OSError::kSystem, errno); 157 os_error->SetCodeAndMessage(OSError::kSystem, errno);
220 } 158 }
221 159
222 160
223 int Socket::GetType(intptr_t fd) { 161 int SocketBase::GetType(intptr_t fd) {
224 struct stat buf; 162 struct stat buf;
225 int result = fstat(fd, &buf); 163 int result = fstat(fd, &buf);
226 if (result == -1) { 164 if (result == -1) {
227 return -1; 165 return -1;
228 } 166 }
229 if (S_ISCHR(buf.st_mode)) { 167 if (S_ISCHR(buf.st_mode)) {
230 return File::kTerminal; 168 return File::kTerminal;
231 } 169 }
232 if (S_ISFIFO(buf.st_mode)) { 170 if (S_ISFIFO(buf.st_mode)) {
233 return File::kPipe; 171 return File::kPipe;
234 } 172 }
235 if (S_ISREG(buf.st_mode)) { 173 if (S_ISREG(buf.st_mode)) {
236 return File::kFile; 174 return File::kFile;
237 } 175 }
238 return File::kOther; 176 return File::kOther;
239 } 177 }
240 178
241 179
242 intptr_t Socket::GetStdioHandle(intptr_t num) { 180 intptr_t SocketBase::GetStdioHandle(intptr_t num) {
243 return num; 181 return num;
244 } 182 }
245 183
246 184
247 AddressList<SocketAddress>* Socket::LookupAddress(const char* host, 185 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host,
248 int type, 186 int type,
249 OSError** os_error) { 187 OSError** os_error) {
250 // Perform a name lookup for a host name. 188 // Perform a name lookup for a host name.
251 struct addrinfo hints; 189 struct addrinfo hints;
252 memset(&hints, 0, sizeof(hints)); 190 memset(&hints, 0, sizeof(hints));
253 hints.ai_family = SocketAddress::FromType(type); 191 hints.ai_family = SocketAddress::FromType(type);
254 hints.ai_socktype = SOCK_STREAM; 192 hints.ai_socktype = SOCK_STREAM;
255 hints.ai_flags = 0; 193 hints.ai_flags = 0;
256 hints.ai_protocol = IPPROTO_TCP; 194 hints.ai_protocol = IPPROTO_TCP;
257 struct addrinfo* info = NULL; 195 struct addrinfo* info = NULL;
258 int status = getaddrinfo(host, 0, &hints, &info); 196 int status = getaddrinfo(host, 0, &hints, &info);
259 if (status != 0) { 197 if (status != 0) {
(...skipping 14 matching lines...) Expand all
274 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { 212 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) {
275 addresses->SetAt(i, new SocketAddress(c->ai_addr)); 213 addresses->SetAt(i, new SocketAddress(c->ai_addr));
276 i++; 214 i++;
277 } 215 }
278 } 216 }
279 freeaddrinfo(info); 217 freeaddrinfo(info);
280 return addresses; 218 return addresses;
281 } 219 }
282 220
283 221
284 bool Socket::ReverseLookup(const RawAddr& addr, 222 bool SocketBase::ReverseLookup(const RawAddr& addr,
285 char* host, 223 char* host,
286 intptr_t host_len, 224 intptr_t host_len,
287 OSError** os_error) { 225 OSError** os_error) {
288 ASSERT(host_len >= NI_MAXHOST); 226 ASSERT(host_len >= NI_MAXHOST);
289 int status = NO_RETRY_EXPECTED( 227 int status = NO_RETRY_EXPECTED(
290 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, 228 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host,
291 host_len, NULL, 0, NI_NAMEREQD)); 229 host_len, NULL, 0, NI_NAMEREQD));
292 if (status != 0) { 230 if (status != 0) {
293 ASSERT(*os_error == NULL); 231 ASSERT(*os_error == NULL);
294 *os_error = 232 *os_error =
295 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); 233 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
296 return false; 234 return false;
297 } 235 }
298 return true; 236 return true;
299 } 237 }
300 238
301 239
302 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { 240 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
303 int result; 241 int result;
304 if (type == SocketAddress::TYPE_IPV4) { 242 if (type == SocketAddress::TYPE_IPV4) {
305 result = inet_pton(AF_INET, address, &addr->in.sin_addr); 243 result = inet_pton(AF_INET, address, &addr->in.sin_addr);
306 } else { 244 } else {
307 ASSERT(type == SocketAddress::TYPE_IPV6); 245 ASSERT(type == SocketAddress::TYPE_IPV6);
308 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); 246 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr);
309 } 247 }
310 return (result == 1); 248 return (result == 1);
311 } 249 }
312 250
313 251
314 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) {
315 intptr_t fd;
316
317 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, SOCK_DGRAM, IPPROTO_UDP));
318 if (fd < 0) {
319 return -1;
320 }
321
322 if (!FDUtils::SetCloseOnExec(fd)) {
323 FDUtils::SaveErrorAndClose(fd);
324 return -1;
325 }
326
327 if (reuseAddress) {
328 int optval = 1;
329 VOID_NO_RETRY_EXPECTED(
330 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
331 }
332
333 if (NO_RETRY_EXPECTED(
334 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) {
335 FDUtils::SaveErrorAndClose(fd);
336 return -1;
337 }
338
339 if (!FDUtils::SetNonBlocking(fd)) {
340 FDUtils::SaveErrorAndClose(fd);
341 return -1;
342 }
343 return fd;
344 }
345
346
347 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { 252 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
348 if (ifa->ifa_addr == NULL) { 253 if (ifa->ifa_addr == NULL) {
349 // OpenVPN's virtual device tun0. 254 // OpenVPN's virtual device tun0.
350 return false; 255 return false;
351 } 256 }
352 int family = ifa->ifa_addr->sa_family; 257 int family = ifa->ifa_addr->sa_family;
353 return ((lookup_family == family) || 258 return ((lookup_family == family) ||
354 ((lookup_family == AF_UNSPEC) && 259 ((lookup_family == AF_UNSPEC) &&
355 ((family == AF_INET) || (family == AF_INET6)))); 260 ((family == AF_INET) || (family == AF_INET6))));
356 } 261 }
357 262
358 263
359 bool Socket::ListInterfacesSupported() { 264 bool SocketBase::ListInterfacesSupported() {
360 return true; 265 return true;
361 } 266 }
362 267
363 268
364 AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( 269 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
365 int type, 270 int type,
366 OSError** os_error) { 271 OSError** os_error) {
367 struct ifaddrs* ifaddr; 272 struct ifaddrs* ifaddr;
368 273
369 int status = getifaddrs(&ifaddr); 274 int status = getifaddrs(&ifaddr);
370 if (status != 0) { 275 if (status != 0) {
371 ASSERT(*os_error == NULL); 276 ASSERT(*os_error == NULL);
372 *os_error = 277 *os_error =
373 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); 278 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
374 return NULL; 279 return NULL;
(...skipping 18 matching lines...) Expand all
393 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, 298 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name,
394 if_nametoindex(ifa->ifa_name))); 299 if_nametoindex(ifa->ifa_name)));
395 i++; 300 i++;
396 } 301 }
397 } 302 }
398 freeifaddrs(ifaddr); 303 freeifaddrs(ifaddr);
399 return addresses; 304 return addresses;
400 } 305 }
401 306
402 307
403 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, 308 void SocketBase::Close(intptr_t fd) {
404 intptr_t backlog,
405 bool v6_only) {
406 intptr_t fd;
407
408 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0));
409 if (fd < 0) {
410 return -1;
411 }
412
413 if (!FDUtils::SetCloseOnExec(fd)) {
414 FDUtils::SaveErrorAndClose(fd);
415 return -1;
416 }
417
418 int optval = 1;
419 VOID_NO_RETRY_EXPECTED(
420 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
421
422 if (addr.ss.ss_family == AF_INET6) {
423 optval = v6_only ? 1 : 0;
424 VOID_NO_RETRY_EXPECTED(
425 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)));
426 }
427
428 if (NO_RETRY_EXPECTED(
429 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) {
430 FDUtils::SaveErrorAndClose(fd);
431 return -1;
432 }
433
434 // Test for invalid socket port 65535 (some browsers disallow it).
435 if ((SocketAddress::GetAddrPort(addr) == 0) &&
436 (Socket::GetPort(fd) == 65535)) {
437 // Don't close the socket until we have created a new socket, ensuring
438 // that we do not get the bad port number again.
439 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only);
440 FDUtils::SaveErrorAndClose(fd);
441 return new_fd;
442 }
443
444 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
445 FDUtils::SaveErrorAndClose(fd);
446 return -1;
447 }
448
449 if (!FDUtils::SetNonBlocking(fd)) {
450 FDUtils::SaveErrorAndClose(fd);
451 return -1;
452 }
453 return fd;
454 }
455
456
457 bool ServerSocket::StartAccept(intptr_t fd) {
458 USE(fd);
459 return true;
460 }
461
462
463 intptr_t ServerSocket::Accept(intptr_t fd) {
464 intptr_t socket;
465 struct sockaddr clientaddr;
466 socklen_t addrlen = sizeof(clientaddr);
467 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen));
468 if (socket == -1) {
469 if (errno == EAGAIN) {
470 // We need to signal to the caller that this is actually not an
471 // error. We got woken up from the poll on the listening socket,
472 // but there is no connection ready to be accepted.
473 ASSERT(kTemporaryFailure != -1);
474 socket = kTemporaryFailure;
475 }
476 } else {
477 if (!FDUtils::SetCloseOnExec(socket)) {
478 FDUtils::SaveErrorAndClose(socket);
479 return -1;
480 }
481 if (!FDUtils::SetNonBlocking(socket)) {
482 FDUtils::SaveErrorAndClose(socket);
483 return -1;
484 }
485 }
486 return socket;
487 }
488
489
490 void Socket::Close(intptr_t fd) {
491 ASSERT(fd >= 0); 309 ASSERT(fd >= 0);
492 VOID_TEMP_FAILURE_RETRY(close(fd)); 310 VOID_TEMP_FAILURE_RETRY(close(fd));
493 } 311 }
494 312
495 313
496 bool Socket::GetNoDelay(intptr_t fd, bool* enabled) { 314 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) {
497 int on; 315 int on;
498 socklen_t len = sizeof(on); 316 socklen_t len = sizeof(on);
499 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 317 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
500 reinterpret_cast<void*>(&on), &len)); 318 reinterpret_cast<void*>(&on), &len));
501 if (err == 0) { 319 if (err == 0) {
502 *enabled = (on == 1); 320 *enabled = (on == 1);
503 } 321 }
504 return (err == 0); 322 return (err == 0);
505 } 323 }
506 324
507 325
508 bool Socket::SetNoDelay(intptr_t fd, bool enabled) { 326 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) {
509 int on = enabled ? 1 : 0; 327 int on = enabled ? 1 : 0;
510 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 328 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
511 reinterpret_cast<char*>(&on), 329 reinterpret_cast<char*>(&on),
512 sizeof(on))) == 0; 330 sizeof(on))) == 0;
513 } 331 }
514 332
515 333
516 bool Socket::GetMulticastLoop(intptr_t fd, intptr_t protocol, bool* enabled) { 334 bool SocketBase::GetMulticastLoop(intptr_t fd,
335 intptr_t protocol,
336 bool* enabled) {
517 uint8_t on; 337 uint8_t on;
518 socklen_t len = sizeof(on); 338 socklen_t len = sizeof(on);
519 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 339 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
520 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 340 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
521 : IPV6_MULTICAST_LOOP; 341 : IPV6_MULTICAST_LOOP;
522 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, 342 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
523 reinterpret_cast<char*>(&on), &len)) == 0) { 343 reinterpret_cast<char*>(&on), &len)) == 0) {
524 *enabled = (on == 1); 344 *enabled = (on == 1);
525 return true; 345 return true;
526 } 346 }
527 return false; 347 return false;
528 } 348 }
529 349
530 350
531 bool Socket::SetMulticastLoop(intptr_t fd, intptr_t protocol, bool enabled) { 351 bool SocketBase::SetMulticastLoop(intptr_t fd,
352 intptr_t protocol,
353 bool enabled) {
532 u_int on = enabled ? 1 : 0; 354 u_int on = enabled ? 1 : 0;
533 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 355 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
534 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP 356 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP
535 : IPV6_MULTICAST_LOOP; 357 : IPV6_MULTICAST_LOOP;
536 return NO_RETRY_EXPECTED(setsockopt( 358 return NO_RETRY_EXPECTED(setsockopt(
537 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == 359 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) ==
538 0; 360 0;
539 } 361 }
540 362
541 363
542 bool Socket::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { 364 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) {
543 uint8_t v; 365 uint8_t v;
544 socklen_t len = sizeof(v); 366 socklen_t len = sizeof(v);
545 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 367 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
546 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 368 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
547 : IPV6_MULTICAST_HOPS; 369 : IPV6_MULTICAST_HOPS;
548 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, 370 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname,
549 reinterpret_cast<char*>(&v), &len)) == 0) { 371 reinterpret_cast<char*>(&v), &len)) == 0) {
550 *value = v; 372 *value = v;
551 return true; 373 return true;
552 } 374 }
553 return false; 375 return false;
554 } 376 }
555 377
556 378
557 bool Socket::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { 379 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) {
558 int v = value; 380 int v = value;
559 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; 381 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6;
560 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL 382 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL
561 : IPV6_MULTICAST_HOPS; 383 : IPV6_MULTICAST_HOPS;
562 return NO_RETRY_EXPECTED(setsockopt( 384 return NO_RETRY_EXPECTED(setsockopt(
563 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; 385 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0;
564 } 386 }
565 387
566 388
567 bool Socket::GetBroadcast(intptr_t fd, bool* enabled) { 389 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) {
568 int on; 390 int on;
569 socklen_t len = sizeof(on); 391 socklen_t len = sizeof(on);
570 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, 392 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST,
571 reinterpret_cast<char*>(&on), &len)); 393 reinterpret_cast<char*>(&on), &len));
572 if (err == 0) { 394 if (err == 0) {
573 *enabled = (on == 1); 395 *enabled = (on == 1);
574 } 396 }
575 return (err == 0); 397 return (err == 0);
576 } 398 }
577 399
578 400
579 bool Socket::SetBroadcast(intptr_t fd, bool enabled) { 401 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) {
580 int on = enabled ? 1 : 0; 402 int on = enabled ? 1 : 0;
581 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, 403 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
582 reinterpret_cast<char*>(&on), 404 reinterpret_cast<char*>(&on),
583 sizeof(on))) == 0; 405 sizeof(on))) == 0;
584 } 406 }
585 407
586 408
587 static bool JoinOrLeaveMulticast(intptr_t fd, 409 static bool JoinOrLeaveMulticast(intptr_t fd,
588 const RawAddr& addr, 410 const RawAddr& addr,
589 const RawAddr& interface, 411 const RawAddr& interface,
(...skipping 22 matching lines...) Expand all
612 if (join) { 434 if (join) {
613 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, 435 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
614 &mreq, sizeof(mreq))) == 0; 436 &mreq, sizeof(mreq))) == 0;
615 } else { 437 } else {
616 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, 438 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
617 &mreq, sizeof(mreq))) == 0; 439 &mreq, sizeof(mreq))) == 0;
618 } 440 }
619 } 441 }
620 } 442 }
621 443
622 bool Socket::JoinMulticast(intptr_t fd, 444 bool SocketBase::JoinMulticast(intptr_t fd,
623 const RawAddr& addr, 445 const RawAddr& addr,
624 const RawAddr& interface, 446 const RawAddr& interface,
625 int interfaceIndex) { 447 int interfaceIndex) {
626 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); 448 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true);
627 } 449 }
628 450
629 451
630 bool Socket::LeaveMulticast(intptr_t fd, 452 bool SocketBase::LeaveMulticast(intptr_t fd,
631 const RawAddr& addr, 453 const RawAddr& addr,
632 const RawAddr& interface, 454 const RawAddr& interface,
633 int interfaceIndex) { 455 int interfaceIndex) {
634 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); 456 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false);
635 } 457 }
636 458
637 } // namespace bin 459 } // namespace bin
638 } // namespace dart 460 } // namespace dart
639 461
640 #endif // defined(HOST_OS_MACOS) 462 #endif // defined(HOST_OS_MACOS)
641 463
642 #endif // !defined(DART_IO_DISABLED) 464 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/socket_base_macos.h ('k') | runtime/bin/socket_base_unsupported.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698