Chromium Code Reviews| Index: runtime/bin/socket_linux.cc |
| diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc |
| index 04ecbe7c836609e9e57c2b21e839a78a092e9371..dfe0c46df1518c14ebe7db446da7614762d8188d 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)); |
| } |
| @@ -184,9 +186,9 @@ intptr_t Socket::GetStdioHandle(int num) { |
| } |
| -SocketAddresses* Socket::LookupAddress(const char* host, |
| - int type, |
| - OSError** os_error) { |
| +AddressList<SocketAddress>* Socket::LookupAddress(const char* host, |
| + int type, |
| + OSError** os_error) { |
| // Perform a name lookup for a host name. |
| struct addrinfo hints; |
| memset(&hints, 0, sizeof(hints)); |
| @@ -207,11 +209,11 @@ SocketAddresses* Socket::LookupAddress(const char* host, |
| for (struct addrinfo* c = info; c != NULL; c = c->ai_next) { |
| if (c->ai_family == AF_INET || c->ai_family == AF_INET6) count++; |
| } |
| - SocketAddresses* addresses = new SocketAddresses(count); |
| - intptr_t i = 0; |
| + int i = 0; |
| + AddressList<SocketAddress>* addresses = new AddressList<SocketAddress>(count); |
| 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)); |
| + addresses->SetAt(i, new SocketAddress(c->ai_addr)); |
| i++; |
| } |
| } |
| @@ -220,6 +222,50 @@ SocketAddresses* Socket::LookupAddress(const char* host, |
| } |
| +AddressList<InterfaceSocketAddress>* Socket::ListInterfaces( |
| + 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)))) { |
|
Søren Gjesse
2013/06/20 14:38:17
Consider adding a static function
static bool XXX
Anders Johnsen
2013/06/20 15:00:25
Done.
|
| + count++; |
| + } |
| + } |
| + |
| + AddressList<InterfaceSocketAddress>* addresses = |
| + new AddressList<InterfaceSocketAddress>(count); |
| + int i = 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)))) { |
| + addresses->SetAt(i, new InterfaceSocketAddress( |
| + ifa->ifa_addr, strdup(ifa->ifa_name))); |
| + i++; |
| + } |
| + } |
| + freeifaddrs(ifaddr); |
| + return addresses; |
| +} |
| + |
| + |
| intptr_t ServerSocket::CreateBindListen(RawAddr addr, |
| intptr_t port, |
| intptr_t backlog, |