| 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_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 10 matching lines...) Expand all Loading... |
| 21 #include "bin/thread.h" | 21 #include "bin/thread.h" |
| 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( | 41 if (NO_RETRY_EXPECTED(getnameinfo( |
| 42 &addr->addr, salen, address, len, NULL, 0, NI_NUMERICHOST) != 0)) { | 42 &addr.addr, salen, address, len, NULL, 0, NI_NUMERICHOST) != 0)) { |
| 43 return false; | 43 return false; |
| 44 } | 44 } |
| 45 return true; | 45 return true; |
| 46 } | 46 } |
| 47 | 47 |
| 48 | 48 |
| 49 bool Socket::Initialize() { | 49 bool Socket::Initialize() { |
| 50 // Nothing to do on Linux. | 50 // Nothing to do on Linux. |
| 51 return true; | 51 return true; |
| 52 } | 52 } |
| 53 | 53 |
| 54 | 54 |
| 55 static intptr_t Create(RawAddr addr) { | 55 static intptr_t Create(const RawAddr& addr) { |
| 56 intptr_t fd; | 56 intptr_t fd; |
| 57 fd = NO_RETRY_EXPECTED( | 57 fd = NO_RETRY_EXPECTED( |
| 58 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); | 58 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); |
| 59 if (fd < 0) { | 59 if (fd < 0) { |
| 60 return -1; | 60 return -1; |
| 61 } | 61 } |
| 62 return fd; | 62 return fd; |
| 63 } | 63 } |
| 64 | 64 |
| 65 | 65 |
| 66 static intptr_t Connect(intptr_t fd, RawAddr addr, const intptr_t port) { | 66 static intptr_t Connect(intptr_t fd, const RawAddr& addr) { |
| 67 SocketAddress::SetAddrPort(&addr, port); | |
| 68 intptr_t result = TEMP_FAILURE_RETRY( | 67 intptr_t result = TEMP_FAILURE_RETRY( |
| 69 connect(fd, &addr.addr, SocketAddress::GetAddrLength(&addr))); | 68 connect(fd, &addr.addr, SocketAddress::GetAddrLength(addr))); |
| 70 if (result == 0 || errno == EINPROGRESS) { | 69 if (result == 0 || errno == EINPROGRESS) { |
| 71 return fd; | 70 return fd; |
| 72 } | 71 } |
| 73 VOID_TEMP_FAILURE_RETRY(close(fd)); | 72 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 74 return -1; | 73 return -1; |
| 75 } | 74 } |
| 76 | 75 |
| 77 | 76 |
| 78 intptr_t Socket::CreateConnect(const RawAddr& addr, const intptr_t port) { | 77 intptr_t Socket::CreateConnect(const RawAddr& addr) { |
| 79 intptr_t fd = Create(addr); | 78 intptr_t fd = Create(addr); |
| 80 if (fd < 0) { | 79 if (fd < 0) { |
| 81 return fd; | 80 return fd; |
| 82 } | 81 } |
| 83 return Connect(fd, addr, port); | 82 return Connect(fd, addr); |
| 84 } | 83 } |
| 85 | 84 |
| 86 | 85 |
| 87 intptr_t Socket::CreateBindConnect(const RawAddr& addr, | 86 intptr_t Socket::CreateBindConnect(const RawAddr& addr, |
| 88 const intptr_t port, | |
| 89 const RawAddr& source_addr) { | 87 const RawAddr& source_addr) { |
| 90 intptr_t fd = Create(addr); | 88 intptr_t fd = Create(addr); |
| 91 if (fd < 0) { | 89 if (fd < 0) { |
| 92 return fd; | 90 return fd; |
| 93 } | 91 } |
| 94 | 92 |
| 95 intptr_t result = TEMP_FAILURE_RETRY( | 93 intptr_t result = TEMP_FAILURE_RETRY( |
| 96 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(&source_addr))); | 94 bind(fd, &source_addr.addr, SocketAddress::GetAddrLength(source_addr))); |
| 97 if (result != 0 && errno != EINPROGRESS) { | 95 if (result != 0 && errno != EINPROGRESS) { |
| 98 VOID_TEMP_FAILURE_RETRY(close(fd)); | 96 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 99 return -1; | 97 return -1; |
| 100 } | 98 } |
| 101 | 99 |
| 102 return Connect(fd, addr, port); | 100 return Connect(fd, addr); |
| 103 } | 101 } |
| 104 | 102 |
| 105 | 103 |
| 106 intptr_t Socket::Available(intptr_t fd) { | 104 intptr_t Socket::Available(intptr_t fd) { |
| 107 return FDUtils::AvailableBytes(fd); | 105 return FDUtils::AvailableBytes(fd); |
| 108 } | 106 } |
| 109 | 107 |
| 110 | 108 |
| 111 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { | 109 intptr_t Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) { |
| 112 ASSERT(fd >= 0); | 110 ASSERT(fd >= 0); |
| 113 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); | 111 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); |
| 114 ASSERT(EAGAIN == EWOULDBLOCK); | 112 ASSERT(EAGAIN == EWOULDBLOCK); |
| 115 if (read_bytes == -1 && errno == EWOULDBLOCK) { | 113 if (read_bytes == -1 && errno == EWOULDBLOCK) { |
| 116 // If the read would block we need to retry and therefore return 0 | 114 // If the read would block we need to retry and therefore return 0 |
| 117 // as the number of bytes written. | 115 // as the number of bytes written. |
| 118 read_bytes = 0; | 116 read_bytes = 0; |
| 119 } | 117 } |
| 120 return read_bytes; | 118 return read_bytes; |
| 121 } | 119 } |
| 122 | 120 |
| 123 | 121 |
| 124 intptr_t Socket::RecvFrom(intptr_t fd, void* buffer, intptr_t num_bytes, | 122 intptr_t Socket::RecvFrom( |
| 125 RawAddr* addr) { | 123 intptr_t fd, void* buffer, intptr_t num_bytes, RawAddr* addr) { |
| 126 ASSERT(fd >= 0); | 124 ASSERT(fd >= 0); |
| 127 socklen_t addr_len = sizeof(addr->ss); | 125 socklen_t addr_len = sizeof(addr->ss); |
| 128 ssize_t read_bytes = TEMP_FAILURE_RETRY( | 126 ssize_t read_bytes = TEMP_FAILURE_RETRY( |
| 129 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); | 127 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); |
| 130 if (read_bytes == -1 && errno == EWOULDBLOCK) { | 128 if (read_bytes == -1 && errno == EWOULDBLOCK) { |
| 131 // If the read would block we need to retry and therefore return 0 | 129 // If the read would block we need to retry and therefore return 0 |
| 132 // as the number of bytes written. | 130 // as the number of bytes written. |
| 133 read_bytes = 0; | 131 read_bytes = 0; |
| 134 } | 132 } |
| 135 return read_bytes; | 133 return read_bytes; |
| 136 } | 134 } |
| 137 | 135 |
| 138 | 136 |
| 139 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { | 137 intptr_t Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) { |
| 140 ASSERT(fd >= 0); | 138 ASSERT(fd >= 0); |
| 141 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); | 139 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); |
| 142 ASSERT(EAGAIN == EWOULDBLOCK); | 140 ASSERT(EAGAIN == EWOULDBLOCK); |
| 143 if (written_bytes == -1 && errno == EWOULDBLOCK) { | 141 if (written_bytes == -1 && errno == EWOULDBLOCK) { |
| 144 // If the would block we need to retry and therefore return 0 as | 142 // If the would block we need to retry and therefore return 0 as |
| 145 // the number of bytes written. | 143 // the number of bytes written. |
| 146 written_bytes = 0; | 144 written_bytes = 0; |
| 147 } | 145 } |
| 148 return written_bytes; | 146 return written_bytes; |
| 149 } | 147 } |
| 150 | 148 |
| 151 | 149 |
| 152 intptr_t Socket::SendTo(intptr_t fd, const void* buffer, intptr_t num_bytes, | 150 intptr_t Socket::SendTo( |
| 153 RawAddr addr) { | 151 intptr_t fd, const void* buffer, intptr_t num_bytes, const RawAddr& addr) { |
| 154 ASSERT(fd >= 0); | 152 ASSERT(fd >= 0); |
| 155 ssize_t written_bytes = TEMP_FAILURE_RETRY( | 153 ssize_t written_bytes = TEMP_FAILURE_RETRY( |
| 156 sendto(fd, buffer, num_bytes, 0, | 154 sendto(fd, buffer, num_bytes, 0, |
| 157 &addr.addr, SocketAddress::GetAddrLength(&addr))); | 155 &addr.addr, SocketAddress::GetAddrLength(addr))); |
| 158 ASSERT(EAGAIN == EWOULDBLOCK); | 156 ASSERT(EAGAIN == EWOULDBLOCK); |
| 159 if (written_bytes == -1 && errno == EWOULDBLOCK) { | 157 if (written_bytes == -1 && errno == EWOULDBLOCK) { |
| 160 // If the would block we need to retry and therefore return 0 as | 158 // If the would block we need to retry and therefore return 0 as |
| 161 // the number of bytes written. | 159 // the number of bytes written. |
| 162 written_bytes = 0; | 160 written_bytes = 0; |
| 163 } | 161 } |
| 164 return written_bytes; | 162 return written_bytes; |
| 165 } | 163 } |
| 166 | 164 |
| 167 | 165 |
| 168 intptr_t Socket::GetPort(intptr_t fd) { | 166 intptr_t Socket::GetPort(intptr_t fd) { |
| 169 ASSERT(fd >= 0); | 167 ASSERT(fd >= 0); |
| 170 RawAddr raw; | 168 RawAddr raw; |
| 171 socklen_t size = sizeof(raw); | 169 socklen_t size = sizeof(raw); |
| 172 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { | 170 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { |
| 173 return 0; | 171 return 0; |
| 174 } | 172 } |
| 175 return SocketAddress::GetAddrPort(&raw); | 173 return SocketAddress::GetAddrPort(raw); |
| 176 } | 174 } |
| 177 | 175 |
| 178 | 176 |
| 179 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { | 177 SocketAddress* Socket::GetRemotePeer(intptr_t fd, intptr_t* port) { |
| 180 ASSERT(fd >= 0); | 178 ASSERT(fd >= 0); |
| 181 RawAddr raw; | 179 RawAddr raw; |
| 182 socklen_t size = sizeof(raw); | 180 socklen_t size = sizeof(raw); |
| 183 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { | 181 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { |
| 184 return NULL; | 182 return NULL; |
| 185 } | 183 } |
| 186 *port = SocketAddress::GetAddrPort(&raw); | 184 *port = SocketAddress::GetAddrPort(raw); |
| 187 return new SocketAddress(&raw.addr); | 185 return new SocketAddress(&raw.addr); |
| 188 } | 186 } |
| 189 | 187 |
| 190 | 188 |
| 191 void Socket::GetError(intptr_t fd, OSError* os_error) { | 189 void Socket::GetError(intptr_t fd, OSError* os_error) { |
| 192 int len = sizeof(errno); | 190 int len = sizeof(errno); |
| 193 int err = 0; | 191 int err = 0; |
| 194 VOID_NO_RETRY_EXPECTED(getsockopt( | 192 VOID_NO_RETRY_EXPECTED(getsockopt( |
| 195 fd, SOL_SOCKET, SO_ERROR, &err, reinterpret_cast<socklen_t*>(&len))); | 193 fd, SOL_SOCKET, SO_ERROR, &err, reinterpret_cast<socklen_t*>(&len))); |
| 196 errno = err; | 194 errno = err; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) { | 247 if (c->ai_family == AF_INET || c->ai_family == AF_INET6) { |
| 250 addresses->SetAt(i, new SocketAddress(c->ai_addr)); | 248 addresses->SetAt(i, new SocketAddress(c->ai_addr)); |
| 251 i++; | 249 i++; |
| 252 } | 250 } |
| 253 } | 251 } |
| 254 freeaddrinfo(info); | 252 freeaddrinfo(info); |
| 255 return addresses; | 253 return addresses; |
| 256 } | 254 } |
| 257 | 255 |
| 258 | 256 |
| 259 bool Socket::ReverseLookup(RawAddr addr, | 257 bool Socket::ReverseLookup(const RawAddr& addr, |
| 260 char* host, | 258 char* host, |
| 261 intptr_t host_len, | 259 intptr_t host_len, |
| 262 OSError** os_error) { | 260 OSError** os_error) { |
| 263 ASSERT(host_len >= NI_MAXHOST); | 261 ASSERT(host_len >= NI_MAXHOST); |
| 264 int status = NO_RETRY_EXPECTED(getnameinfo( | 262 int status = NO_RETRY_EXPECTED(getnameinfo( |
| 265 &addr.addr, | 263 &addr.addr, |
| 266 SocketAddress::GetAddrLength(&addr), | 264 SocketAddress::GetAddrLength(addr), |
| 267 host, | 265 host, |
| 268 host_len, | 266 host_len, |
| 269 NULL, | 267 NULL, |
| 270 0, | 268 0, |
| 271 NI_NAMEREQD)); | 269 NI_NAMEREQD)); |
| 272 if (status != 0) { | 270 if (status != 0) { |
| 273 ASSERT(*os_error == NULL); | 271 ASSERT(*os_error == NULL); |
| 274 *os_error = new OSError(status, | 272 *os_error = new OSError(status, |
| 275 gai_strerror(status), | 273 gai_strerror(status), |
| 276 OSError::kGetAddressInfo); | 274 OSError::kGetAddressInfo); |
| 277 return false; | 275 return false; |
| 278 } | 276 } |
| 279 return true; | 277 return true; |
| 280 } | 278 } |
| 281 | 279 |
| 282 | 280 |
| 283 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { | 281 bool Socket::ParseAddress(int type, const char* address, RawAddr* addr) { |
| 284 int result; | 282 int result; |
| 285 if (type == SocketAddress::TYPE_IPV4) { | 283 if (type == SocketAddress::TYPE_IPV4) { |
| 286 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); | 284 result = NO_RETRY_EXPECTED(inet_pton(AF_INET, address, &addr->in.sin_addr)); |
| 287 } else { | 285 } else { |
| 288 ASSERT(type == SocketAddress::TYPE_IPV6); | 286 ASSERT(type == SocketAddress::TYPE_IPV6); |
| 289 result = NO_RETRY_EXPECTED( | 287 result = NO_RETRY_EXPECTED( |
| 290 inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); | 288 inet_pton(AF_INET6, address, &addr->in6.sin6_addr)); |
| 291 } | 289 } |
| 292 return result == 1; | 290 return result == 1; |
| 293 } | 291 } |
| 294 | 292 |
| 295 | 293 |
| 296 intptr_t Socket::CreateBindDatagram( | 294 intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) { |
| 297 RawAddr* addr, intptr_t port, bool reuseAddress) { | |
| 298 intptr_t fd; | 295 intptr_t fd; |
| 299 | 296 |
| 300 fd = NO_RETRY_EXPECTED(socket(addr->addr.sa_family, | 297 fd = NO_RETRY_EXPECTED(socket(addr.addr.sa_family, |
| 301 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, | 298 SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, |
| 302 IPPROTO_UDP)); | 299 IPPROTO_UDP)); |
| 303 if (fd < 0) return -1; | 300 if (fd < 0) return -1; |
| 304 | 301 |
| 305 if (reuseAddress) { | 302 if (reuseAddress) { |
| 306 int optval = 1; | 303 int optval = 1; |
| 307 VOID_NO_RETRY_EXPECTED( | 304 VOID_NO_RETRY_EXPECTED( |
| 308 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 305 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); |
| 309 } | 306 } |
| 310 | 307 |
| 311 SocketAddress::SetAddrPort(addr, port); | |
| 312 if (NO_RETRY_EXPECTED( | 308 if (NO_RETRY_EXPECTED( |
| 313 bind(fd, &addr->addr, SocketAddress::GetAddrLength(addr))) < 0) { | 309 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { |
| 314 VOID_TEMP_FAILURE_RETRY(close(fd)); | 310 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 315 return -1; | 311 return -1; |
| 316 } | 312 } |
| 317 return fd; | 313 return fd; |
| 318 } | 314 } |
| 319 | 315 |
| 320 | 316 |
| 321 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { | 317 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { |
| 322 if (ifa->ifa_addr == NULL) { | 318 if (ifa->ifa_addr == NULL) { |
| 323 // OpenVPN's virtual device tun0. | 319 // OpenVPN's virtual device tun0. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 addresses->SetAt(i, new InterfaceSocketAddress( | 358 addresses->SetAt(i, new InterfaceSocketAddress( |
| 363 ifa->ifa_addr, strdup(ifa->ifa_name), if_nametoindex(ifa->ifa_name))); | 359 ifa->ifa_addr, strdup(ifa->ifa_name), if_nametoindex(ifa->ifa_name))); |
| 364 i++; | 360 i++; |
| 365 } | 361 } |
| 366 } | 362 } |
| 367 freeifaddrs(ifaddr); | 363 freeifaddrs(ifaddr); |
| 368 return addresses; | 364 return addresses; |
| 369 } | 365 } |
| 370 | 366 |
| 371 | 367 |
| 372 intptr_t ServerSocket::CreateBindListen(RawAddr addr, | 368 intptr_t ServerSocket::CreateBindListen(const RawAddr& addr, |
| 373 intptr_t port, | |
| 374 intptr_t backlog, | 369 intptr_t backlog, |
| 375 bool v6_only) { | 370 bool v6_only) { |
| 376 intptr_t fd; | 371 intptr_t fd; |
| 377 | 372 |
| 378 fd = NO_RETRY_EXPECTED( | 373 fd = NO_RETRY_EXPECTED( |
| 379 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); | 374 socket(addr.ss.ss_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)); |
| 380 if (fd < 0) return -1; | 375 if (fd < 0) return -1; |
| 381 | 376 |
| 382 int optval = 1; | 377 int optval = 1; |
| 383 VOID_NO_RETRY_EXPECTED( | 378 VOID_NO_RETRY_EXPECTED( |
| 384 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); | 379 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))); |
| 385 | 380 |
| 386 if (addr.ss.ss_family == AF_INET6) { | 381 if (addr.ss.ss_family == AF_INET6) { |
| 387 optval = v6_only ? 1 : 0; | 382 optval = v6_only ? 1 : 0; |
| 388 VOID_NO_RETRY_EXPECTED( | 383 VOID_NO_RETRY_EXPECTED( |
| 389 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); | 384 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval))); |
| 390 } | 385 } |
| 391 | 386 |
| 392 SocketAddress::SetAddrPort(&addr, port); | |
| 393 if (NO_RETRY_EXPECTED( | 387 if (NO_RETRY_EXPECTED( |
| 394 bind(fd, &addr.addr, SocketAddress::GetAddrLength(&addr))) < 0) { | 388 bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) { |
| 395 VOID_TEMP_FAILURE_RETRY(close(fd)); | 389 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 396 return -1; | 390 return -1; |
| 397 } | 391 } |
| 398 | 392 |
| 399 // Test for invalid socket port 65535 (some browsers disallow it). | 393 // Test for invalid socket port 65535 (some browsers disallow it). |
| 400 if (port == 0 && Socket::GetPort(fd) == 65535) { | 394 if (SocketAddress::GetAddrPort(addr) == 0 && Socket::GetPort(fd) == 65535) { |
| 401 // Don't close the socket until we have created a new socket, ensuring | 395 // Don't close the socket until we have created a new socket, ensuring |
| 402 // that we do not get the bad port number again. | 396 // that we do not get the bad port number again. |
| 403 intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only); | 397 intptr_t new_fd = CreateBindListen(addr, backlog, v6_only); |
| 404 int err = errno; | 398 int err = errno; |
| 405 VOID_TEMP_FAILURE_RETRY(close(fd)); | 399 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 406 errno = err; | 400 errno = err; |
| 407 return new_fd; | 401 return new_fd; |
| 408 } | 402 } |
| 409 | 403 |
| 410 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { | 404 if (NO_RETRY_EXPECTED(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) { |
| 411 VOID_TEMP_FAILURE_RETRY(close(fd)); | 405 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 412 return -1; | 406 return -1; |
| 413 } | 407 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 int on = enabled ? 1 : 0; | 541 int on = enabled ? 1 : 0; |
| 548 return NO_RETRY_EXPECTED(setsockopt(fd, | 542 return NO_RETRY_EXPECTED(setsockopt(fd, |
| 549 SOL_SOCKET, | 543 SOL_SOCKET, |
| 550 SO_BROADCAST, | 544 SO_BROADCAST, |
| 551 reinterpret_cast<char *>(&on), | 545 reinterpret_cast<char *>(&on), |
| 552 sizeof(on))) == 0; | 546 sizeof(on))) == 0; |
| 553 } | 547 } |
| 554 | 548 |
| 555 | 549 |
| 556 bool Socket::JoinMulticast( | 550 bool Socket::JoinMulticast( |
| 557 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { | 551 intptr_t fd, const RawAddr& addr, const RawAddr&, int interfaceIndex) { |
| 558 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 552 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 559 struct group_req mreq; | 553 struct group_req mreq; |
| 560 mreq.gr_interface = interfaceIndex; | 554 mreq.gr_interface = interfaceIndex; |
| 561 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); | 555 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); |
| 562 return NO_RETRY_EXPECTED( | 556 return NO_RETRY_EXPECTED( |
| 563 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; | 557 setsockopt(fd, proto, MCAST_JOIN_GROUP, &mreq, sizeof(mreq))) == 0; |
| 564 } | 558 } |
| 565 | 559 |
| 566 | 560 |
| 567 bool Socket::LeaveMulticast( | 561 bool Socket::LeaveMulticast( |
| 568 intptr_t fd, RawAddr* addr, RawAddr*, int interfaceIndex) { | 562 intptr_t fd, const RawAddr& addr, const RawAddr&, int interfaceIndex) { |
| 569 int proto = addr->addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 563 int proto = addr.addr.sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
| 570 struct group_req mreq; | 564 struct group_req mreq; |
| 571 mreq.gr_interface = interfaceIndex; | 565 mreq.gr_interface = interfaceIndex; |
| 572 memmove(&mreq.gr_group, &addr->ss, SocketAddress::GetAddrLength(addr)); | 566 memmove(&mreq.gr_group, &addr.ss, SocketAddress::GetAddrLength(addr)); |
| 573 return NO_RETRY_EXPECTED( | 567 return NO_RETRY_EXPECTED( |
| 574 setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; | 568 setsockopt(fd, proto, MCAST_LEAVE_GROUP, &mreq, sizeof(mreq))) == 0; |
| 575 } | 569 } |
| 576 | 570 |
| 577 } // namespace bin | 571 } // namespace bin |
| 578 } // namespace dart | 572 } // namespace dart |
| 579 | 573 |
| 580 #endif // defined(TARGET_OS_LINUX) | 574 #endif // defined(TARGET_OS_LINUX) |
| OLD | NEW |