Fixes NetworkInterface.list crash on Android

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 .
This commit is contained in:
Zachary Anderson 2016-04-26 07:48:58 -07:00
parent 099f227c17
commit ba550f1c43
13 changed files with 68 additions and 3 deletions

View file

@ -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

View file

@ -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) \

View file

@ -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);

View file

@ -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,

View file

@ -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;
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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,
@ -57,6 +61,8 @@ patch class NetworkInterface {
includeLinkLocal: includeLinkLocal,
type: type);
}
static bool _listSupported() native "NetworkInterface_ListSupported";
}
class _InternetAddress implements InternetAddress {

View file

@ -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"));

View file

@ -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) {

View file

@ -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,

View file

@ -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 {
@ -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.
*

View file

@ -47,6 +47,9 @@ void testListIndex() {
void main() {
if (!NetworkInterface.listSupported) {
return;
}
testListLoopback();
testListLinkLocal();
testListIndex();