mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 15:01:29 +00:00
[fuchsia] migrate from ioctls to FIDL
Bug: https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=6250 Change-Id: If2756bca0b226bfe8e89b4c793933abac540801e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117620 Commit-Queue: Zach Anderson <zra@google.com> Auto-Submit: Tamir Duberstein <tamird@google.com> Reviewed-by: Zach Anderson <zra@google.com> Reviewed-by: Chinmay Garde <chinmaygarde@google.com>
This commit is contained in:
parent
cb80ea7ba9
commit
085f81224a
|
@ -266,12 +266,12 @@ template("build_gen_snapshot_dart_io") {
|
|||
|
||||
if (is_fuchsia) {
|
||||
if (using_fuchsia_sdk) {
|
||||
deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
|
||||
deps += [ "$fuchsia_sdk_root/fidl:fuchsia.netstack" ]
|
||||
public_deps = [
|
||||
"$fuchsia_sdk_root/pkg:fdio",
|
||||
]
|
||||
} else {
|
||||
deps += [ "//garnet/public/lib/netstack/c" ]
|
||||
deps += [ "//sdk/fidl/fuchsia.netstack" ]
|
||||
public_deps = [
|
||||
"//zircon/public/lib/fdio",
|
||||
]
|
||||
|
@ -388,12 +388,12 @@ template("dart_io") {
|
|||
|
||||
if (is_fuchsia) {
|
||||
if (using_fuchsia_sdk) {
|
||||
deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
|
||||
deps += [ "$fuchsia_sdk_root/fidl:fuchsia.netstack" ]
|
||||
public_deps = [
|
||||
"$fuchsia_sdk_root/pkg:fdio",
|
||||
]
|
||||
} else {
|
||||
deps += [ "//garnet/public/lib/netstack/c" ]
|
||||
deps += [ "//sdk/fidl/fuchsia.netstack" ]
|
||||
public_deps = [
|
||||
"//zircon/public/lib/fdio",
|
||||
]
|
||||
|
|
|
@ -7,20 +7,18 @@
|
|||
|
||||
#include "bin/socket_base.h"
|
||||
|
||||
// TODO(ZX-766): If/when Fuchsia adds getifaddrs(), use that instead of the
|
||||
// ioctl in netconfig.h.
|
||||
#include <errno.h> // NOLINT
|
||||
#include <fcntl.h> // NOLINT
|
||||
#include <ifaddrs.h> // NOLINT
|
||||
#include <lib/netstack/c/netconfig.h>
|
||||
#include <net/if.h> // NOLINT
|
||||
#include <netinet/tcp.h> // NOLINT
|
||||
#include <stdio.h> // NOLINT
|
||||
#include <stdlib.h> // NOLINT
|
||||
#include <string.h> // NOLINT
|
||||
#include <sys/ioctl.h> // NOLINT
|
||||
#include <sys/stat.h> // NOLINT
|
||||
#include <unistd.h> // NOLINT
|
||||
#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>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
#include "bin/eventhandler.h"
|
||||
#include "bin/fdutils.h"
|
||||
|
@ -66,9 +64,20 @@ SocketAddress::SocketAddress(struct sockaddr* sa) {
|
|||
memmove(reinterpret_cast<void*>(&addr_), sa, salen);
|
||||
}
|
||||
|
||||
static fidl::SynchronousInterfacePtr<fuchsia::netstack::Netstack> netstack;
|
||||
static zx_status_t status;
|
||||
static std::once_flag once;
|
||||
|
||||
bool SocketBase::Initialize() {
|
||||
// Nothing to do on Fuchsia.
|
||||
return true;
|
||||
std::call_once(once, [&]() {
|
||||
auto directory = sys::ServiceDirectory::CreateFromNamespace();
|
||||
status = directory->Connect(netstack.NewRequest());
|
||||
if (status != ZX_OK) {
|
||||
LOG_ERR("Initialize: connecting to fuchsia.netstack failed: %s\n",
|
||||
zx_status_get_string(status));
|
||||
}
|
||||
});
|
||||
return status == ZX_OK;
|
||||
}
|
||||
|
||||
bool SocketBase::FormatNumericAddress(const RawAddr& addr,
|
||||
|
@ -264,13 +273,6 @@ bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
|
|||
return (result == 1);
|
||||
}
|
||||
|
||||
static bool ShouldIncludeIfaAddrs(netc_if_info_t* if_info, int lookup_family) {
|
||||
const int family = if_info->addr.ss_family;
|
||||
return ((lookup_family == family) ||
|
||||
(((lookup_family == AF_UNSPEC) &&
|
||||
((family == AF_INET) || (family == AF_INET6)))));
|
||||
}
|
||||
|
||||
bool SocketBase::ListInterfacesSupported() {
|
||||
return true;
|
||||
}
|
||||
|
@ -278,54 +280,59 @@ bool SocketBase::ListInterfacesSupported() {
|
|||
AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
|
||||
int type,
|
||||
OSError** os_error) {
|
||||
// We need a dummy socket.
|
||||
const int fd = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
LOG_ERR("ListInterfaces: socket(AF_INET, SOCK_DGRAM, 0) failed\n");
|
||||
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;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Call the ioctls.
|
||||
netc_get_if_info_t get_if_info;
|
||||
const ssize_t size = ioctl_netc_get_num_ifs(fd, &get_if_info.n_info);
|
||||
if (size < 0) {
|
||||
LOG_ERR("ListInterfaces: ioctl_netc_get_num_ifs() failed");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
for (uint32_t i = 0; i < get_if_info.n_info; i++) {
|
||||
const ssize_t size =
|
||||
ioctl_netc_get_if_info_at(fd, &i, &get_if_info.info[i]);
|
||||
if (size < 0) {
|
||||
LOG_ERR("ListInterfaces: ioctl_netc_get_if_info_at() failed");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Process the results.
|
||||
const int lookup_family = SocketAddress::FromType(type);
|
||||
intptr_t count = 0;
|
||||
for (intptr_t i = 0; i < get_if_info.n_info; i++) {
|
||||
if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
AddressList<InterfaceSocketAddress>* addresses =
|
||||
new AddressList<InterfaceSocketAddress>(count);
|
||||
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 (intptr_t i = 0; i < get_if_info.n_info; i++) {
|
||||
if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) {
|
||||
char* ifa_name = DartUtils::ScopedCopyCString(get_if_info.info[i].name);
|
||||
InterfaceSocketAddress* isa = new InterfaceSocketAddress(
|
||||
reinterpret_cast<struct sockaddr*>(&get_if_info.info[i].addr),
|
||||
ifa_name, if_nametoindex(get_if_info.info[i].name));
|
||||
addresses->SetAt(addresses_idx, isa);
|
||||
addresses_idx++;
|
||||
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();
|
||||
}
|
||||
addresses->SetAt(addresses_idx,
|
||||
new InterfaceSocketAddress(
|
||||
reinterpret_cast<sockaddr*>(&addr),
|
||||
DartUtils::ScopedCopyCString(interface.name.c_str()),
|
||||
if_nametoindex(interface.name.c_str())));
|
||||
addresses_idx++;
|
||||
}
|
||||
close(fd);
|
||||
return addresses;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue