[dart:io] Remove dependency on FIDL
ListInterfaces copied from Linux; Fuchsia's fdio implements getifaddrs
since https://fuchsia.googlesource.com/fuchsia/+/a8b1df8.
Change-Id: I6fa03dfa8a446551e4fa1ad3c0309ad51bb93310
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/159220
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Zach Anderson <zra@google.com>
diff --git a/build/fuchsia/dart.cmx b/build/fuchsia/dart.cmx
index f8f5750..d57d9ac 100644
--- a/build/fuchsia/dart.cmx
+++ b/build/fuchsia/dart.cmx
@@ -18,7 +18,6 @@
"fuchsia.intl.PropertyProvider",
"fuchsia.logger.LogSink",
"fuchsia.net.NameLookup",
- "fuchsia.netstack.Netstack",
"fuchsia.posix.socket.Provider",
"fuchsia.sysmem.Allocator",
"fuchsia.timezone.Timezone",
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 2341506..a42626d 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -312,31 +312,18 @@
"..:dart_config",
"..:dart_precompiler_config",
] + extra_configs
- deps = []
if (is_fuchsia) {
if (using_fuchsia_gn_sdk) {
- deps += [
- "$fuchsia_sdk_root/fidl/fuchsia.netstack",
- "$fuchsia_sdk_root/pkg/sys_cpp",
- ]
public_deps = [ "$fuchsia_sdk_root/pkg/fdio" ]
} else if (using_fuchsia_sdk) {
- deps += [
- "$fuchsia_sdk_root/fidl:fuchsia.netstack",
- "$fuchsia_sdk_root/pkg:sys_cpp",
- ]
public_deps = [ "$fuchsia_sdk_root/pkg:fdio" ]
} else {
- deps += [
- "//sdk/fidl/fuchsia.netstack",
- "//sdk/lib/sys/cpp",
- ]
public_deps = [ "//sdk/lib/fdio" ]
}
}
- deps += [ "//third_party/zlib" ]
+ deps = [ "//third_party/zlib" ]
custom_sources_filter = [
"*_test.cc",
@@ -458,22 +445,10 @@
if (is_fuchsia) {
if (using_fuchsia_gn_sdk) {
- deps += [
- "$fuchsia_sdk_root/fidl/fuchsia.netstack",
- "$fuchsia_sdk_root/pkg/sys_cpp",
- ]
public_deps = [ "$fuchsia_sdk_root/pkg/fdio" ]
} else if (using_fuchsia_sdk) {
- deps += [
- "$fuchsia_sdk_root/fidl:fuchsia.netstack",
- "$fuchsia_sdk_root/pkg:sys_cpp",
- ]
public_deps = [ "$fuchsia_sdk_root/pkg:fdio" ]
} else {
- deps += [
- "//sdk/fidl/fuchsia.netstack",
- "//sdk/lib/sys/cpp",
- ]
public_deps = [ "//sdk/lib/fdio" ]
}
}
diff --git a/runtime/bin/socket_base_fuchsia.cc b/runtime/bin/socket_base_fuchsia.cc
index b76b6c6..be1eb256 100644
--- a/runtime/bin/socket_base_fuchsia.cc
+++ b/runtime/bin/socket_base_fuchsia.cc
@@ -8,9 +8,7 @@
#include "bin/socket_base.h"
#include <errno.h>
-#include <fuchsia/netstack/cpp/fidl.h>
#include <ifaddrs.h>
-#include <lib/sys/cpp/service_directory.h>
#include <net/if.h>
#include <netinet/tcp.h>
#include <stdio.h>
@@ -68,21 +66,10 @@
memmove(reinterpret_cast<void*>(&addr_), sa, salen);
}
-static fidl::SynchronousInterfacePtr<fuchsia::netstack::Netstack> netstack;
-static std::once_flag once;
bool SocketBase::Initialize() {
- static zx_status_t status;
- std::call_once(once, [&]() {
- auto directory = sys::ServiceDirectory::CreateFromNamespace();
- status = directory->Connect(netstack.NewRequest());
- if (status != ZX_OK) {
- Syslog::PrintErr(
- "Initialize: connecting to fuchsia.netstack failed: %s\n",
- zx_status_get_string(status));
- }
- });
- return status == ZX_OK;
+ // Nothing to do on Fuchsia.
+ return true;
}
bool SocketBase::FormatNumericAddress(const RawAddr& addr,
@@ -294,6 +281,17 @@
}
}
+static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
+ if (ifa->ifa_addr == NULL) {
+ // OpenVPN's virtual device tun0.
+ return false;
+ }
+ int family = ifa->ifa_addr->sa_family;
+ return ((lookup_family == family) ||
+ (((lookup_family == AF_UNSPEC) &&
+ ((family == AF_INET) || (family == AF_INET6)))));
+}
+
bool SocketBase::ListInterfacesSupported() {
return true;
}
@@ -301,59 +299,38 @@
AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
int type,
OSError** os_error) {
- std::vector<fuchsia::netstack::NetInterface2> interfaces;
- zx_status_t status = netstack->GetInterfaces2(&interfaces);
- if (status != ZX_OK) {
- LOG_ERR("ListInterfaces: fuchsia.netstack.GetInterfaces2 failed: %s\n",
- zx_status_get_string(status));
- errno = EIO;
+ struct ifaddrs* ifaddr;
+
+ int status = NO_RETRY_EXPECTED(getifaddrs(&ifaddr));
+ if (status != 0) {
+ ASSERT(*os_error == NULL);
+ *os_error =
+ new OSError(status, gai_strerror(status), OSError::kGetAddressInfo);
return NULL;
}
- // Process the results.
- const int lookup_family = SocketAddress::FromType(type);
+ int lookup_family = SocketAddress::FromType(type);
- std::remove_if(
- interfaces.begin(), interfaces.end(),
- [lookup_family](const auto& interface) {
- switch (interface.addr.Which()) {
- case fuchsia::net::IpAddress::Tag::kIpv4:
- return !(lookup_family == AF_UNSPEC || lookup_family == AF_INET);
- case fuchsia::net::IpAddress::Tag::kIpv6:
- return !(lookup_family == AF_UNSPEC || lookup_family == AF_INET6);
- case fuchsia::net::IpAddress::Tag::Invalid:
- return true;
- }
- });
-
- auto addresses = new AddressList<InterfaceSocketAddress>(interfaces.size());
- int addresses_idx = 0;
- for (const auto& interface : interfaces) {
- struct sockaddr_storage addr = {};
- auto addr_in = reinterpret_cast<struct sockaddr_in*>(&addr);
- auto addr_in6 = reinterpret_cast<struct sockaddr_in6*>(&addr);
- switch (interface.addr.Which()) {
- case fuchsia::net::IpAddress::Tag::kIpv4:
- addr_in->sin_family = AF_INET;
- memmove(&addr_in->sin_addr, interface.addr.ipv4().addr.data(),
- sizeof(addr_in->sin_addr));
- break;
- case fuchsia::net::IpAddress::Tag::kIpv6:
- addr_in6->sin6_family = AF_INET6;
- memmove(&addr_in6->sin6_addr, interface.addr.ipv6().addr.data(),
- sizeof(addr_in6->sin6_addr));
- break;
- case fuchsia::net::IpAddress::Tag::Invalid:
- // Should have been filtered out above.
- UNREACHABLE();
+ intptr_t count = 0;
+ for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+ count++;
}
- addresses->SetAt(addresses_idx,
- new InterfaceSocketAddress(
- reinterpret_cast<sockaddr*>(&addr),
- DartUtils::ScopedCopyCString(interface.name.c_str()),
- if_nametoindex(interface.name.c_str())));
- addresses_idx++;
}
+
+ AddressList<InterfaceSocketAddress>* addresses =
+ new AddressList<InterfaceSocketAddress>(count);
+ int i = 0;
+ for (struct ifaddrs* ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (ShouldIncludeIfaAddrs(ifa, lookup_family)) {
+ char* ifa_name = DartUtils::ScopedCopyCString(ifa->ifa_name);
+ addresses->SetAt(
+ i, new InterfaceSocketAddress(ifa->ifa_addr, ifa_name,
+ if_nametoindex(ifa->ifa_name)));
+ i++;
+ }
+ }
+ freeifaddrs(ifaddr);
return addresses;
}