| 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 #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_base.h" | 10 #include "bin/socket_base.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 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 (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), | 32 if (!SocketBase::FormatNumericAddress(*reinterpret_cast<RawAddr*>(sa), |
| 33 as_string_, 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 | |
| 41 bool SocketBase::Initialize() { | 40 bool SocketBase::Initialize() { |
| 42 // Nothing to do on Mac OS. | 41 // Nothing to do on Mac OS. |
| 43 return true; | 42 return true; |
| 44 } | 43 } |
| 45 | 44 |
| 46 | |
| 47 bool SocketBase::FormatNumericAddress(const RawAddr& addr, | 45 bool SocketBase::FormatNumericAddress(const RawAddr& addr, |
| 48 char* address, | 46 char* address, |
| 49 int len) { | 47 int len) { |
| 50 socklen_t salen = SocketAddress::GetAddrLength(addr); | 48 socklen_t salen = SocketAddress::GetAddrLength(addr); |
| 51 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, | 49 return (NO_RETRY_EXPECTED(getnameinfo(&addr.addr, salen, address, len, NULL, |
| 52 0, NI_NUMERICHOST)) == 0); | 50 0, NI_NUMERICHOST)) == 0); |
| 53 } | 51 } |
| 54 | 52 |
| 55 | |
| 56 bool SocketBase::IsBindError(intptr_t error_number) { | 53 bool SocketBase::IsBindError(intptr_t error_number) { |
| 57 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || | 54 return error_number == EADDRINUSE || error_number == EADDRNOTAVAIL || |
| 58 error_number == EINVAL; | 55 error_number == EINVAL; |
| 59 } | 56 } |
| 60 | 57 |
| 61 | |
| 62 intptr_t SocketBase::Available(intptr_t fd) { | 58 intptr_t SocketBase::Available(intptr_t fd) { |
| 63 return FDUtils::AvailableBytes(fd); | 59 return FDUtils::AvailableBytes(fd); |
| 64 } | 60 } |
| 65 | 61 |
| 66 | |
| 67 intptr_t SocketBase::Read(intptr_t fd, | 62 intptr_t SocketBase::Read(intptr_t fd, |
| 68 void* buffer, | 63 void* buffer, |
| 69 intptr_t num_bytes, | 64 intptr_t num_bytes, |
| 70 SocketOpKind sync) { | 65 SocketOpKind sync) { |
| 71 ASSERT(fd >= 0); | 66 ASSERT(fd >= 0); |
| 72 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); | 67 ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes)); |
| 73 ASSERT(EAGAIN == EWOULDBLOCK); | 68 ASSERT(EAGAIN == EWOULDBLOCK); |
| 74 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { | 69 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { |
| 75 // If the read would block we need to retry and therefore return 0 | 70 // If the read would block we need to retry and therefore return 0 |
| 76 // as the number of bytes written. | 71 // as the number of bytes written. |
| 77 read_bytes = 0; | 72 read_bytes = 0; |
| 78 } | 73 } |
| 79 return read_bytes; | 74 return read_bytes; |
| 80 } | 75 } |
| 81 | 76 |
| 82 | |
| 83 intptr_t SocketBase::RecvFrom(intptr_t fd, | 77 intptr_t SocketBase::RecvFrom(intptr_t fd, |
| 84 void* buffer, | 78 void* buffer, |
| 85 intptr_t num_bytes, | 79 intptr_t num_bytes, |
| 86 RawAddr* addr, | 80 RawAddr* addr, |
| 87 SocketOpKind sync) { | 81 SocketOpKind sync) { |
| 88 ASSERT(fd >= 0); | 82 ASSERT(fd >= 0); |
| 89 socklen_t addr_len = sizeof(addr->ss); | 83 socklen_t addr_len = sizeof(addr->ss); |
| 90 ssize_t read_bytes = TEMP_FAILURE_RETRY( | 84 ssize_t read_bytes = TEMP_FAILURE_RETRY( |
| 91 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); | 85 recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len)); |
| 92 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { | 86 if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) { |
| 93 // If the read would block we need to retry and therefore return 0 | 87 // If the read would block we need to retry and therefore return 0 |
| 94 // as the number of bytes written. | 88 // as the number of bytes written. |
| 95 read_bytes = 0; | 89 read_bytes = 0; |
| 96 } | 90 } |
| 97 return read_bytes; | 91 return read_bytes; |
| 98 } | 92 } |
| 99 | 93 |
| 100 | |
| 101 intptr_t SocketBase::Write(intptr_t fd, | 94 intptr_t SocketBase::Write(intptr_t fd, |
| 102 const void* buffer, | 95 const void* buffer, |
| 103 intptr_t num_bytes, | 96 intptr_t num_bytes, |
| 104 SocketOpKind sync) { | 97 SocketOpKind sync) { |
| 105 ASSERT(fd >= 0); | 98 ASSERT(fd >= 0); |
| 106 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); | 99 ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes)); |
| 107 ASSERT(EAGAIN == EWOULDBLOCK); | 100 ASSERT(EAGAIN == EWOULDBLOCK); |
| 108 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { | 101 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { |
| 109 // If the would block we need to retry and therefore return 0 as | 102 // If the would block we need to retry and therefore return 0 as |
| 110 // the number of bytes written. | 103 // the number of bytes written. |
| 111 written_bytes = 0; | 104 written_bytes = 0; |
| 112 } | 105 } |
| 113 return written_bytes; | 106 return written_bytes; |
| 114 } | 107 } |
| 115 | 108 |
| 116 | |
| 117 intptr_t SocketBase::SendTo(intptr_t fd, | 109 intptr_t SocketBase::SendTo(intptr_t fd, |
| 118 const void* buffer, | 110 const void* buffer, |
| 119 intptr_t num_bytes, | 111 intptr_t num_bytes, |
| 120 const RawAddr& addr, | 112 const RawAddr& addr, |
| 121 SocketOpKind sync) { | 113 SocketOpKind sync) { |
| 122 ASSERT(fd >= 0); | 114 ASSERT(fd >= 0); |
| 123 ssize_t written_bytes = | 115 ssize_t written_bytes = |
| 124 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, | 116 TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr, |
| 125 SocketAddress::GetAddrLength(addr))); | 117 SocketAddress::GetAddrLength(addr))); |
| 126 ASSERT(EAGAIN == EWOULDBLOCK); | 118 ASSERT(EAGAIN == EWOULDBLOCK); |
| 127 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { | 119 if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) { |
| 128 // If the would block we need to retry and therefore return 0 as | 120 // If the would block we need to retry and therefore return 0 as |
| 129 // the number of bytes written. | 121 // the number of bytes written. |
| 130 written_bytes = 0; | 122 written_bytes = 0; |
| 131 } | 123 } |
| 132 return written_bytes; | 124 return written_bytes; |
| 133 } | 125 } |
| 134 | 126 |
| 135 | |
| 136 intptr_t SocketBase::GetPort(intptr_t fd) { | 127 intptr_t SocketBase::GetPort(intptr_t fd) { |
| 137 ASSERT(fd >= 0); | 128 ASSERT(fd >= 0); |
| 138 RawAddr raw; | 129 RawAddr raw; |
| 139 socklen_t size = sizeof(raw); | 130 socklen_t size = sizeof(raw); |
| 140 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { | 131 if (NO_RETRY_EXPECTED(getsockname(fd, &raw.addr, &size))) { |
| 141 return 0; | 132 return 0; |
| 142 } | 133 } |
| 143 return SocketAddress::GetAddrPort(raw); | 134 return SocketAddress::GetAddrPort(raw); |
| 144 } | 135 } |
| 145 | 136 |
| 146 | |
| 147 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { | 137 SocketAddress* SocketBase::GetRemotePeer(intptr_t fd, intptr_t* port) { |
| 148 ASSERT(fd >= 0); | 138 ASSERT(fd >= 0); |
| 149 RawAddr raw; | 139 RawAddr raw; |
| 150 socklen_t size = sizeof(raw); | 140 socklen_t size = sizeof(raw); |
| 151 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { | 141 if (NO_RETRY_EXPECTED(getpeername(fd, &raw.addr, &size))) { |
| 152 return NULL; | 142 return NULL; |
| 153 } | 143 } |
| 154 *port = SocketAddress::GetAddrPort(raw); | 144 *port = SocketAddress::GetAddrPort(raw); |
| 155 return new SocketAddress(&raw.addr); | 145 return new SocketAddress(&raw.addr); |
| 156 } | 146 } |
| 157 | 147 |
| 158 | |
| 159 void SocketBase::GetError(intptr_t fd, OSError* os_error) { | 148 void SocketBase::GetError(intptr_t fd, OSError* os_error) { |
| 160 int len = sizeof(errno); | 149 int len = sizeof(errno); |
| 161 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, | 150 getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, |
| 162 reinterpret_cast<socklen_t*>(&len)); | 151 reinterpret_cast<socklen_t*>(&len)); |
| 163 os_error->SetCodeAndMessage(OSError::kSystem, errno); | 152 os_error->SetCodeAndMessage(OSError::kSystem, errno); |
| 164 } | 153 } |
| 165 | 154 |
| 166 | |
| 167 int SocketBase::GetType(intptr_t fd) { | 155 int SocketBase::GetType(intptr_t fd) { |
| 168 struct stat buf; | 156 struct stat buf; |
| 169 int result = fstat(fd, &buf); | 157 int result = fstat(fd, &buf); |
| 170 if (result == -1) { | 158 if (result == -1) { |
| 171 return -1; | 159 return -1; |
| 172 } | 160 } |
| 173 if (S_ISCHR(buf.st_mode)) { | 161 if (S_ISCHR(buf.st_mode)) { |
| 174 return File::kTerminal; | 162 return File::kTerminal; |
| 175 } | 163 } |
| 176 if (S_ISFIFO(buf.st_mode)) { | 164 if (S_ISFIFO(buf.st_mode)) { |
| 177 return File::kPipe; | 165 return File::kPipe; |
| 178 } | 166 } |
| 179 if (S_ISREG(buf.st_mode)) { | 167 if (S_ISREG(buf.st_mode)) { |
| 180 return File::kFile; | 168 return File::kFile; |
| 181 } | 169 } |
| 182 return File::kOther; | 170 return File::kOther; |
| 183 } | 171 } |
| 184 | 172 |
| 185 | |
| 186 intptr_t SocketBase::GetStdioHandle(intptr_t num) { | 173 intptr_t SocketBase::GetStdioHandle(intptr_t num) { |
| 187 return num; | 174 return num; |
| 188 } | 175 } |
| 189 | 176 |
| 190 | |
| 191 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, | 177 AddressList<SocketAddress>* SocketBase::LookupAddress(const char* host, |
| 192 int type, | 178 int type, |
| 193 OSError** os_error) { | 179 OSError** os_error) { |
| 194 // Perform a name lookup for a host name. | 180 // Perform a name lookup for a host name. |
| 195 struct addrinfo hints; | 181 struct addrinfo hints; |
| 196 memset(&hints, 0, sizeof(hints)); | 182 memset(&hints, 0, sizeof(hints)); |
| 197 hints.ai_family = SocketAddress::FromType(type); | 183 hints.ai_family = SocketAddress::FromType(type); |
| 198 hints.ai_socktype = SOCK_STREAM; | 184 hints.ai_socktype = SOCK_STREAM; |
| 199 hints.ai_flags = 0; | 185 hints.ai_flags = 0; |
| 200 hints.ai_protocol = IPPROTO_TCP; | 186 hints.ai_protocol = IPPROTO_TCP; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 217 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { | 203 for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { |
| 218 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { | 204 if ((c->ai_family == AF_INET) || (c->ai_family == AF_INET6)) { |
| 219 addresses->SetAt(i, new SocketAddress(c->ai_addr)); | 205 addresses->SetAt(i, new SocketAddress(c->ai_addr)); |
| 220 i++; | 206 i++; |
| 221 } | 207 } |
| 222 } | 208 } |
| 223 freeaddrinfo(info); | 209 freeaddrinfo(info); |
| 224 return addresses; | 210 return addresses; |
| 225 } | 211 } |
| 226 | 212 |
| 227 | |
| 228 bool SocketBase::ReverseLookup(const RawAddr& addr, | 213 bool SocketBase::ReverseLookup(const RawAddr& addr, |
| 229 char* host, | 214 char* host, |
| 230 intptr_t host_len, | 215 intptr_t host_len, |
| 231 OSError** os_error) { | 216 OSError** os_error) { |
| 232 ASSERT(host_len >= NI_MAXHOST); | 217 ASSERT(host_len >= NI_MAXHOST); |
| 233 int status = NO_RETRY_EXPECTED( | 218 int status = NO_RETRY_EXPECTED( |
| 234 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, | 219 getnameinfo(&addr.addr, SocketAddress::GetAddrLength(addr), host, |
| 235 host_len, NULL, 0, NI_NAMEREQD)); | 220 host_len, NULL, 0, NI_NAMEREQD)); |
| 236 if (status != 0) { | 221 if (status != 0) { |
| 237 ASSERT(*os_error == NULL); | 222 ASSERT(*os_error == NULL); |
| 238 *os_error = | 223 *os_error = |
| 239 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); | 224 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); |
| 240 return false; | 225 return false; |
| 241 } | 226 } |
| 242 return true; | 227 return true; |
| 243 } | 228 } |
| 244 | 229 |
| 245 | |
| 246 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { | 230 bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) { |
| 247 int result; | 231 int result; |
| 248 if (type == SocketAddress::TYPE_IPV4) { | 232 if (type == SocketAddress::TYPE_IPV4) { |
| 249 result = inet_pton(AF_INET, address, &addr->in.sin_addr); | 233 result = inet_pton(AF_INET, address, &addr->in.sin_addr); |
| 250 } else { | 234 } else { |
| 251 ASSERT(type == SocketAddress::TYPE_IPV6); | 235 ASSERT(type == SocketAddress::TYPE_IPV6); |
| 252 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); | 236 result = inet_pton(AF_INET6, address, &addr->in6.sin6_addr); |
| 253 } | 237 } |
| 254 return (result == 1); | 238 return (result == 1); |
| 255 } | 239 } |
| 256 | 240 |
| 257 | |
| 258 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { | 241 static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) { |
| 259 if (ifa->ifa_addr == NULL) { | 242 if (ifa->ifa_addr == NULL) { |
| 260 // OpenVPN's virtual device tun0. | 243 // OpenVPN's virtual device tun0. |
| 261 return false; | 244 return false; |
| 262 } | 245 } |
| 263 int family = ifa->ifa_addr->sa_family; | 246 int family = ifa->ifa_addr->sa_family; |
| 264 return ((lookup_family == family) || | 247 return ((lookup_family == family) || |
| 265 ((lookup_family == AF_UNSPEC) && | 248 ((lookup_family == AF_UNSPEC) && |
| 266 ((family == AF_INET) || (family == AF_INET6)))); | 249 ((family == AF_INET) || (family == AF_INET6)))); |
| 267 } | 250 } |
| 268 | 251 |
| 269 | |
| 270 bool SocketBase::ListInterfacesSupported() { | 252 bool SocketBase::ListInterfacesSupported() { |
| 271 return true; | 253 return true; |
| 272 } | 254 } |
| 273 | 255 |
| 274 | |
| 275 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( | 256 AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces( |
| 276 int type, | 257 int type, |
| 277 OSError** os_error) { | 258 OSError** os_error) { |
| 278 struct ifaddrs* ifaddr; | 259 struct ifaddrs* ifaddr; |
| 279 | 260 |
| 280 int status = getifaddrs(&ifaddr); | 261 int status = getifaddrs(&ifaddr); |
| 281 if (status != 0) { | 262 if (status != 0) { |
| 282 ASSERT(*os_error == NULL); | 263 ASSERT(*os_error == NULL); |
| 283 *os_error = | 264 *os_error = |
| 284 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); | 265 new OSError(status, gai_strerror(status), OSError::kGetAddressInfo); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 303 addresses->SetAt( | 284 addresses->SetAt( |
| 304 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, | 285 i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name, |
| 305 if_nametoindex(ifa->ifa_name))); | 286 if_nametoindex(ifa->ifa_name))); |
| 306 i++; | 287 i++; |
| 307 } | 288 } |
| 308 } | 289 } |
| 309 freeifaddrs(ifaddr); | 290 freeifaddrs(ifaddr); |
| 310 return addresses; | 291 return addresses; |
| 311 } | 292 } |
| 312 | 293 |
| 313 | |
| 314 void SocketBase::Close(intptr_t fd) { | 294 void SocketBase::Close(intptr_t fd) { |
| 315 ASSERT(fd >= 0); | 295 ASSERT(fd >= 0); |
| 316 VOID_TEMP_FAILURE_RETRY(close(fd)); | 296 VOID_TEMP_FAILURE_RETRY(close(fd)); |
| 317 } | 297 } |
| 318 | 298 |
| 319 | |
| 320 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { | 299 bool SocketBase::GetNoDelay(intptr_t fd, bool* enabled) { |
| 321 int on; | 300 int on; |
| 322 socklen_t len = sizeof(on); | 301 socklen_t len = sizeof(on); |
| 323 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, | 302 int err = NO_RETRY_EXPECTED(getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, |
| 324 reinterpret_cast<void*>(&on), &len)); | 303 reinterpret_cast<void*>(&on), &len)); |
| 325 if (err == 0) { | 304 if (err == 0) { |
| 326 *enabled = (on == 1); | 305 *enabled = (on == 1); |
| 327 } | 306 } |
| 328 return (err == 0); | 307 return (err == 0); |
| 329 } | 308 } |
| 330 | 309 |
| 331 | |
| 332 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { | 310 bool SocketBase::SetNoDelay(intptr_t fd, bool enabled) { |
| 333 int on = enabled ? 1 : 0; | 311 int on = enabled ? 1 : 0; |
| 334 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, | 312 return NO_RETRY_EXPECTED(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, |
| 335 reinterpret_cast<char*>(&on), | 313 reinterpret_cast<char*>(&on), |
| 336 sizeof(on))) == 0; | 314 sizeof(on))) == 0; |
| 337 } | 315 } |
| 338 | 316 |
| 339 | |
| 340 bool SocketBase::GetMulticastLoop(intptr_t fd, | 317 bool SocketBase::GetMulticastLoop(intptr_t fd, |
| 341 intptr_t protocol, | 318 intptr_t protocol, |
| 342 bool* enabled) { | 319 bool* enabled) { |
| 343 uint8_t on; | 320 uint8_t on; |
| 344 socklen_t len = sizeof(on); | 321 socklen_t len = sizeof(on); |
| 345 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 322 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 346 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 323 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
| 347 : IPV6_MULTICAST_LOOP; | 324 : IPV6_MULTICAST_LOOP; |
| 348 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, | 325 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, |
| 349 reinterpret_cast<char*>(&on), &len)) == 0) { | 326 reinterpret_cast<char*>(&on), &len)) == 0) { |
| 350 *enabled = (on == 1); | 327 *enabled = (on == 1); |
| 351 return true; | 328 return true; |
| 352 } | 329 } |
| 353 return false; | 330 return false; |
| 354 } | 331 } |
| 355 | 332 |
| 356 | |
| 357 bool SocketBase::SetMulticastLoop(intptr_t fd, | 333 bool SocketBase::SetMulticastLoop(intptr_t fd, |
| 358 intptr_t protocol, | 334 intptr_t protocol, |
| 359 bool enabled) { | 335 bool enabled) { |
| 360 u_int on = enabled ? 1 : 0; | 336 u_int on = enabled ? 1 : 0; |
| 361 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 337 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 362 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP | 338 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_LOOP |
| 363 : IPV6_MULTICAST_LOOP; | 339 : IPV6_MULTICAST_LOOP; |
| 364 return NO_RETRY_EXPECTED(setsockopt( | 340 return NO_RETRY_EXPECTED(setsockopt( |
| 365 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == | 341 fd, level, optname, reinterpret_cast<char*>(&on), sizeof(on))) == |
| 366 0; | 342 0; |
| 367 } | 343 } |
| 368 | 344 |
| 369 | |
| 370 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { | 345 bool SocketBase::GetMulticastHops(intptr_t fd, intptr_t protocol, int* value) { |
| 371 uint8_t v; | 346 uint8_t v; |
| 372 socklen_t len = sizeof(v); | 347 socklen_t len = sizeof(v); |
| 373 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 348 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 374 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 349 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
| 375 : IPV6_MULTICAST_HOPS; | 350 : IPV6_MULTICAST_HOPS; |
| 376 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, | 351 if (NO_RETRY_EXPECTED(getsockopt(fd, level, optname, |
| 377 reinterpret_cast<char*>(&v), &len)) == 0) { | 352 reinterpret_cast<char*>(&v), &len)) == 0) { |
| 378 *value = v; | 353 *value = v; |
| 379 return true; | 354 return true; |
| 380 } | 355 } |
| 381 return false; | 356 return false; |
| 382 } | 357 } |
| 383 | 358 |
| 384 | |
| 385 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { | 359 bool SocketBase::SetMulticastHops(intptr_t fd, intptr_t protocol, int value) { |
| 386 int v = value; | 360 int v = value; |
| 387 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; | 361 int level = protocol == SocketAddress::TYPE_IPV4 ? IPPROTO_IP : IPPROTO_IPV6; |
| 388 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL | 362 int optname = protocol == SocketAddress::TYPE_IPV4 ? IP_MULTICAST_TTL |
| 389 : IPV6_MULTICAST_HOPS; | 363 : IPV6_MULTICAST_HOPS; |
| 390 return NO_RETRY_EXPECTED(setsockopt( | 364 return NO_RETRY_EXPECTED(setsockopt( |
| 391 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; | 365 fd, level, optname, reinterpret_cast<char*>(&v), sizeof(v))) == 0; |
| 392 } | 366 } |
| 393 | 367 |
| 394 | |
| 395 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { | 368 bool SocketBase::GetBroadcast(intptr_t fd, bool* enabled) { |
| 396 int on; | 369 int on; |
| 397 socklen_t len = sizeof(on); | 370 socklen_t len = sizeof(on); |
| 398 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, | 371 int err = NO_RETRY_EXPECTED(getsockopt(fd, SOL_SOCKET, SO_BROADCAST, |
| 399 reinterpret_cast<char*>(&on), &len)); | 372 reinterpret_cast<char*>(&on), &len)); |
| 400 if (err == 0) { | 373 if (err == 0) { |
| 401 *enabled = (on == 1); | 374 *enabled = (on == 1); |
| 402 } | 375 } |
| 403 return (err == 0); | 376 return (err == 0); |
| 404 } | 377 } |
| 405 | 378 |
| 406 | |
| 407 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { | 379 bool SocketBase::SetBroadcast(intptr_t fd, bool enabled) { |
| 408 int on = enabled ? 1 : 0; | 380 int on = enabled ? 1 : 0; |
| 409 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, | 381 return NO_RETRY_EXPECTED(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, |
| 410 reinterpret_cast<char*>(&on), | 382 reinterpret_cast<char*>(&on), |
| 411 sizeof(on))) == 0; | 383 sizeof(on))) == 0; |
| 412 } | 384 } |
| 413 | 385 |
| 414 | |
| 415 static bool JoinOrLeaveMulticast(intptr_t fd, | 386 static bool JoinOrLeaveMulticast(intptr_t fd, |
| 416 const RawAddr& addr, | 387 const RawAddr& addr, |
| 417 const RawAddr& interface, | 388 const RawAddr& interface, |
| 418 int interfaceIndex, | 389 int interfaceIndex, |
| 419 bool join) { | 390 bool join) { |
| 420 if (addr.addr.sa_family == AF_INET) { | 391 if (addr.addr.sa_family == AF_INET) { |
| 421 ASSERT(interface.addr.sa_family == AF_INET); | 392 ASSERT(interface.addr.sa_family == AF_INET); |
| 422 struct ip_mreq mreq; | 393 struct ip_mreq mreq; |
| 423 memmove(&mreq.imr_multiaddr, &addr.in.sin_addr, | 394 memmove(&mreq.imr_multiaddr, &addr.in.sin_addr, |
| 424 SocketAddress::GetInAddrLength(addr)); | 395 SocketAddress::GetInAddrLength(addr)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 447 } | 418 } |
| 448 } | 419 } |
| 449 | 420 |
| 450 bool SocketBase::JoinMulticast(intptr_t fd, | 421 bool SocketBase::JoinMulticast(intptr_t fd, |
| 451 const RawAddr& addr, | 422 const RawAddr& addr, |
| 452 const RawAddr& interface, | 423 const RawAddr& interface, |
| 453 int interfaceIndex) { | 424 int interfaceIndex) { |
| 454 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); | 425 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, true); |
| 455 } | 426 } |
| 456 | 427 |
| 457 | |
| 458 bool SocketBase::LeaveMulticast(intptr_t fd, | 428 bool SocketBase::LeaveMulticast(intptr_t fd, |
| 459 const RawAddr& addr, | 429 const RawAddr& addr, |
| 460 const RawAddr& interface, | 430 const RawAddr& interface, |
| 461 int interfaceIndex) { | 431 int interfaceIndex) { |
| 462 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); | 432 return JoinOrLeaveMulticast(fd, addr, interface, interfaceIndex, false); |
| 463 } | 433 } |
| 464 | 434 |
| 465 } // namespace bin | 435 } // namespace bin |
| 466 } // namespace dart | 436 } // namespace dart |
| 467 | 437 |
| 468 #endif // defined(HOST_OS_MACOS) | 438 #endif // defined(HOST_OS_MACOS) |
| 469 | 439 |
| 470 #endif // !defined(DART_IO_DISABLED) | 440 #endif // !defined(DART_IO_DISABLED) |
| OLD | NEW |