| OLD | NEW |
| 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_MACOS) | 6 #if defined(TARGET_OS_MACOS) |
| 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 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 #include "platform/signal_blocker.h" | 22 #include "platform/signal_blocker.h" |
| 23 | 23 |
| 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( | 30 if (!Socket::FormatNumericAddress( |
| 31 reinterpret_cast<RawAddr*>(sa), as_string_, INET6_ADDRSTRLEN)) { | 31 *reinterpret_cast<RawAddr*>(sa), 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(RawAddr* addr, char* address, int len) { | 39 bool Socket::FormatNumericAddress(const RawAddr& addr, char* address, int len) { |
| 40 socklen_t salen = SocketAddress::GetAddrLength(addr); | 40 socklen_t salen = SocketAddress::GetAddrLength(addr); |
| 41 if (NO_RETRY_EXPECTED(getnameinfo(&addr->addr, | 41 if (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, |
| 42 salen, | 42 salen, |
| 43 address, | 43 address, |
| 44 len, | 44 len, |
| 45 NULL, | 45 NULL, |
| 46 0, | 46 0, |
| 47 NI_NUMERICHOST)) != 0) { | 47 NI_NUMERICHOST)) != 0) { |
| 48 return false; | 48 return false; |
| 49 } | 49 } |
| 50 return true; | 50 return true; |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 bool Socket::Initialize() { | 54 bool Socket::Initialize() { |
| 55 // Nothing to do on Mac OS. | 55 // Nothing to do on Mac OS. |
| 56 return true; | 56 return true; |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 static intptr_t Create(RawAddr addr) { | 60 static intptr_t Create(const RawAddr& addr) { |
| 61 intptr_t fd; | 61 intptr_t fd; |
| 62 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0)); | 62 fd = NO_RETRY_EXPECTED(socket(addr.ss.ss_family, SOCK_STREAM, 0)); |
| 63 if (fd < 0) { | 63 if (fd < 0) { |
| 64 return -1; | 64 return -1; |
| 65 } | 65 } |
| 66 FDUtils::SetCloseOnExec(fd); | 66 FDUtils::SetCloseOnExec(fd); |
| 67 return fd; | 67 return fd; |
| 68 } | 68 } |
| 69 | 69 |
| 70 | 70 |
| 71 static intptr_t Connect(intptr_t fd, RawAddr addr, const intptr_t port) { | 71 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { |
| 72 SocketAddress::SetAddrPort(&addr, port); | |
| 73 intptr_t result = TEMP_FAILURE_RETRY( | 72 intptr_t result = TEMP_FAILURE_RETRY( |
| 74 connect(fd, &addr.addr, SocketAddress::GetAddrLength(&addr))); | 73 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); |
| 75 if (result == 0 || errno == EINPROGRESS) { | 74 if (result == 0 || errno == EINPROGRESS) { |
| 76 return fd; | 75 return fd; |
| 77 } | 76 } |
| 78 VOID_TEMP_FAILURE_RETRY(close(fd)); | 77 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 79 return -1; | 78 return -1; |
| 80 } | 79 } |
| 81 | 80 |
| 82 | 81 |
| 83 intptr_t Socket::CreateConnect(const RawAddr& addr, const intptr_t port) { | 82 intptr_t Socket::CreateConnect(const RawAddr& addr) { |
| 84 intptr_t fd = Create(addr); | 83 intptr_t fd = Create(addr); |
| 85 if (fd < 0) { | 84 if (fd < 0) { |
| 86 return fd; | 85 return fd; |
| 87 } | 86 } |
| 88 | 87 |
| 89 FDUtils::SetNonBlocking(fd); | 88 FDUtils::SetNonBlocking(fd); |
| 90 | 89 |
| 91 return Connect(fd, addr, port); | 90 return Connect(fd, addr); |
| 92 } | 91 } |
| 93 | 92 |
| 94 | 93 |
| 95 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 94 intptr_t Socket::CreateBindConnect(const RawAddr& addr, |
| 96 const intptr_t port, | |
| 97 const RawAddr& source_addr) { | 95 const RawAddr& source_addr) { |
| 98 intptr_t fd = Create(addr); | 96 intptr_t fd = Create(addr); |
| 99 if (fd < 0) { | 97 if (fd < 0) { |
| 100 return fd; | 98 return fd; |
| 101 } | 99 } |
| 102 | 100 |
| 103 intptr_t result = TEMP_FAILURE_RETRY( | 101 intptr_t result = TEMP_FAILURE_RETRY( |
| 104 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(&source_addr))); | 102 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); |
| 105 if (result != 0 && errno != EINPROGRESS) { | 103 if (result != 0 && errno != EINPROGRESS) { |
| 106 VOID_TEMP_FAILURE_RETRY(close(fd)); | 104 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 107 return -1; | 105 return -1; |
| 108 } | 106 } |
| 109 | 107 |
| 110 return Connect(fd, addr, port); | 108 return Connect(fd, addr); |
| 111 } | 109 } |
| 112 | 110 |
| 113 | 111 |
| 114 intptr_t Socket::Available(intptr_t fd) { | 112 intptr_t Socket::Available(intptr_t fd) { |
| 115 return FDUtils::AvailableBytes(fd); | 113 return FDUtils::AvailableBytes(fd); |
| 116 } | 114 } |
| 117 | 115 |
| 118 | 116 |
| 119 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { | 117 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { |
| 120 ASSERT(fd >= 0); | 118 ASSERT(fd >= 0); |
| 121 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)); |
| 122 ASSERT(EAGAIN == EWOULDBLOCK); | 120 ASSERT(EAGAIN == EWOULDBLOCK); |
| 123 if (read_bytes == -1 && errno == EWOULDBLOCK) { | 121 if (read_bytes == -1 && errno == EWOULDBLOCK) { |
| 124 // 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 |
| 125 // as the number of bytes written. | 123 // as the number of bytes written. |
| 126 read_bytes = 0; | 124 read_bytes = 0; |
| 127 } | 125 } |
| 128 return read_bytes; | 126 return read_bytes; |
| 129 } | 127 } |
| 130 | 128 |
| 131 | 129 |
| 132 intptr_t Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes, | 130 intptr_t Socket::RecvFrom( |
| 133 RawAddr* addr) { | 131 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr) { |
| 134 ASSERT(fd >= 0); | 132 ASSERT(fd >= 0); |
| 135 socklen_t addr_len = sizeof(addr->ss); | 133 socklen_t addr_len = sizeof(addr->ss); |
| 136 ssize_t read_bytes = TEMP_FAILURE_RETRY( | 134 ssize_t read_bytes = TEMP_FAILURE_RETRY( |
| 137 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); | 135 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); |
| 138 if (read_bytes == -1 && errno == EWOULDBLOCK) { | 136 if (read_bytes == -1 && errno == EWOULDBLOCK) { |
| 139 // If the read would block we need to retry and therefore return 0 | 137 // If the read would block we need to retry and therefore return 0 |
| 140 // as the number of bytes written. | 138 // as the number of bytes written. |
| 141 read_bytes = 0; | 139 read_bytes = 0; |
| 142 } | 140 } |
| 143 return read_bytes; | 141 return read_bytes; |
| 144 } | 142 } |
| 145 | 143 |
| 146 | 144 |
| 147 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { | 145 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { |
| 148 ASSERT(fd >= 0); | 146 ASSERT(fd >= 0); |
| 149 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); | 147 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); |
| 150 ASSERT(EAGAIN == EWOULDBLOCK); | 148 ASSERT(EAGAIN == EWOULDBLOCK); |
| 151 if (written_bytes == -1 && errno == EWOULDBLOCK) { | 149 if (written_bytes == -1 && errno == EWOULDBLOCK) { |
| 152 // If the would block we need to retry and therefore return 0 as | 150 // If the would block we need to retry and therefore return 0 as |
| 153 // the number of bytes written. | 151 // the number of bytes written. |
| 154 written_bytes = 0; | 152 written_bytes = 0; |
| 155 } | 153 } |
| 156 return written_bytes; | 154 return written_bytes; |
| 157 } | 155 } |
| 158 | 156 |
| 159 | 157 |
| 160 intptr_t Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes, | 158 intptr_t Socket::SendTo( |
| 161 RawAddr addr) { | 159 intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr) { |
| 162 ASSERT(fd >= 0); | 160 ASSERT(fd >= 0); |
| 163 ssize_t written_bytes = TEMP_FAILURE_RETRY( | 161 ssize_t written_bytes = TEMP_FAILURE_RETRY( |
| 164 sendto(fd, buffer, num_bytes, 0, | 162 sendto(fd, buffer, num_bytes, 0, |
| 165 &addr.addr, SocketAddress::GetAddrLength(&addr))); | 163 &addr.addr, SocketAddress::GetAddrLength(addr))); |
| 166 ASSERT(EAGAIN == EWOULDBLOCK); | 164 ASSERT(EAGAIN == EWOULDBLOCK); |
| 167 if (written_bytes == -1 && errno == EWOULDBLOCK) { | 165 if (written_bytes == -1 && errno == EWOULDBLOCK) { |
| 168 // If the would block we need to retry and therefore return 0 as | 166 // If the would block we need to retry and therefore return 0 as |
| 169 // the number of bytes written. | 167 // the number of bytes written. |
| 170 written_bytes = 0; | 168 written_bytes = 0; |
| 171 } | 169 } |
| 172 return written_bytes; | 170 return written_bytes; |
| 173 } | 171 } |
| 174 | 172 |
| 175 | 173 |
| 176 intptr_t Socket::GetPort(intptr_t fd) { | 174 intptr_t Socket::GetPort(intptr_t fd) { |
| 177 ASSERT(fd >= 0); | 175 ASSERT(fd >= 0); |
| 178 RawAddr raw; | 176 RawAddr raw; |
| 179 socklen_t size = sizeof(raw); | 177 socklen_t size = sizeof(raw); |
| 180 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { | 178 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { |
| 181 return 0; | 179 return 0; |
| 182 } | 180 } |
| 183 return SocketAddress::GetAddrPort(&raw); | 181 return SocketAddress::GetAddrPort(raw); |
| 184 } | 182 } |
| 185 | 183 |
| 186 | 184 |
| 187 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { | 185 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { |
| 188 ASSERT(fd >= 0); | 186 ASSERT(fd >= 0); |
| 189 RawAddr raw; | 187 RawAddr raw; |
| 190 socklen_t size = sizeof(raw); | 188 socklen_t size = sizeof(raw); |
| 191 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { | 189 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { |
| 192 return NULL; | 190 return NULL; |
| 193 } | 191 } |
| 194 *port = SocketAddress::GetAddrPort(&raw); | 192 *port = SocketAddress::GetAddrPort(raw); |
| 195 return new SocketAddress(&raw.addr); | 193 return new SocketAddress(&raw.addr); |
| 196 } | 194 } |
| 197 | 195 |
| 198 | 196 |
| 199 void Socket::GetError(intptr_t fd, OSError* os_error) { | 197 void Socket::GetError(intptr_t fd, OSError* os_error) { |
| 200 int len = sizeof(errno); | 198 int len = sizeof(errno); |
| 201 getsockopt(fd, | 199 getsockopt(fd, |
| 202 SOL_SOCKET, | 200 SOL_SOCKET, |
| 203 SO_ERROR, | 201 SO_ERROR, |
| 204 &errno, | 202 &errno, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) { | 250 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) { |
| 253 addresses->SetAt(i, new SocketAddress(c->ai_addr)); | 251 addresses->SetAt(i, new SocketAddress(c->ai_addr)); |
| 254 i++; | 252 i++; |
| 255 } | 253 } |
| 256 } | 254 } |
| 257 freeaddrinfo(info); | 255 freeaddrinfo(info); |
| 258 return addresses; | 256 return addresses; |
| 259 } | 257 } |
| 260 | 258 |
| 261 | 259 |
| 262 bool Socket::ReverseLookup(RawAddr addr, | 260 bool Socket::ReverseLookup(const RawAddr& addr, |
| 263 char* host, | 261 char* host, |
| 264 intptr_t host_len, | 262 intptr_t host_len, |
| 265 OSError** os_error) { | 263 OSError** os_error) { |
| 266 ASSERT(host_len >= NI_MAXHOST); | 264 ASSERT(host_len >= NI_MAXHOST); |
| 267 int status = NO_RETRY_EXPECTED(getnameinfo( | 265 int status = NO_RETRY_EXPECTED(getnameinfo( |
| 268 &addr.addr, | 266 &addr.addr, |
| 269 SocketAddress::GetAddrLength(&addr), | 267 SocketAddress::GetAddrLength(addr), |
| 270 host, | 268 host, |
| 271 host_len, | 269 host_len, |
| 272 NULL, | 270 NULL, |
| 273 0, | 271 0, |
| 274 NI_NAMEREQD)); | 272 NI_NAMEREQD)); |
| 275 if (status != 0) { | 273 if (status != 0) { |
| 276 ASSERT(*os_error == NULL); | 274 ASSERT(*os_error == NULL); |
| 277 *os_error = new OSError(status, | 275 *os_error = new OSError(status, |
| 278 gai_strerror(status), | 276 gai_strerror(status), |
| 279 OSError::kGetAddressInfo); | 277 OSError::kGetAddressInfo); |
| 280 return false; | 278 return false; |
| 281 } | 279 } |
| 282 return true; | 280 return true; |
| 283 } | 281 } |
| 284 | 282 |
| 285 | 283 |
| 286 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { | 284 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { |
| 287 int result; | 285 int result; |
| 288 if (type == SocketAddress::TYPE_IPV4) { | 286 if (type == SocketAddress::TYPE_IPV4) { |
| 289 result = inet_pton(AF_INET, address, &addr->in.sin_addr); | 287 result = inet_pton(AF_INET, address, &addr->in.sin_addr); |
| 290 } else { | 288 } else { |
| 291 ASSERT(type == SocketAddress::TYPE_IPV6); | 289 ASSERT(type == SocketAddress::TYPE_IPV6); |
| 292 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); | 290 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); |
| 293 } | 291 } |
| 294 return result == 1; | 292 return result == 1; |
| 295 } | 293 } |
| 296 | 294 |
| 297 | 295 |
| 298 intptr_t Socket::CreateBindDatagram( | 296 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { |
| 299 RawAddr* addr, intptr_t port, bool reuseAddress) { | |
| 300 intptr_t fd; | 297 intptr_t fd; |
| 301 | 298 |
| 302 fd = NO_RETRY_EXPECTED(socket(addr->addr.sa_family, SOCK_DGRAM, IPPROTO_UDP)); | 299 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, SOCK_DGRAM, IPPROTO_UDP)); |
| 303 if (fd < 0) return -1; | 300 if (fd < 0) return -1; |
| 304 | 301 |
| 305 FDUtils::SetCloseOnExec(fd); | 302 FDUtils::SetCloseOnExec(fd); |
| 306 | 303 |
| 307 if (reuseAddress) { | 304 if (reuseAddress) { |
| 308 int optval = 1; | 305 int optval = 1; |
| 309 VOID_NO_RETRY_EXPECTED( | 306 VOID_NO_RETRY_EXPECTED( |
| 310 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 307 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); |
| 311 } | 308 } |
| 312 | 309 |
| 313 SocketAddress::SetAddrPort(addr, port); | |
| 314 if (NO_RETRY_EXPECTED( | 310 if (NO_RETRY_EXPECTED( |
| 315 bind(fd, &addr->addr, SocketAddress::GetAddrLength(addr))) < 0) { | 311 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { |
| 316 VOID_TEMP_FAILURE_RETRY(close(fd)); | 312 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 317 return -1; | 313 return -1; |
| 318 } | 314 } |
| 319 | 315 |
| 320 FDUtils::SetNonBlocking(fd); | 316 FDUtils::SetNonBlocking(fd); |
| 321 return fd; | 317 return fd; |
| 322 } | 318 } |
| 323 | 319 |
| 324 | 320 |
| 325 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { | 321 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 addresses->SetAt(i, new InterfaceSocketAddress( | 362 addresses->SetAt(i, new InterfaceSocketAddress( |
| 367 ifa->ifa_addr, strdup(ifa->ifa_name), if_nametoindex(ifa->ifa_name))); | 363 ifa->ifa_addr, strdup(ifa->ifa_name), if_nametoindex(ifa->ifa_name))); |
| 368 i++; | 364 i++; |
| 369 } | 365 } |
| 370 } | 366 } |
| 371 freeifaddrs(ifaddr); | 367 freeifaddrs(ifaddr); |
| 372 return addresses; | 368 return addresses; |
| 373 } | 369 } |
| 374 | 370 |
| 375 | 371 |
| 376 intptr_t ServerSocket::CreateBindListen(RawAddr addr, | 372 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, |
| 377 intptr_t port, | |
| 378 intptr_t backlog, | 373 intptr_t backlog, |
| 379 bool v6_only) { | 374 bool v6_only) { |
| 380 intptr_t fd; | 375 intptr_t fd; |
| 381 | 376 |
| 382 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0)); | 377 fd = TEMP_FAILURE_RETRY(socket(addr.ss.ss_family, SOCK_STREAM, 0)); |
| 383 if (fd < 0) return -1; | 378 if (fd < 0) return -1; |
| 384 | 379 |
| 385 FDUtils::SetCloseOnExec(fd); | 380 FDUtils::SetCloseOnExec(fd); |
| 386 | 381 |
| 387 int optval = 1; | 382 int optval = 1; |
| 388 VOID_NO_RETRY_EXPECTED( | 383 VOID_NO_RETRY_EXPECTED( |
| 389 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 384 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); |
| 390 | 385 |
| 391 if (addr.ss.ss_family == AF_INET6) { | 386 if (addr.ss.ss_family == AF_INET6) { |
| 392 optval = v6_only ? 1 : 0; | 387 optval = v6_only ? 1 : 0; |
| 393 VOID_NO_RETRY_EXPECTED( | 388 VOID_NO_RETRY_EXPECTED( |
| 394 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); | 389 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); |
| 395 } | 390 } |
| 396 | 391 |
| 397 SocketAddress::SetAddrPort(&addr, port); | |
| 398 if (NO_RETRY_EXPECTED( | 392 if (NO_RETRY_EXPECTED( |
| 399 bind(fd, &addr.addr, SocketAddress::GetAddrLength(&addr))) < 0) { | 393 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { |
| 400 VOID_TEMP_FAILURE_RETRY(close(fd)); | 394 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 401 return -1; | 395 return -1; |
| 402 } | 396 } |
| 403 | 397 |
| 404 // Test for invalid socket port 65535 (some browsers disallow it). | 398 // Test for invalid socket port 65535 (some browsers disallow it). |
| 405 if (port == 0 && Socket::GetPort(fd) == 65535) { | 399 if (SocketAddress::GetAddrPort(addr) == 0 && Socket::GetPort(fd) == 65535) { |
| 406 // 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 |
| 407 // that we do not get the bad port number again. | 401 // that we do not get the bad port number again. |
| 408 intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only); | 402 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); |
| 409 int err = errno; | 403 int err = errno; |
| 410 VOID_TEMP_FAILURE_RETRY(close(fd)); | 404 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 411 errno = err; | 405 errno = err; |
| 412 return new_fd; | 406 return new_fd; |
| 413 } | 407 } |
| 414 | 408 |
| 415 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 409 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { |
| 416 VOID_TEMP_FAILURE_RETRY(close(fd)); | 410 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 417 return -1; | 411 return -1; |
| 418 } | 412 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 int on = enabled ? 1 : 0; | 555 int on = enabled ? 1 : 0; |
| 562 return NO_RETRY_EXPECTED(setsockopt(fd, | 556 return NO_RETRY_EXPECTED(setsockopt(fd, |
| 563 SOL_SOCKET, | 557 SOL_SOCKET, |
| 564 SO_BROADCAST, | 558 SO_BROADCAST, |
| 565 reinterpret_cast<char *>(&on), | 559 reinterpret_cast<char *>(&on), |
| 566 sizeof(on))) == 0; | 560 sizeof(on))) == 0; |
| 567 } | 561 } |
| 568 | 562 |
| 569 | 563 |
| 570 static bool JoinOrLeaveMulticast(intptr_t fd, | 564 static bool JoinOrLeaveMulticast(intptr_t fd, |
| 571 RawAddr* addr, | 565 const RawAddr& addr, |
| 572 RawAddr* interface, | 566 const RawAddr& interface, |
| 573 int interfaceIndex, | 567 int interfaceIndex, |
| 574 bool join) { | 568 bool join) { |
| 575 if (addr->addr.sa_family == AF_INET) { | 569 if (addr.addr.sa_family == AF_INET) { |
| 576 ASSERT(interface->addr.sa_family == AF_INET); | 570 ASSERT(interface.addr.sa_family == AF_INET); |
| 577 struct ip_mreq mreq; | 571 struct ip_mreq mreq; |
| 578 memmove(&mreq.imr_multiaddr, | 572 memmove(&mreq.imr_multiaddr, |
| 579 &addr->in.sin_addr, | 573 &addr.in.sin_addr, |
| 580 SocketAddress::GetInAddrLength(addr)); | 574 SocketAddress::GetInAddrLength(addr)); |
| 581 memmove(&mreq.imr_interface, | 575 memmove(&mreq.imr_interface, |
| 582 &interface->in.sin_addr, | 576 &interface.in.sin_addr, |
| 583 SocketAddress::GetInAddrLength(interface)); | 577 SocketAddress::GetInAddrLength(interface)); |
| 584 if (join) { | 578 if (join) { |
| 585 return NO_RETRY_EXPECTED(setsockopt( | 579 return NO_RETRY_EXPECTED(setsockopt( |
| 586 fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; | 580 fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; |
| 587 } else { | 581 } else { |
| 588 return NO_RETRY_EXPECTED(setsockopt( | 582 return NO_RETRY_EXPECTED(setsockopt( |
| 589 fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; | 583 fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq))) == 0; |
| 590 } | 584 } |
| 591 } else { | 585 } else { |
| 592 ASSERT(addr->addr.sa_family == AF_INET6); | 586 ASSERT(addr.addr.sa_family == AF_INET6); |
| 593 struct ipv6_mreq mreq; | 587 struct ipv6_mreq mreq; |
| 594 memmove(&mreq.ipv6mr_multiaddr, | 588 memmove(&mreq.ipv6mr_multiaddr, |
| 595 &addr->in6.sin6_addr, | 589 &addr.in6.sin6_addr, |
| 596 SocketAddress::GetInAddrLength(addr)); | 590 SocketAddress::GetInAddrLength(addr)); |
| 597 mreq.ipv6mr_interface = interfaceIndex; | 591 mreq.ipv6mr_interface = interfaceIndex; |
| 598 if (join) { | 592 if (join) { |
| 599 return NO_RETRY_EXPECTED(setsockopt( | 593 return NO_RETRY_EXPECTED(setsockopt( |
| 600 fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; | 594 fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; |
| 601 } else { | 595 } else { |
| 602 return NO_RETRY_EXPECTED(setsockopt( | 596 return NO_RETRY_EXPECTED(setsockopt( |
| 603 fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; | 597 fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; |
| 604 } | 598 } |
| 605 } | 599 } |
| 606 } | 600 } |
| 607 | 601 |
| 608 bool Socket::JoinMulticast( | 602 bool Socket::JoinMulticast(intptr_t fd, |
| 609 intptr_t fd, RawAddr* addr, RawAddr* interface, int interfaceIndex) { | 603 const RawAddr& addr, |
| 604 const RawAddr& interface, |
| 605 int interfaceIndex) { |
| 610 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); | 606 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); |
| 611 } | 607 } |
| 612 | 608 |
| 613 | 609 |
| 614 bool Socket::LeaveMulticast( | 610 bool Socket::LeaveMulticast(intptr_t fd, |
| 615 intptr_t fd, RawAddr* addr, RawAddr* interface, int interfaceIndex) { | 611 const RawAddr& addr, |
| 612 const RawAddr& interface, |
| 613 int interfaceIndex) { |
| 616 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); | 614 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); |
| 617 } | 615 } |
| 618 | 616 |
| 619 } // namespace bin | 617 } // namespace bin |
| 620 } // namespace dart | 618 } // namespace dart |
| 621 | 619 |
| 622 #endif // defined(TARGET_OS_MACOS) | 620 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |