Skip to content

Commit

Permalink
Fixes NetworkInterface.list crash on Android
Browse files Browse the repository at this point in the history
Previously, Socket::ListInterfaces failed to set the os_error out
parameter causing a crash in the caller. This change sets an error here.

I've also added NetworkInterface.listSupported, which returns false on
Android, and true everywhere else. ifaddrs.h continues not to exist in
the NDK, so in order to support NetworkInterface.list, we'd have to
reimplement it, or find a suitable reimplementation somewhere.

related #26329

R=johnmccutchan@google.com

Review URL: https://codereview.chromium.org/1916223003 .
  • Loading branch information
zanderso committed Apr 26, 2016
1 parent 099f227 commit ba550f1
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
* `Uri.replace` supports iterables as values for the query parameters.
* `Uri.parseIPv6Address` returns a `Uint8List`.

* `dart:io`
* Added `NetworkInterface.listSupported`, which is `true` when
`NetworkInterface.list` is supported, and `false` otherwise. Currently,
`NetworkInterface.list` is not supported on Android.

## 1.16.0

### Core library changes
Expand Down
1 change: 1 addition & 0 deletions runtime/bin/io_natives.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ namespace bin {
V(Filter_Processed, 3) \
V(InternetAddress_Parse, 1) \
V(IOService_NewServicePort, 0) \
V(NetworkInterface_ListSupported, 0) \
V(Platform_NumberOfProcessors, 0) \
V(Platform_OperatingSystem, 0) \
V(Platform_PathSeparator, 0) \
Expand Down
5 changes: 5 additions & 0 deletions runtime/bin/socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
}


void FUNCTION_NAME(NetworkInterface_ListSupported)(Dart_NativeArguments args) {
Dart_SetReturnValue(args, Dart_NewBoolean(Socket::ListInterfacesSupported()));
}


void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) {
RawAddr addr;
SocketAddress::GetSockAddr(Dart_GetNativeArgument(args, 1), &addr);
Expand Down
3 changes: 3 additions & 0 deletions runtime/bin/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ class Socket {
static bool ParseAddress(int type, const char* address, RawAddr* addr);
static bool FormatNumericAddress(const RawAddr& addr, char* address, int len);

// Whether ListInterfaces is supported.
static bool ListInterfacesSupported();

// List interfaces. Returns a AddressList of InterfaceSocketAddress's.
static AddressList<InterfaceSocketAddress>* ListInterfaces(
int type,
Expand Down
10 changes: 10 additions & 0 deletions runtime/bin/socket_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,21 @@ intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) {
}


bool Socket::ListInterfacesSupported() {
return false;
}


AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
int type,
OSError** os_error) {
// The ifaddrs.h header is not provided on Android. An Android
// implementation would have to use IOCTL or netlink.
ASSERT(*os_error == NULL);
*os_error = new OSError(-1,
"Listing interfaces is not supported "
"on this platform",
OSError::kSystem);
return NULL;
}

Expand Down
5 changes: 5 additions & 0 deletions runtime/bin/socket_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
}


bool Socket::ListInterfacesSupported() {
return true;
}


AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
int type,
OSError** os_error) {
Expand Down
5 changes: 5 additions & 0 deletions runtime/bin/socket_macos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ static bool ShouldIncludeIfaAddrs(struct ifaddrs* ifa, int lookup_family) {
}


bool Socket::ListInterfacesSupported() {
return true;
}


AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
int type,
OSError** os_error) {
Expand Down
6 changes: 6 additions & 0 deletions runtime/bin/socket_patch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ patch class InternetAddress {
}

patch class NetworkInterface {
/* patch */ static bool get listSupported {
return _listSupported();
}

/* patch */ static Future<List<NetworkInterface>> list({
bool includeLoopback: false,
bool includeLinkLocal: false,
Expand All @@ -57,6 +61,8 @@ patch class NetworkInterface {
includeLinkLocal: includeLinkLocal,
type: type);
}

static bool _listSupported() native "NetworkInterface_ListSupported";
}

class _InternetAddress implements InternetAddress {
Expand Down
6 changes: 6 additions & 0 deletions runtime/bin/socket_unsupported.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
}


void FUNCTION_NAME(NetworkInterface_ListSupported)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Sockets unsupported on this platform"));
}


void FUNCTION_NAME(Socket_CreateConnect)(Dart_NativeArguments args) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
"Sockets unsupported on this platform"));
Expand Down
5 changes: 5 additions & 0 deletions runtime/bin/socket_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ intptr_t Socket::CreateBindDatagram(const RawAddr& addr, bool reuseAddress) {
}


bool Socket::ListInterfacesSupported() {
return true;
}


AddressList<InterfaceSocketAddress>* Socket::ListInterfaces(
int type,
OSError** os_error) {
Expand Down
4 changes: 4 additions & 0 deletions sdk/lib/_internal/js_runtime/lib/io_patch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ class InternetAddress {

@patch
class NetworkInterface {
@patch
static bool get listSupported {
throw new UnsupportedError("NetworkInterface.listSupported");
}
@patch
static Future<List<NetworkInterface>> list({
bool includeLoopback: false,
Expand Down
13 changes: 10 additions & 3 deletions sdk/lib/io/socket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ abstract class InternetAddress {


/**
* A [NetworkInterface] represent an active network interface on the current
* system. It contains a list of [InternetAddress]s, that's bound to the
* A [NetworkInterface] represents an active network interface on the current
* system. It contains a list of [InternetAddress]es that are bound to the
* interface.
*/
abstract class NetworkInterface {
Expand All @@ -161,11 +161,18 @@ abstract class NetworkInterface {
String get index;

/**
* Get a list of [InternetAddress]s currently bound to this
* Get a list of [InternetAddress]es currently bound to this
* [NetworkInterface].
*/
List<InternetAddress> get addresses;

/**
* Whether [list] is supported.
*
* [list] is currently unsupported on Android.
*/
external static bool get listSupported;

/**
* Query the system for [NetworkInterface]s.
*
Expand Down
3 changes: 3 additions & 0 deletions tests/standalone/io/network_interface_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ void testListIndex() {


void main() {
if (!NetworkInterface.listSupported) {
return;
}
testListLoopback();
testListLinkLocal();
testListIndex();
Expand Down

0 comments on commit ba550f1

Please sign in to comment.