| Index: runtime/bin/socket_linux.cc
|
| diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
|
| index 04ecbe7c836609e9e57c2b21e839a78a092e9371..4067e95409f6e68fb14846c500ce238d0d659077 100644
|
| --- a/runtime/bin/socket_linux.cc
|
| +++ b/runtime/bin/socket_linux.cc
|
| @@ -12,6 +12,8 @@
|
| #include <sys/stat.h> // NOLINT
|
| #include <unistd.h> // NOLINT
|
| #include <netinet/tcp.h> // NOLINT
|
| +#include <ifaddrs.h> // NOLINT
|
| +#include <net/if.h> // NOLINT
|
|
|
| #include "bin/fdutils.h"
|
| #include "bin/file.h"
|
| @@ -22,17 +24,17 @@
|
| namespace dart {
|
| namespace bin {
|
|
|
| -SocketAddress::SocketAddress(struct addrinfo* addrinfo) {
|
| +SocketAddress::SocketAddress(struct sockaddr* sockaddr) {
|
| ASSERT(INET6_ADDRSTRLEN >= INET_ADDRSTRLEN);
|
| - RawAddr* raw = reinterpret_cast<RawAddr*>(addrinfo->ai_addr);
|
| - const char* result = inet_ntop(addrinfo->ai_family,
|
| + RawAddr* raw = reinterpret_cast<RawAddr*>(sockaddr);
|
| + const char* result = inet_ntop(sockaddr->sa_family,
|
| &raw->in.sin_addr,
|
| as_string_,
|
| INET6_ADDRSTRLEN);
|
| if (result == NULL) as_string_[0] = 0;
|
| memmove(reinterpret_cast<void *>(&addr_),
|
| - addrinfo->ai_addr,
|
| - addrinfo->ai_addrlen);
|
| + sockaddr,
|
| + GetAddrLength(*raw));
|
| }
|
|
|
|
|
| @@ -208,11 +210,9 @@ SocketAddresses* Socket::LookupAddress(const char* host,
|
| if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++;
|
| }
|
| SocketAddresses* addresses = new SocketAddresses(count);
|
| - intptr_t i = 0;
|
| for (struct addrinfo* c = info; c != NULL; c = c->ai_next) {
|
| if (c->ai_family == AF_INET || c->ai_family == AF_INET6) {
|
| - addresses->SetAt(i, new SocketAddress(c));
|
| - i++;
|
| + addresses->SetAt(i, new SocketAddress(c->ai_addr));
|
| }
|
| }
|
| freeaddrinfo(info);
|
| @@ -220,6 +220,49 @@ SocketAddresses* Socket::LookupAddress(const char* host,
|
| }
|
|
|
|
|
| +SocketAddresses* Socket::ListAdaptors(bool include_loopback,
|
| + int type,
|
| + OSError** os_error) {
|
| + struct ifaddrs* ifaddr;
|
| +
|
| + int status = getifaddrs(&ifaddr);
|
| + if (status != 0) {
|
| + ASSERT(*os_error == NULL);
|
| + *os_error = new OSError(status,
|
| + gai_strerror(status),
|
| + OSError::kGetAddressInfo);
|
| + return NULL;
|
| + }
|
| +
|
| + int lookup_family = SocketAddress::FromType(type);
|
| +
|
| + intptr_t count = 0;
|
| + for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
| + int family = ifa->ifa_addr->sa_family;
|
| + if ((lookup_family == family ||
|
| + (lookup_family == AF_UNSPEC &&
|
| + (family == AF_INET || family == AF_INET6))) &&
|
| + (include_loopback || (ifa->ifa_flags & IFF_LOOPBACK) == 0)) {
|
| + count++;
|
| + }
|
| + }
|
| +
|
| + SocketAddresses* addresses = new SocketAddresses(count);
|
| + for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
|
| + int family = ifa->ifa_addr->sa_family;
|
| + if ((lookup_family == family ||
|
| + (lookup_family == AF_UNSPEC &&
|
| + (family == AF_INET || family == AF_INET6))) &&
|
| + (include_loopback || (ifa->ifa_flags & IFF_LOOPBACK) == 0)) {
|
| + addresses->SetAt(i, new AdaptorSocketAddress(
|
| + ifa->ifa_addr, strdup(ifa->ifa_name)));
|
| + }
|
| + }
|
| + freeifaddrs(ifaddr);
|
| + return addresses;
|
| +}
|
| +
|
| +
|
| intptr_t ServerSocket::CreateBindListen(RawAddr addr,
|
| intptr_t port,
|
| intptr_t backlog,
|
|
|