Skip to content

Commit 085f812

Browse files
tamirdcommit-bot@chromium.org
authored andcommitted
[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 <[email protected]> Auto-Submit: Tamir Duberstein <[email protected]> Reviewed-by: Zach Anderson <[email protected]> Reviewed-by: Chinmay Garde <[email protected]>
1 parent cb80ea7 commit 085f812

File tree

2 files changed

+73
-66
lines changed

2 files changed

+73
-66
lines changed

runtime/bin/BUILD.gn

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,12 @@ template("build_gen_snapshot_dart_io") {
266266

267267
if (is_fuchsia) {
268268
if (using_fuchsia_sdk) {
269-
deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
269+
deps += [ "$fuchsia_sdk_root/fidl:fuchsia.netstack" ]
270270
public_deps = [
271271
"$fuchsia_sdk_root/pkg:fdio",
272272
]
273273
} else {
274-
deps += [ "//garnet/public/lib/netstack/c" ]
274+
deps += [ "//sdk/fidl/fuchsia.netstack" ]
275275
public_deps = [
276276
"//zircon/public/lib/fdio",
277277
]
@@ -388,12 +388,12 @@ template("dart_io") {
388388

389389
if (is_fuchsia) {
390390
if (using_fuchsia_sdk) {
391-
deps += [ "$fuchsia_sdk_root/pkg/lib/netstack/c" ]
391+
deps += [ "$fuchsia_sdk_root/fidl:fuchsia.netstack" ]
392392
public_deps = [
393393
"$fuchsia_sdk_root/pkg:fdio",
394394
]
395395
} else {
396-
deps += [ "//garnet/public/lib/netstack/c" ]
396+
deps += [ "//sdk/fidl/fuchsia.netstack" ]
397397
public_deps = [
398398
"//zircon/public/lib/fdio",
399399
]

runtime/bin/socket_base_fuchsia.cc

Lines changed: 69 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,18 @@
77

88
#include "bin/socket_base.h"
99

10-
// TODO(ZX-766): If/when Fuchsia adds getifaddrs(), use that instead of the
11-
// ioctl in netconfig.h.
12-
#include <errno.h> // NOLINT
13-
#include <fcntl.h> // NOLINT
14-
#include <ifaddrs.h> // NOLINT
15-
#include <lib/netstack/c/netconfig.h>
16-
#include <net/if.h> // NOLINT
17-
#include <netinet/tcp.h> // NOLINT
18-
#include <stdio.h> // NOLINT
19-
#include <stdlib.h> // NOLINT
20-
#include <string.h> // NOLINT
21-
#include <sys/ioctl.h> // NOLINT
22-
#include <sys/stat.h> // NOLINT
23-
#include <unistd.h> // NOLINT
10+
#include <errno.h>
11+
#include <fuchsia/netstack/cpp/fidl.h>
12+
#include <ifaddrs.h>
13+
#include <lib/sys/cpp/service_directory.h>
14+
#include <net/if.h>
15+
#include <netinet/tcp.h>
16+
#include <stdio.h>
17+
#include <stdlib.h>
18+
#include <string.h>
19+
#include <sys/stat.h>
20+
#include <unistd.h>
21+
#include <vector>
2422

2523
#include "bin/eventhandler.h"
2624
#include "bin/fdutils.h"
@@ -66,9 +64,20 @@ SocketAddress::SocketAddress(struct sockaddr* sa) {
6664
memmove(reinterpret_cast<void*>(&addr_), sa, salen);
6765
}
6866

67+
static fidl::SynchronousInterfacePtr<fuchsia::netstack::Netstack> netstack;
68+
static zx_status_t status;
69+
static std::once_flag once;
70+
6971
bool SocketBase::Initialize() {
70-
// Nothing to do on Fuchsia.
71-
return true;
72+
std::call_once(once, [&]() {
73+
auto directory = sys::ServiceDirectory::CreateFromNamespace();
74+
status = directory->Connect(netstack.NewRequest());
75+
if (status != ZX_OK) {
76+
LOG_ERR("Initialize: connecting to fuchsia.netstack failed: %s\n",
77+
zx_status_get_string(status));
78+
}
79+
});
80+
return status == ZX_OK;
7281
}
7382

7483
bool SocketBase::FormatNumericAddress(const RawAddr& addr,
@@ -264,68 +273,66 @@ bool SocketBase::ParseAddress(int type, const char* address, RawAddr* addr) {
264273
return (result == 1);
265274
}
266275

267-
static bool ShouldIncludeIfaAddrs(netc_if_info_t* if_info, int lookup_family) {
268-
const int family = if_info->addr.ss_family;
269-
return ((lookup_family == family) ||
270-
(((lookup_family == AF_UNSPEC) &&
271-
((family == AF_INET) || (family == AF_INET6)))));
272-
}
273-
274276
bool SocketBase::ListInterfacesSupported() {
275277
return true;
276278
}
277279

278280
AddressList<InterfaceSocketAddress>* SocketBase::ListInterfaces(
279281
int type,
280282
OSError** os_error) {
281-
// We need a dummy socket.
282-
const int fd = socket(AF_INET6, SOCK_STREAM, 0);
283-
if (fd < 0) {
284-
LOG_ERR("ListInterfaces: socket(AF_INET, SOCK_DGRAM, 0) failed\n");
283+
std::vector<fuchsia::netstack::NetInterface2> interfaces;
284+
zx_status_t status = netstack->GetInterfaces2(&interfaces);
285+
if (status != ZX_OK) {
286+
LOG_ERR("ListInterfaces: fuchsia.netstack.GetInterfaces2 failed: %s\n",
287+
zx_status_get_string(status));
288+
errno = EIO;
285289
return NULL;
286290
}
287291

288-
// Call the ioctls.
289-
netc_get_if_info_t get_if_info;
290-
const ssize_t size = ioctl_netc_get_num_ifs(fd, &get_if_info.n_info);
291-
if (size < 0) {
292-
LOG_ERR("ListInterfaces: ioctl_netc_get_num_ifs() failed");
293-
close(fd);
294-
return NULL;
295-
}
296-
for (uint32_t i = 0; i < get_if_info.n_info; i++) {
297-
const ssize_t size =
298-
ioctl_netc_get_if_info_at(fd, &i, &get_if_info.info[i]);
299-
if (size < 0) {
300-
LOG_ERR("ListInterfaces: ioctl_netc_get_if_info_at() failed");
301-
close(fd);
302-
return NULL;
303-
}
304-
}
305-
306292
// Process the results.
307293
const int lookup_family = SocketAddress::FromType(type);
308-
intptr_t count = 0;
309-
for (intptr_t i = 0; i < get_if_info.n_info; i++) {
310-
if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) {
311-
count++;
312-
}
313-
}
314294

315-
AddressList<InterfaceSocketAddress>* addresses =
316-
new AddressList<InterfaceSocketAddress>(count);
295+
std::remove_if(
296+
interfaces.begin(), interfaces.end(),
297+
[lookup_family](const auto& interface) {
298+
switch (interface.addr.Which()) {
299+
case fuchsia::net::IpAddress::Tag::kIpv4:
300+
return !(lookup_family == AF_UNSPEC || lookup_family == AF_INET);
301+
case fuchsia::net::IpAddress::Tag::kIpv6:
302+
return !(lookup_family == AF_UNSPEC || lookup_family == AF_INET6);
303+
case fuchsia::net::IpAddress::Tag::Invalid:
304+
return true;
305+
}
306+
});
307+
308+
auto addresses = new AddressList<InterfaceSocketAddress>(interfaces.size());
317309
int addresses_idx = 0;
318-
for (intptr_t i = 0; i < get_if_info.n_info; i++) {
319-
if (ShouldIncludeIfaAddrs(&get_if_info.info[i], lookup_family)) {
320-
char* ifa_name = DartUtils::ScopedCopyCString(get_if_info.info[i].name);
321-
InterfaceSocketAddress* isa = new InterfaceSocketAddress(
322-
reinterpret_cast<struct sockaddr*>(&get_if_info.info[i].addr),
323-
ifa_name, if_nametoindex(get_if_info.info[i].name));
324-
addresses->SetAt(addresses_idx, isa);
325-
addresses_idx++;
310+
for (const auto& interface : interfaces) {
311+
struct sockaddr_storage addr = {};
312+
auto addr_in = reinterpret_cast<struct sockaddr_in*>(&addr);
313+
auto addr_in6 = reinterpret_cast<struct sockaddr_in6*>(&addr);
314+
switch (interface.addr.Which()) {
315+
case fuchsia::net::IpAddress::Tag::kIpv4:
316+
addr_in->sin_family = AF_INET;
317+
memmove(&addr_in->sin_addr, interface.addr.ipv4().addr.data(),
318+
sizeof(addr_in->sin_addr));
319+
break;
320+
case fuchsia::net::IpAddress::Tag::kIpv6:
321+
addr_in6->sin6_family = AF_INET6;
322+
memmove(&addr_in6->sin6_addr, interface.addr.ipv6().addr.data(),
323+
sizeof(addr_in6->sin6_addr));
324+
break;
325+
case fuchsia::net::IpAddress::Tag::Invalid:
326+
// Should have been filtered out above.
327+
UNREACHABLE();
326328
}
329+
addresses->SetAt(addresses_idx,
330+
new InterfaceSocketAddress(
331+
reinterpret_cast<sockaddr*>(&addr),
332+
DartUtils::ScopedCopyCString(interface.name.c_str()),
333+
if_nametoindex(interface.name.c_str())));
334+
addresses_idx++;
327335
}
328-
close(fd);
329336
return addresses;
330337
}
331338

0 commit comments

Comments
 (0)