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