From 3c600a15a1ab35272405c8902a6ab92e46f18ce4 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Thu, 10 Jan 2019 19:12:46 +0900 Subject: [PATCH 1/2] Move IpClient to NetworkStack Test: atest FrameworksNetTests NetworkStackTests Bug: b/112869080 Change-Id: I7d00848c052382cd1b6ce458868bed6a1e9e8ec5 --- .../net/INetworkManagementEventObserver.aidl | 2 +- .../android/net/INetworkStackConnector.aidl | 2 + core/java/android/net/NetworkStack.java | 16 + .../net/util/MultinetworkPolicyTracker.java | 0 packages/NetworkStack/Android.bp | 2 +- packages/NetworkStack/AndroidManifest.xml | 1 + .../src}/android/net/apf/ApfFilter.java | 16 +- .../src}/android/net/apf/ApfGenerator.java | 0 .../src}/android/net/dhcp/DhcpAckPacket.java | 0 .../src}/android/net/dhcp/DhcpClient.java | 0 .../android/net/dhcp/DhcpDeclinePacket.java | 0 .../android/net/dhcp/DhcpDiscoverPacket.java | 0 .../android/net/dhcp/DhcpInformPacket.java | 0 .../src}/android/net/dhcp/DhcpNakPacket.java | 0 .../android/net/dhcp/DhcpOfferPacket.java | 0 .../src}/android/net/dhcp/DhcpPacket.java | 0 .../android/net/dhcp/DhcpReleasePacket.java | 0 .../android/net/dhcp/DhcpRequestPacket.java | 0 .../net/ip/ConnectivityPacketTracker.java | 0 .../src}/android/net/ip/IpClient.java | 301 +++++++----------- .../android/net/ip/IpNeighborMonitor.java | 0 .../android/net/ip/IpReachabilityMonitor.java | 0 .../net/util/ConnectivityPacketSummary.java | 96 +++--- .../src}/android/net/util/FdEventsReader.java | 0 .../src}/android/net/util/PacketReader.java | 0 .../android/server/NetworkStackService.java | 53 +++ .../server/util/NetworkStackConstants.java | 91 ++++++ packages/NetworkStack/tests/Android.bp | 67 +++- .../NetworkStack/tests/AndroidManifest.xml | 29 ++ .../NetworkStack/tests}/jni/apf_jni.cpp | 0 .../NetworkStack/tests}/res/raw/apf.pcap | Bin .../NetworkStack/tests}/res/raw/apfPcap.pcap | Bin .../tests/src}/android/net/apf/ApfTest.java | 27 +- .../tests/src}/android/net/apf/Bpf2Apf.java | 0 .../src}/android/net/dhcp/DhcpPacketTest.java | 0 .../src}/android/net/ip/IpClientTest.java | 34 +- .../net/ip/IpReachabilityMonitorTest.java | 0 .../util/ConnectivityPacketSummaryTest.java | 0 .../android/net/util/PacketReaderTest.java | 0 .../android/server/ConnectivityService.java | 2 +- .../java/com/android/server/IpSecService.java | 2 +- .../server/NetworkManagementService.java | 2 +- .../connectivity/IpConnectivityMetrics.java | 14 - services/net/Android.bp | 18 +- .../net/java/android/net/ip/IpClientUtil.java | 116 ++++++- .../net/java/android/net/ip/IpServer.java | 2 +- .../net/{util => shared}/NetdService.java | 2 +- .../android/net/util/InterfaceParams.java | 8 +- .../android/net/util/NetworkConstants.java | 92 ------ tests/net/Android.mk | 68 ---- 50 files changed, 601 insertions(+), 462 deletions(-) rename {services/net => core}/java/android/net/util/MultinetworkPolicyTracker.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/apf/ApfFilter.java (99%) rename {services/net/java => packages/NetworkStack/src}/android/net/apf/ApfGenerator.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpAckPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpClient.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpDeclinePacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpDiscoverPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpInformPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpNakPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpOfferPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpReleasePacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/dhcp/DhcpRequestPacket.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/ip/ConnectivityPacketTracker.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/ip/IpClient.java (89%) rename {services/net/java => packages/NetworkStack/src}/android/net/ip/IpNeighborMonitor.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/ip/IpReachabilityMonitor.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/util/ConnectivityPacketSummary.java (79%) rename {services/net/java => packages/NetworkStack/src}/android/net/util/FdEventsReader.java (100%) rename {services/net/java => packages/NetworkStack/src}/android/net/util/PacketReader.java (100%) rename {tests/net => packages/NetworkStack/tests}/jni/apf_jni.cpp (100%) rename {tests/net => packages/NetworkStack/tests}/res/raw/apf.pcap (100%) rename {tests/net => packages/NetworkStack/tests}/res/raw/apfPcap.pcap (100%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/apf/ApfTest.java (98%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/apf/Bpf2Apf.java (100%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/dhcp/DhcpPacketTest.java (100%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/ip/IpClientTest.java (94%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/ip/IpReachabilityMonitorTest.java (100%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/util/ConnectivityPacketSummaryTest.java (100%) rename {tests/net/java => packages/NetworkStack/tests/src}/android/net/util/PacketReaderTest.java (100%) rename services/net/java/android/net/{util => shared}/NetdService.java (99%) diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl index b7af37474307b..f0fe92eb86414 100644 --- a/core/java/android/net/INetworkManagementEventObserver.aidl +++ b/core/java/android/net/INetworkManagementEventObserver.aidl @@ -24,7 +24,7 @@ import android.net.RouteInfo; * * @hide */ -interface INetworkManagementEventObserver { +oneway interface INetworkManagementEventObserver { /** * Interface configuration status has changed. * diff --git a/core/java/android/net/INetworkStackConnector.aidl b/core/java/android/net/INetworkStackConnector.aidl index 2df8ab7ec1983..8b64f1c7c45a5 100644 --- a/core/java/android/net/INetworkStackConnector.aidl +++ b/core/java/android/net/INetworkStackConnector.aidl @@ -18,10 +18,12 @@ package android.net; import android.net.INetworkMonitorCallbacks; import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.IDhcpServerCallbacks; +import android.net.ip.IIpClientCallbacks; /** @hide */ oneway interface INetworkStackConnector { void makeDhcpServer(in String ifName, in DhcpServingParamsParcel params, in IDhcpServerCallbacks cb); void makeNetworkMonitor(int netId, String name, in INetworkMonitorCallbacks cb); + void makeIpClient(in String ifName, in IIpClientCallbacks callbacks); } \ No newline at end of file diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java index af043eeccde2c..d277034650a1c 100644 --- a/core/java/android/net/NetworkStack.java +++ b/core/java/android/net/NetworkStack.java @@ -27,6 +27,7 @@ import android.content.Intent; import android.content.ServiceConnection; import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.IDhcpServerCallbacks; +import android.net.ip.IIpClientCallbacks; import android.os.Binder; import android.os.IBinder; import android.os.Process; @@ -83,6 +84,21 @@ public class NetworkStack { }); } + /** + * Create an IpClient on the specified interface. + * + *

The IpClient will be returned asynchronously through the provided callbacks. + */ + public void makeIpClient(String ifName, IIpClientCallbacks cb) { + requestConnector(connector -> { + try { + connector.makeIpClient(ifName, cb); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + }); + } + /** * Create a NetworkMonitor. * diff --git a/services/net/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java similarity index 100% rename from services/net/java/android/net/util/MultinetworkPolicyTracker.java rename to core/java/android/net/util/MultinetworkPolicyTracker.java diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp index 2f7d599c68bfc..a2da0a0795508 100644 --- a/packages/NetworkStack/Android.bp +++ b/packages/NetworkStack/Android.bp @@ -24,7 +24,7 @@ java_library { ":services-networkstack-shared-srcs", ], static_libs: [ - "dhcp-packet-lib", + "services-netlink-lib", ] } diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml index 7f8bb93ae0233..5ab833bda66dc 100644 --- a/packages/NetworkStack/AndroidManifest.xml +++ b/packages/NetworkStack/AndroidManifest.xml @@ -28,6 +28,7 @@ + sSmLogs = new ConcurrentHashMap<>(); private static final ConcurrentHashMap sPktLogs = new ConcurrentHashMap<>(); - // If |args| is non-empty, assume it's a list of interface names for which - // we should print IpClient logs (filter out all others). - public static void dumpAllLogs(PrintWriter writer, String[] args) { + /** + * Dump all state machine and connectivity packet logs to the specified writer. + * @param skippedIfaces Interfaces for which logs should not be dumped. + */ + public static void dumpAllLogs(PrintWriter writer, Set skippedIfaces) { for (String ifname : sSmLogs.keySet()) { - if (!ArrayUtils.isEmpty(args) && !ArrayUtils.contains(args, ifname)) continue; + if (skippedIfaces.contains(ifname)) continue; writer.println(String.format("--- BEGIN %s ---", ifname)); @@ -127,19 +134,6 @@ public class IpClient extends StateMachine { } } - /** - * TODO: remove after migrating clients to use IpClientCallbacks directly - * @see IpClientCallbacks - */ - public static class Callback extends IpClientCallbacks {} - - /** - * TODO: remove once clients are migrated to IpClientUtil.WaitForProvisioningCallback - * @see IpClientUtil.WaitForProvisioningCallbacks - */ - public static class WaitForProvisioningCallback - extends IpClientUtil.WaitForProvisioningCallbacks {} - // Use a wrapper class to log in order to ensure complete and detailed // logging. This method is lighter weight than annotations/reflection // and has the following benefits: @@ -160,181 +154,134 @@ public class IpClient extends StateMachine { // once passed on to the callback they may be modified by another thread. // // TODO: Find an lighter weight approach. - private class LoggingCallbackWrapper extends IpClientCallbacks { + public static class IpClientCallbacksWrapper { private static final String PREFIX = "INVOKE "; - private final IpClientCallbacks mCallback; + private final IIpClientCallbacks mCallback; + private final SharedLog mLog; - LoggingCallbackWrapper(IpClientCallbacks callback) { - mCallback = (callback != null) ? callback : new IpClientCallbacks(); + @VisibleForTesting + protected IpClientCallbacksWrapper(IIpClientCallbacks callback, SharedLog log) { + mCallback = callback; + mLog = log; } private void log(String msg) { mLog.log(PREFIX + msg); } - @Override + private void log(String msg, Throwable e) { + mLog.e(PREFIX + msg, e); + } + public void onPreDhcpAction() { log("onPreDhcpAction()"); - mCallback.onPreDhcpAction(); + try { + mCallback.onPreDhcpAction(); + } catch (RemoteException e) { + log("Failed to call onPreDhcpAction", e); + } } - @Override + public void onPostDhcpAction() { log("onPostDhcpAction()"); - mCallback.onPostDhcpAction(); + try { + mCallback.onPostDhcpAction(); + } catch (RemoteException e) { + log("Failed to call onPostDhcpAction", e); + } } - @Override + public void onNewDhcpResults(DhcpResults dhcpResults) { log("onNewDhcpResults({" + dhcpResults + "})"); - mCallback.onNewDhcpResults(dhcpResults); + try { + mCallback.onNewDhcpResults(toStableParcelable(dhcpResults)); + } catch (RemoteException e) { + log("Failed to call onNewDhcpResults", e); + } } - @Override + public void onProvisioningSuccess(LinkProperties newLp) { log("onProvisioningSuccess({" + newLp + "})"); - mCallback.onProvisioningSuccess(newLp); + try { + mCallback.onProvisioningSuccess(toStableParcelable(newLp)); + } catch (RemoteException e) { + log("Failed to call onProvisioningSuccess", e); + } } - @Override + public void onProvisioningFailure(LinkProperties newLp) { log("onProvisioningFailure({" + newLp + "})"); - mCallback.onProvisioningFailure(newLp); + try { + mCallback.onProvisioningFailure(toStableParcelable(newLp)); + } catch (RemoteException e) { + log("Failed to call onProvisioningFailure", e); + } } - @Override + public void onLinkPropertiesChange(LinkProperties newLp) { log("onLinkPropertiesChange({" + newLp + "})"); - mCallback.onLinkPropertiesChange(newLp); + try { + mCallback.onLinkPropertiesChange(toStableParcelable(newLp)); + } catch (RemoteException e) { + log("Failed to call onLinkPropertiesChange", e); + } } - @Override + public void onReachabilityLost(String logMsg) { log("onReachabilityLost(" + logMsg + ")"); - mCallback.onReachabilityLost(logMsg); + try { + mCallback.onReachabilityLost(logMsg); + } catch (RemoteException e) { + log("Failed to call onReachabilityLost", e); + } } - @Override + public void onQuit() { log("onQuit()"); - mCallback.onQuit(); + try { + mCallback.onQuit(); + } catch (RemoteException e) { + log("Failed to call onQuit", e); + } } - @Override + public void installPacketFilter(byte[] filter) { log("installPacketFilter(byte[" + filter.length + "])"); - mCallback.installPacketFilter(filter); + try { + mCallback.installPacketFilter(filter); + } catch (RemoteException e) { + log("Failed to call installPacketFilter", e); + } } - @Override + public void startReadPacketFilter() { log("startReadPacketFilter()"); - mCallback.startReadPacketFilter(); + try { + mCallback.startReadPacketFilter(); + } catch (RemoteException e) { + log("Failed to call startReadPacketFilter", e); + } } - @Override + public void setFallbackMulticastFilter(boolean enabled) { log("setFallbackMulticastFilter(" + enabled + ")"); - mCallback.setFallbackMulticastFilter(enabled); + try { + mCallback.setFallbackMulticastFilter(enabled); + } catch (RemoteException e) { + log("Failed to call setFallbackMulticastFilter", e); + } } - @Override + public void setNeighborDiscoveryOffload(boolean enable) { log("setNeighborDiscoveryOffload(" + enable + ")"); - mCallback.setNeighborDiscoveryOffload(enable); - } - } - - /** - * TODO: remove after migrating clients to use the shared configuration class directly. - * @see android.net.shared.ProvisioningConfiguration - */ - public static class ProvisioningConfiguration - extends android.net.shared.ProvisioningConfiguration { - public ProvisioningConfiguration(android.net.shared.ProvisioningConfiguration other) { - super(other); - } - - /** - * @see android.net.shared.ProvisioningConfiguration.Builder - */ - public static class Builder extends android.net.shared.ProvisioningConfiguration.Builder { - // Override all methods to have a return type matching this Builder - @Override - public Builder withoutIPv4() { - super.withoutIPv4(); - return this; - } - - @Override - public Builder withoutIPv6() { - super.withoutIPv6(); - return this; - } - - @Override - public Builder withoutMultinetworkPolicyTracker() { - super.withoutMultinetworkPolicyTracker(); - return this; - } - - @Override - public Builder withoutIpReachabilityMonitor() { - super.withoutIpReachabilityMonitor(); - return this; - } - - @Override - public Builder withPreDhcpAction() { - super.withPreDhcpAction(); - return this; - } - - @Override - public Builder withPreDhcpAction(int dhcpActionTimeoutMs) { - super.withPreDhcpAction(dhcpActionTimeoutMs); - return this; - } - - @Override - public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) { - super.withStaticConfiguration(staticConfig); - return this; - } - - @Override - public Builder withApfCapabilities(ApfCapabilities apfCapabilities) { - super.withApfCapabilities(apfCapabilities); - return this; - } - - @Override - public Builder withProvisioningTimeoutMs(int timeoutMs) { - super.withProvisioningTimeoutMs(timeoutMs); - return this; - } - - @Override - public Builder withRandomMacAddress() { - super.withRandomMacAddress(); - return this; - } - - @Override - public Builder withStableMacAddress() { - super.withStableMacAddress(); - return this; - } - - @Override - public Builder withNetwork(Network network) { - super.withNetwork(network); - return this; - } - - @Override - public Builder withDisplayName(String displayName) { - super.withDisplayName(displayName); - return this; - } - - @Override - public ProvisioningConfiguration build() { - return new ProvisioningConfiguration(mConfig); + try { + mCallback.setNeighborDiscoveryOffload(enable); + } catch (RemoteException e) { + log("Failed to call setNeighborDiscoveryOffload", e); } } } - public static final String DUMP_ARG = "ipclient"; public static final String DUMP_ARG_CONFIRM = "confirm"; private static final int CMD_TERMINATE_AFTER_STOP = 1; @@ -388,7 +335,7 @@ public class IpClient extends StateMachine { private final String mInterfaceName; private final String mClatInterfaceName; @VisibleForTesting - protected final IpClientCallbacks mCallback; + protected final IpClientCallbacksWrapper mCallback; private final Dependencies mDependencies; private final CountDownLatch mShutdownLatch; private final ConnectivityManager mCm; @@ -444,7 +391,7 @@ public class IpClient extends StateMachine { } } - public IpClient(Context context, String ifName, IpClientCallbacks callback) { + public IpClient(Context context, String ifName, IIpClientCallbacks callback) { this(context, ifName, callback, new Dependencies()); } @@ -452,7 +399,7 @@ public class IpClient extends StateMachine { * An expanded constructor, useful for dependency injection. * TODO: migrate all test users to mock IpClient directly and remove this ctor. */ - public IpClient(Context context, String ifName, IpClientCallbacks callback, + public IpClient(Context context, String ifName, IIpClientCallbacks callback, INetworkManagementService nwService) { this(context, ifName, callback, new Dependencies() { @Override @@ -463,7 +410,7 @@ public class IpClient extends StateMachine { } @VisibleForTesting - IpClient(Context context, String ifName, IpClientCallbacks callback, Dependencies deps) { + IpClient(Context context, String ifName, IIpClientCallbacks callback, Dependencies deps) { super(IpClient.class.getSimpleName() + "." + ifName); Preconditions.checkNotNull(ifName); Preconditions.checkNotNull(callback); @@ -473,7 +420,6 @@ public class IpClient extends StateMachine { mContext = context; mInterfaceName = ifName; mClatInterfaceName = CLAT_PREFIX + ifName; - mCallback = new LoggingCallbackWrapper(callback); mDependencies = deps; mShutdownLatch = new CountDownLatch(1); mCm = mContext.getSystemService(ConnectivityManager.class); @@ -484,6 +430,7 @@ public class IpClient extends StateMachine { sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS)); mConnectivityPacketLog = sPktLogs.get(mInterfaceName); mMsgStateLogger = new MessageHandlingLogger(); + mCallback = new IpClientCallbacksWrapper(callback, mLog); // TODO: Consider creating, constructing, and passing in some kind of // InterfaceController.Dependencies class. @@ -561,45 +508,53 @@ public class IpClient extends StateMachine { class IpClientConnector extends IIpClient.Stub { @Override public void completedPreDhcpAction() { + checkNetworkStackCallingPermission(); IpClient.this.completedPreDhcpAction(); } @Override public void confirmConfiguration() { + checkNetworkStackCallingPermission(); IpClient.this.confirmConfiguration(); } @Override public void readPacketFilterComplete(byte[] data) { + checkNetworkStackCallingPermission(); IpClient.this.readPacketFilterComplete(data); } @Override public void shutdown() { + checkNetworkStackCallingPermission(); IpClient.this.shutdown(); } @Override public void startProvisioning(ProvisioningConfigurationParcelable req) { - IpClient.this.startProvisioning( - android.net.shared.ProvisioningConfiguration.fromStableParcelable(req)); + checkNetworkStackCallingPermission(); + IpClient.this.startProvisioning(ProvisioningConfiguration.fromStableParcelable(req)); } @Override public void stop() { + checkNetworkStackCallingPermission(); IpClient.this.stop(); } @Override public void setTcpBufferSizes(String tcpBufferSizes) { + checkNetworkStackCallingPermission(); IpClient.this.setTcpBufferSizes(tcpBufferSizes); } @Override public void setHttpProxy(ProxyInfoParcelable proxyInfo) { + checkNetworkStackCallingPermission(); IpClient.this.setHttpProxy(fromStableParcelable(proxyInfo)); } @Override public void setMulticastFilter(boolean enabled) { + checkNetworkStackCallingPermission(); IpClient.this.setMulticastFilter(enabled); } - // TODO: remove and have IpClient logs dumped in NetworkStack dumpsys - public void dumpIpClientLogs(FileDescriptor fd, PrintWriter pw, String[] args) { - IpClient.this.dump(fd, pw, args); - } + } + + public String getInterfaceName() { + return mInterfaceName; } private void configureAndStartStateMachine() { @@ -645,25 +600,10 @@ public class IpClient extends StateMachine { sendMessage(CMD_TERMINATE_AFTER_STOP); } - // In order to avoid deadlock, this method MUST NOT be called on the - // IpClient instance's thread. This prohibition includes code executed by - // when methods on the passed-in IpClient.Callback instance are called. - public void awaitShutdown() { - try { - mShutdownLatch.await(); - } catch (InterruptedException e) { - mLog.e("Interrupted while awaiting shutdown: " + e); - } - } - - public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() { - return new ProvisioningConfiguration.Builder(); - } - /** * Start provisioning with the provided parameters. */ - public void startProvisioning(android.net.shared.ProvisioningConfiguration req) { + public void startProvisioning(ProvisioningConfiguration req) { if (!req.isValid()) { doImmediateProvisioningFailure(IpManagerEvent.ERROR_INVALID_PROVISIONING); return; @@ -680,17 +620,6 @@ public class IpClient extends StateMachine { sendMessage(CMD_START, new android.net.shared.ProvisioningConfiguration(req)); } - // TODO: Delete this. - public void startProvisioning(StaticIpConfiguration staticIpConfig) { - startProvisioning(buildProvisioningConfiguration() - .withStaticConfiguration(staticIpConfig) - .build()); - } - - public void startProvisioning() { - startProvisioning(new android.net.shared.ProvisioningConfiguration()); - } - /** * Stop this IpClient. * diff --git a/services/net/java/android/net/ip/IpNeighborMonitor.java b/packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java similarity index 100% rename from services/net/java/android/net/ip/IpNeighborMonitor.java rename to packages/NetworkStack/src/android/net/ip/IpNeighborMonitor.java diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java similarity index 100% rename from services/net/java/android/net/ip/IpReachabilityMonitor.java rename to packages/NetworkStack/src/android/net/ip/IpReachabilityMonitor.java diff --git a/services/net/java/android/net/util/ConnectivityPacketSummary.java b/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java similarity index 79% rename from services/net/java/android/net/util/ConnectivityPacketSummary.java rename to packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java index ec833b07e8062..08c3f60eff3d6 100644 --- a/services/net/java/android/net/util/ConnectivityPacketSummary.java +++ b/packages/NetworkStack/src/android/net/util/ConnectivityPacketSummary.java @@ -16,47 +16,46 @@ package android.net.util; -import static android.net.util.NetworkConstants.ARP_HWTYPE_ETHER; -import static android.net.util.NetworkConstants.ARP_PAYLOAD_LEN; -import static android.net.util.NetworkConstants.ARP_REPLY; -import static android.net.util.NetworkConstants.ARP_REQUEST; -import static android.net.util.NetworkConstants.DHCP4_CLIENT_PORT; -import static android.net.util.NetworkConstants.ETHER_ADDR_LEN; -import static android.net.util.NetworkConstants.ETHER_DST_ADDR_OFFSET; -import static android.net.util.NetworkConstants.ETHER_HEADER_LEN; -import static android.net.util.NetworkConstants.ETHER_SRC_ADDR_OFFSET; -import static android.net.util.NetworkConstants.ETHER_TYPE_ARP; -import static android.net.util.NetworkConstants.ETHER_TYPE_IPV4; -import static android.net.util.NetworkConstants.ETHER_TYPE_IPV6; -import static android.net.util.NetworkConstants.ETHER_TYPE_OFFSET; -import static android.net.util.NetworkConstants.ICMPV6_HEADER_MIN_LEN; -import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR; -import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_MIN_LENGTH; -import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_MTU; -import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_SLLA; -import static android.net.util.NetworkConstants.ICMPV6_ND_OPTION_TLLA; -import static android.net.util.NetworkConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; -import static android.net.util.NetworkConstants.ICMPV6_NEIGHBOR_SOLICITATION; -import static android.net.util.NetworkConstants.ICMPV6_ROUTER_ADVERTISEMENT; -import static android.net.util.NetworkConstants.ICMPV6_ROUTER_SOLICITATION; -import static android.net.util.NetworkConstants.IPV4_ADDR_LEN; -import static android.net.util.NetworkConstants.IPV4_DST_ADDR_OFFSET; -import static android.net.util.NetworkConstants.IPV4_FLAGS_OFFSET; -import static android.net.util.NetworkConstants.IPV4_FRAGMENT_MASK; -import static android.net.util.NetworkConstants.IPV4_HEADER_MIN_LEN; -import static android.net.util.NetworkConstants.IPV4_IHL_MASK; -import static android.net.util.NetworkConstants.IPV4_PROTOCOL_OFFSET; -import static android.net.util.NetworkConstants.IPV4_SRC_ADDR_OFFSET; -import static android.net.util.NetworkConstants.IPV6_ADDR_LEN; -import static android.net.util.NetworkConstants.IPV6_HEADER_LEN; -import static android.net.util.NetworkConstants.IPV6_PROTOCOL_OFFSET; -import static android.net.util.NetworkConstants.IPV6_SRC_ADDR_OFFSET; -import static android.net.util.NetworkConstants.UDP_HEADER_LEN; -import static android.net.util.NetworkConstants.asString; -import static android.net.util.NetworkConstants.asUint; import static android.system.OsConstants.IPPROTO_ICMPV6; import static android.system.OsConstants.IPPROTO_UDP; +import static com.android.server.util.NetworkStackConstants.ARP_HWTYPE_ETHER; +import static com.android.server.util.NetworkStackConstants.ARP_PAYLOAD_LEN; +import static com.android.server.util.NetworkStackConstants.ARP_REPLY; +import static com.android.server.util.NetworkStackConstants.ARP_REQUEST; +import static com.android.server.util.NetworkStackConstants.DHCP4_CLIENT_PORT; +import static com.android.server.util.NetworkStackConstants.ETHER_ADDR_LEN; +import static com.android.server.util.NetworkStackConstants.ETHER_DST_ADDR_OFFSET; +import static com.android.server.util.NetworkStackConstants.ETHER_HEADER_LEN; +import static com.android.server.util.NetworkStackConstants.ETHER_SRC_ADDR_OFFSET; +import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_ARP; +import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV4; +import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_IPV6; +import static com.android.server.util.NetworkStackConstants.ETHER_TYPE_OFFSET; +import static com.android.server.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MIN_LENGTH; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_MTU; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; +import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; +import static com.android.server.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ROUTER_SOLICITATION; +import static com.android.server.util.NetworkStackConstants.IPV4_ADDR_LEN; +import static com.android.server.util.NetworkStackConstants.IPV4_DST_ADDR_OFFSET; +import static com.android.server.util.NetworkStackConstants.IPV4_FLAGS_OFFSET; +import static com.android.server.util.NetworkStackConstants.IPV4_FRAGMENT_MASK; +import static com.android.server.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN; +import static com.android.server.util.NetworkStackConstants.IPV4_IHL_MASK; +import static com.android.server.util.NetworkStackConstants.IPV4_PROTOCOL_OFFSET; +import static com.android.server.util.NetworkStackConstants.IPV4_SRC_ADDR_OFFSET; +import static com.android.server.util.NetworkStackConstants.IPV6_ADDR_LEN; +import static com.android.server.util.NetworkStackConstants.IPV6_HEADER_LEN; +import static com.android.server.util.NetworkStackConstants.IPV6_PROTOCOL_OFFSET; +import static com.android.server.util.NetworkStackConstants.IPV6_SRC_ADDR_OFFSET; +import static com.android.server.util.NetworkStackConstants.UDP_HEADER_LEN; + import android.net.MacAddress; import android.net.dhcp.DhcpPacket; @@ -412,4 +411,25 @@ public class ConnectivityPacketSummary { final String MAC48_FORMAT = "%02x:%02x:%02x:%02x:%02x:%02x"; return String.format(MAC48_FORMAT, printableBytes); } + + /** + * Convenience method to convert an int to a String. + */ + public static String asString(int i) { + return Integer.toString(i); + } + + /** + * Convenience method to read a byte as an unsigned int. + */ + public static int asUint(byte b) { + return (b & 0xff); + } + + /** + * Convenience method to read a short as an unsigned int. + */ + public static int asUint(short s) { + return (s & 0xffff); + } } diff --git a/services/net/java/android/net/util/FdEventsReader.java b/packages/NetworkStack/src/android/net/util/FdEventsReader.java similarity index 100% rename from services/net/java/android/net/util/FdEventsReader.java rename to packages/NetworkStack/src/android/net/util/FdEventsReader.java diff --git a/services/net/java/android/net/util/PacketReader.java b/packages/NetworkStack/src/android/net/util/PacketReader.java similarity index 100% rename from services/net/java/android/net/util/PacketReader.java rename to packages/NetworkStack/src/android/net/util/PacketReader.java diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java index cca71e759bdd2..4080ddf9e73fe 100644 --- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java +++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java @@ -39,6 +39,8 @@ import android.net.dhcp.DhcpServer; import android.net.dhcp.DhcpServingParams; import android.net.dhcp.DhcpServingParamsParcel; import android.net.dhcp.IDhcpServerCallbacks; +import android.net.ip.IIpClientCallbacks; +import android.net.ip.IpClient; import android.net.shared.PrivateDnsConfig; import android.net.util.SharedLog; import android.os.IBinder; @@ -50,7 +52,11 @@ import com.android.server.connectivity.NetworkMonitor; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.lang.ref.WeakReference; import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; /** * Android service used to start the network stack when bound to via an intent. @@ -80,6 +86,8 @@ public class NetworkStackService extends Service { private static final int NUM_VALIDATION_LOG_LINES = 20; private final Context mContext; private final ConnectivityManager mCm; + @GuardedBy("mIpClients") + private final ArrayList> mIpClients = new ArrayList<>(); private static final int MAX_VALIDATION_LOGS = 10; @GuardedBy("mValidationLogs") @@ -137,6 +145,24 @@ public class NetworkStackService extends Service { cb.onNetworkMonitorCreated(new NetworkMonitorImpl(nm)); } + @Override + public void makeIpClient(String ifName, IIpClientCallbacks cb) throws RemoteException { + final IpClient ipClient = new IpClient(mContext, ifName, cb); + + synchronized (mIpClients) { + final Iterator> it = mIpClients.iterator(); + while (it.hasNext()) { + final IpClient ipc = it.next().get(); + if (ipc == null) { + it.remove(); + } + } + mIpClients.add(new WeakReference<>(ipClient)); + } + + cb.onIpClientCreated(ipClient.makeConnector()); + } + @Override protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args) { @@ -145,6 +171,33 @@ public class NetworkStackService extends Service { pw.println("NetworkStack logs:"); mLog.dump(fd, pw, args); + // Dump full IpClient logs for non-GCed clients + pw.println(); + pw.println("Recently active IpClient logs:"); + final ArrayList ipClients = new ArrayList<>(); + final HashSet dumpedIpClientIfaces = new HashSet<>(); + synchronized (mIpClients) { + for (WeakReference ipcRef : mIpClients) { + final IpClient ipc = ipcRef.get(); + if (ipc != null) { + ipClients.add(ipc); + } + } + } + + for (IpClient ipc : ipClients) { + pw.println(ipc.getName()); + pw.increaseIndent(); + ipc.dump(fd, pw, args); + pw.decreaseIndent(); + dumpedIpClientIfaces.add(ipc.getInterfaceName()); + } + + // State machine and connectivity metrics logs are kept for GCed IpClients + pw.println(); + pw.println("Other IpClient logs:"); + IpClient.dumpAllLogs(fout, dumpedIpClientIfaces); + pw.println(); pw.println("Validation logs (most recent first):"); synchronized (mValidationLogs) { diff --git a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java b/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java index bb5900c53e52c..eedaf30c055f2 100644 --- a/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java +++ b/packages/NetworkStack/src/com/android/server/util/NetworkStackConstants.java @@ -31,6 +31,96 @@ public final class NetworkStackConstants { public static final int IPV4_MIN_MTU = 68; public static final int IPV4_MAX_MTU = 65_535; + /** + * Ethernet constants. + * + * See also: + * - https://tools.ietf.org/html/rfc894 + * - https://tools.ietf.org/html/rfc2464 + * - https://tools.ietf.org/html/rfc7042 + * - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml + * - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml + */ + public static final int ETHER_DST_ADDR_OFFSET = 0; + public static final int ETHER_SRC_ADDR_OFFSET = 6; + public static final int ETHER_ADDR_LEN = 6; + public static final int ETHER_TYPE_OFFSET = 12; + public static final int ETHER_TYPE_LENGTH = 2; + public static final int ETHER_TYPE_ARP = 0x0806; + public static final int ETHER_TYPE_IPV4 = 0x0800; + public static final int ETHER_TYPE_IPV6 = 0x86dd; + public static final int ETHER_HEADER_LEN = 14; + + /** + * ARP constants. + * + * See also: + * - https://tools.ietf.org/html/rfc826 + * - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml + */ + public static final int ARP_PAYLOAD_LEN = 28; // For Ethernet+IPv4. + public static final int ARP_REQUEST = 1; + public static final int ARP_REPLY = 2; + public static final int ARP_HWTYPE_RESERVED_LO = 0; + public static final int ARP_HWTYPE_ETHER = 1; + public static final int ARP_HWTYPE_RESERVED_HI = 0xffff; + + /** + * IPv4 constants. + * + * See also: + * - https://tools.ietf.org/html/rfc791 + */ + public static final int IPV4_HEADER_MIN_LEN = 20; + public static final int IPV4_IHL_MASK = 0xf; + public static final int IPV4_FLAGS_OFFSET = 6; + public static final int IPV4_FRAGMENT_MASK = 0x1fff; + public static final int IPV4_PROTOCOL_OFFSET = 9; + public static final int IPV4_SRC_ADDR_OFFSET = 12; + public static final int IPV4_DST_ADDR_OFFSET = 16; + public static final int IPV4_ADDR_LEN = 4; + + /** + * IPv6 constants. + * + * See also: + * - https://tools.ietf.org/html/rfc2460 + */ + public static final int IPV6_ADDR_LEN = 16; + public static final int IPV6_HEADER_LEN = 40; + public static final int IPV6_PROTOCOL_OFFSET = 6; + public static final int IPV6_SRC_ADDR_OFFSET = 8; + public static final int IPV6_DST_ADDR_OFFSET = 24; + + /** + * ICMPv6 constants. + * + * See also: + * - https://tools.ietf.org/html/rfc4443 + * - https://tools.ietf.org/html/rfc4861 + */ + public static final int ICMPV6_HEADER_MIN_LEN = 4; + public static final int ICMPV6_ECHO_REPLY_TYPE = 129; + public static final int ICMPV6_ECHO_REQUEST_TYPE = 128; + public static final int ICMPV6_ROUTER_SOLICITATION = 133; + public static final int ICMPV6_ROUTER_ADVERTISEMENT = 134; + public static final int ICMPV6_NEIGHBOR_SOLICITATION = 135; + public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136; + public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8; + public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8; + public static final int ICMPV6_ND_OPTION_SLLA = 1; + public static final int ICMPV6_ND_OPTION_TLLA = 2; + public static final int ICMPV6_ND_OPTION_MTU = 5; + + /** + * UDP constants. + * + * See also: + * - https://tools.ietf.org/html/rfc768 + */ + public static final int UDP_HEADER_LEN = 8; + + /** * DHCP constants. * @@ -38,6 +128,7 @@ public final class NetworkStackConstants { * - https://tools.ietf.org/html/rfc2131 */ public static final int INFINITE_LEASE = 0xffffffff; + public static final int DHCP4_CLIENT_PORT = 68; private NetworkStackConstants() { throw new UnsupportedOperationException("This class is not to be instantiated"); diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp index bd7ff2a757038..45fa2dc2f3833 100644 --- a/packages/NetworkStack/tests/Android.bp +++ b/packages/NetworkStack/tests/Android.bp @@ -16,9 +16,12 @@ android_test { name: "NetworkStackTests", + certificate: "platform", srcs: ["src/**/*.java"], + resource_dirs: ["res"], static_libs: [ "android-support-test", + "frameworks-base-testutils", "mockito-target-extended-minus-junit4", "NetworkStackLib", "testables", @@ -26,10 +29,70 @@ android_test { libs: [ "android.test.runner", "android.test.base", + "android.test.mock", ], jni_libs: [ // For mockito extended "libdexmakerjvmtiagent", "libstaticjvmtiagent", - ] -} \ No newline at end of file + // For ApfTest + "libartbase", + "libbacktrace", + "libbase", + "libbinder", + "libbinderthreadstate", + "libc++", + "libcrypto", + "libcutils", + "libdexfile", + "libhidl-gen-utils", + "libhidlbase", + "libhidltransport", + "libhwbinder", + "liblog", + "liblzma", + "libnativehelper", + "libnetworkstacktestsjni", + "libpackagelistparser", + "libpcre2", + "libprocessgroup", + "libselinux", + "libui", + "libutils", + "libvintf", + "libvndksupport", + "libtinyxml2", + "libunwindstack", + "libutilscallstack", + "libziparchive", + "libz", + "netd_aidl_interface-cpp", + ], +} + +cc_library_shared { + name: "libnetworkstacktestsjni", + srcs: [ + "jni/**/*.cpp" + ], + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + include_dirs: [ + "hardware/google/apf", + ], + shared_libs: [ + "libbinder", + "liblog", + "libcutils", + "libnativehelper", + "netd_aidl_interface-cpp", + ], + static_libs: [ + "libapf", + "libpcap", + ], + +} diff --git a/packages/NetworkStack/tests/AndroidManifest.xml b/packages/NetworkStack/tests/AndroidManifest.xml index 8b8474f57e287..9cb2c21cc3999 100644 --- a/packages/NetworkStack/tests/AndroidManifest.xml +++ b/packages/NetworkStack/tests/AndroidManifest.xml @@ -15,6 +15,35 @@ --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/net/jni/apf_jni.cpp b/packages/NetworkStack/tests/jni/apf_jni.cpp similarity index 100% rename from tests/net/jni/apf_jni.cpp rename to packages/NetworkStack/tests/jni/apf_jni.cpp diff --git a/tests/net/res/raw/apf.pcap b/packages/NetworkStack/tests/res/raw/apf.pcap similarity index 100% rename from tests/net/res/raw/apf.pcap rename to packages/NetworkStack/tests/res/raw/apf.pcap diff --git a/tests/net/res/raw/apfPcap.pcap b/packages/NetworkStack/tests/res/raw/apfPcap.pcap similarity index 100% rename from tests/net/res/raw/apfPcap.pcap rename to packages/NetworkStack/tests/res/raw/apfPcap.pcap diff --git a/tests/net/java/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java similarity index 98% rename from tests/net/java/android/net/apf/ApfTest.java rename to packages/NetworkStack/tests/src/android/net/apf/ApfTest.java index 3c3e7ce3b12ac..f76e41217c2ae 100644 --- a/tests/net/java/android/net/apf/ApfTest.java +++ b/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java @@ -16,8 +16,6 @@ package android.net.apf; -import static android.net.util.NetworkConstants.ICMPV6_ECHO_REQUEST_TYPE; -import static android.net.util.NetworkConstants.ICMPV6_ROUTER_ADVERTISEMENT; import static android.system.OsConstants.AF_UNIX; import static android.system.OsConstants.ARPHRD_ETHER; import static android.system.OsConstants.ETH_P_ARP; @@ -28,12 +26,14 @@ import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.SOCK_STREAM; import static com.android.internal.util.BitUtils.bytesToBEInt; +import static com.android.server.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.content.Context; @@ -42,10 +42,14 @@ import android.net.LinkProperties; import android.net.apf.ApfFilter.ApfConfiguration; import android.net.apf.ApfGenerator.IllegalInstructionException; import android.net.apf.ApfGenerator.Register; +import android.net.ip.IIpClientCallbacks; +import android.net.ip.IpClient; +import android.net.ip.IpClient.IpClientCallbacksWrapper; import android.net.ip.IpClientCallbacks; import android.net.metrics.IpConnectivityLog; import android.net.metrics.RaEvent; import android.net.util.InterfaceParams; +import android.net.util.SharedLog; import android.os.ConditionVariable; import android.os.Parcelable; import android.os.SystemClock; @@ -57,8 +61,9 @@ import android.system.Os; import android.text.format.DateUtils; import android.util.Log; -import com.android.frameworks.tests.net.R; import com.android.internal.util.HexDump; +import com.android.server.networkstack.tests.R; +import com.android.server.util.NetworkStackConstants; import libcore.io.IoUtils; import libcore.io.Streams; @@ -100,7 +105,7 @@ public class ApfTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); // Load up native shared library containing APF interpreter exposed via JNI. - System.loadLibrary("frameworksnettestsjni"); + System.loadLibrary("networkstacktestsjni"); } private static final String TAG = "ApfTest"; @@ -915,10 +920,14 @@ public class ApfTest { HexDump.toHexString(data, false), result); } - private class MockIpClientCallback extends IpClientCallbacks { + private class MockIpClientCallback extends IpClientCallbacksWrapper { private final ConditionVariable mGotApfProgram = new ConditionVariable(); private byte[] mLastApfProgram; + MockIpClientCallback() { + super(mock(IIpClientCallbacks.class), mock(SharedLog.class)); + } + @Override public void installPacketFilter(byte[] filter) { mLastApfProgram = filter; @@ -946,7 +955,7 @@ public class ApfTest { private final long mFixedTimeMs = SystemClock.elapsedRealtime(); public TestApfFilter(Context context, ApfConfiguration config, - IpClientCallbacks ipClientCallback, IpConnectivityLog log) throws Exception { + IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) throws Exception { super(context, config, InterfaceParams.getByName("lo"), ipClientCallback, log); } @@ -1075,8 +1084,8 @@ public class ApfTest { private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0}; // Helper to initialize a default apfFilter. - private ApfFilter setupApfFilter(IpClientCallbacks ipClientCallback, ApfConfiguration config) - throws Exception { + private ApfFilter setupApfFilter( + IpClientCallbacksWrapper ipClientCallback, ApfConfiguration config) throws Exception { LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); @@ -1294,7 +1303,7 @@ public class ApfTest { // However, we should still let through all other ICMPv6 types. ByteBuffer raPacket = ByteBuffer.wrap(packet.array().clone()); - raPacket.put(ICMP6_TYPE_OFFSET, (byte)ICMPV6_ROUTER_ADVERTISEMENT); + raPacket.put(ICMP6_TYPE_OFFSET, (byte) NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT); assertPass(ipClientCallback.getApfProgram(), raPacket.array()); // Now wake up from doze mode to ensure that we no longer drop the packets. diff --git a/tests/net/java/android/net/apf/Bpf2Apf.java b/packages/NetworkStack/tests/src/android/net/apf/Bpf2Apf.java similarity index 100% rename from tests/net/java/android/net/apf/Bpf2Apf.java rename to packages/NetworkStack/tests/src/android/net/apf/Bpf2Apf.java diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java similarity index 100% rename from tests/net/java/android/net/dhcp/DhcpPacketTest.java rename to packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java diff --git a/tests/net/java/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java similarity index 94% rename from tests/net/java/android/net/ip/IpClientTest.java rename to packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java index 5110ce1830b35..f21809fdbc1c7 100644 --- a/tests/net/java/android/net/ip/IpClientTest.java +++ b/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java @@ -16,10 +16,13 @@ package android.net.ip; +import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.eq; @@ -87,7 +90,7 @@ public class IpClientTest { @Mock private INetworkManagementService mNMService; @Mock private INetd mNetd; @Mock private Resources mResources; - @Mock private IpClientCallbacks mCb; + @Mock private IIpClientCallbacks mCb; @Mock private AlarmManager mAlarm; @Mock private IpClient.Dependencies mDependecies; private MockContentResolver mContentResolver; @@ -209,7 +212,8 @@ public class IpClientTest { verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) - .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface))); + .onLinkPropertiesChange(argThat( + lp -> fromStableParcelable(lp).equals(makeEmptyLinkProperties(iface)))); } @Test @@ -254,13 +258,15 @@ public class IpClientTest { mObserver.addressUpdated(iface, new LinkAddress(addresses[lastAddr])); LinkProperties want = linkproperties(links(addresses), routes(prefixes)); want.setInterfaceName(iface); - verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(eq(want)); + verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(argThat( + lp -> fromStableParcelable(lp).equals(want))); ipc.shutdown(); verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) - .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface))); + .onLinkPropertiesChange(argThat( + lp -> fromStableParcelable(lp).equals(makeEmptyLinkProperties(iface)))); } @Test @@ -492,11 +498,11 @@ public class IpClientTest { List list3 = Arrays.asList("bar", "baz"); List list4 = Arrays.asList("foo", "bar", "baz"); - assertTrue(IpClient.all(list1, (x) -> false)); - assertFalse(IpClient.all(list2, (x) -> false)); - assertTrue(IpClient.all(list3, (x) -> true)); - assertTrue(IpClient.all(list2, (x) -> x.charAt(0) == 'f')); - assertFalse(IpClient.all(list4, (x) -> x.charAt(0) == 'f')); + assertTrue(InitialConfiguration.all(list1, (x) -> false)); + assertFalse(InitialConfiguration.all(list2, (x) -> false)); + assertTrue(InitialConfiguration.all(list3, (x) -> true)); + assertTrue(InitialConfiguration.all(list2, (x) -> x.charAt(0) == 'f')); + assertFalse(InitialConfiguration.all(list4, (x) -> x.charAt(0) == 'f')); } @Test @@ -506,11 +512,11 @@ public class IpClientTest { List list3 = Arrays.asList("bar", "baz"); List list4 = Arrays.asList("foo", "bar", "baz"); - assertFalse(IpClient.any(list1, (x) -> true)); - assertTrue(IpClient.any(list2, (x) -> true)); - assertTrue(IpClient.any(list2, (x) -> x.charAt(0) == 'f')); - assertFalse(IpClient.any(list3, (x) -> x.charAt(0) == 'f')); - assertTrue(IpClient.any(list4, (x) -> x.charAt(0) == 'f')); + assertFalse(InitialConfiguration.any(list1, (x) -> true)); + assertTrue(InitialConfiguration.any(list2, (x) -> true)); + assertTrue(InitialConfiguration.any(list2, (x) -> x.charAt(0) == 'f')); + assertFalse(InitialConfiguration.any(list3, (x) -> x.charAt(0) == 'f')); + assertTrue(InitialConfiguration.any(list4, (x) -> x.charAt(0) == 'f')); } @Test diff --git a/tests/net/java/android/net/ip/IpReachabilityMonitorTest.java b/packages/NetworkStack/tests/src/android/net/ip/IpReachabilityMonitorTest.java similarity index 100% rename from tests/net/java/android/net/ip/IpReachabilityMonitorTest.java rename to packages/NetworkStack/tests/src/android/net/ip/IpReachabilityMonitorTest.java diff --git a/tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java b/packages/NetworkStack/tests/src/android/net/util/ConnectivityPacketSummaryTest.java similarity index 100% rename from tests/net/java/android/net/util/ConnectivityPacketSummaryTest.java rename to packages/NetworkStack/tests/src/android/net/util/ConnectivityPacketSummaryTest.java diff --git a/tests/net/java/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java similarity index 100% rename from tests/net/java/android/net/util/PacketReaderTest.java rename to packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index fae7a8d7bfab4..d6cd9022ee9c6 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -100,7 +100,7 @@ import android.net.netlink.InetDiagMessage; import android.net.shared.NetworkMonitorUtils; import android.net.shared.PrivateDnsConfig; import android.net.util.MultinetworkPolicyTracker; -import android.net.util.NetdService; +import android.net.shared.NetdService; import android.os.Binder; import android.os.Build; import android.os.Bundle; diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 126bf6556538e..371276fbd2ae1 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -44,7 +44,7 @@ import android.net.LinkAddress; import android.net.Network; import android.net.NetworkUtils; import android.net.TrafficStats; -import android.net.util.NetdService; +import android.net.shared.NetdService; import android.os.Binder; import android.os.IBinder; import android.os.ParcelFileDescriptor; diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index 5ef3fe49da5d2..61a992fa7c618 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -60,7 +60,7 @@ import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.TetherStatsParcel; import android.net.UidRange; -import android.net.util.NetdService; +import android.net.shared.NetdService; import android.os.BatteryStats; import android.os.Binder; import android.os.Handler; diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java index ac745985417e1..79b56c6027f8b 100644 --- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java +++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java @@ -20,7 +20,6 @@ import android.content.Context; import android.net.ConnectivityMetricsEvent; import android.net.IIpConnectivityMetrics; import android.net.INetdEventCallback; -import android.net.ip.IpClient; import android.net.metrics.ApfProgramEvent; import android.net.metrics.IpConnectivityLog; import android.os.Binder; @@ -270,8 +269,6 @@ final public class IpConnectivityMetrics extends SystemService { // Dump the rolling buffer of metrics event and pretty print events using a human readable // format. Also print network dns/connect statistics and default network event time series. static final String CMD_LIST = "list"; - // Dump all IpClient logs ("ipclient"). - static final String CMD_IPCLIENT = IpClient.DUMP_ARG; // By default any other argument will fall into the default case which is the equivalent // of calling both the "list" and "ipclient" commands. This includes most notably bug // reports collected by dumpsys.cpp with the "-a" argument. @@ -295,20 +292,9 @@ final public class IpConnectivityMetrics extends SystemService { case CMD_PROTO: cmdListAsProto(pw); return; - case CMD_IPCLIENT: { - final String[] ipclientArgs = ((args != null) && (args.length > 1)) - ? Arrays.copyOfRange(args, 1, args.length) - : null; - IpClient.dumpAllLogs(pw, ipclientArgs); - return; - } case CMD_LIST: - cmdList(pw); - return; default: cmdList(pw); - pw.println(""); - IpClient.dumpAllLogs(pw, null); return; } } diff --git a/services/net/Android.bp b/services/net/Android.bp index 3b4d6a75591f2..30c7de57b73ea 100644 --- a/services/net/Android.bp +++ b/services/net/Android.bp @@ -3,18 +3,18 @@ java_library_static { srcs: ["java/**/*.java"], } -// TODO: move to networking module with DhcpClient and remove lib -java_library { - name: "dhcp-packet-lib", - srcs: [ - "java/android/net/dhcp/*Packet.java", - ] -} - filegroup { name: "services-networkstack-shared-srcs", srcs: [ - "java/android/net/util/FdEventsReader.java", // TODO: move to NetworkStack with IpClient + "java/android/net/ip/InterfaceController.java", // TODO: move to NetworkStack with tethering + "java/android/net/util/InterfaceParams.java", // TODO: move to NetworkStack with IpServer "java/android/net/shared/*.java", + ], +} + +java_library { + name: "services-netlink-lib", + srcs: [ + "java/android/net/netlink/*.java", ] } diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index 0aec10149b234..ddf7de386653b 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -16,8 +16,15 @@ package android.net.ip; +import static android.net.shared.IpConfigurationParcelableUtil.fromStableParcelable; +import static android.net.shared.LinkPropertiesParcelableUtil.fromStableParcelable; + import android.content.Context; +import android.net.DhcpResultsParcelable; import android.net.LinkProperties; +import android.net.LinkPropertiesParcelable; +import android.net.NetworkStack; +import android.net.ip.IIpClientCallbacks; import android.os.ConditionVariable; import java.io.FileDescriptor; @@ -31,8 +38,8 @@ import java.io.PrintWriter; * @hide */ public class IpClientUtil { - // TODO: remove once IpClient dumps are moved to NetworkStack and callers don't need this arg - public static final String DUMP_ARG = IpClient.DUMP_ARG; + // TODO: remove with its callers + public static final String DUMP_ARG = "ipclient"; /** * Subclass of {@link IpClientCallbacks} allowing clients to block until provisioning is @@ -69,24 +76,109 @@ public class IpClientUtil { * *

This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of * {@link IIpClientCallbacks}. + * @see {@link NetworkStack#makeIpClient(String, IIpClientCallbacks)} */ public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) { - // TODO: request IpClient asynchronously from NetworkStack. - final IpClient ipClient = new IpClient(context, ifName, callback); - callback.onIpClientCreated(ipClient.makeConnector()); + context.getSystemService(NetworkStack.class) + .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); + } + + private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { + protected final IpClientCallbacks mCb; + IpClientCallbacksProxy(IpClientCallbacks cb) { + mCb = cb; + } + + @Override + public void onIpClientCreated(IIpClient ipClient) { + mCb.onIpClientCreated(ipClient); + } + + @Override + public void onPreDhcpAction() { + mCb.onPreDhcpAction(); + } + + @Override + public void onPostDhcpAction() { + mCb.onPostDhcpAction(); + } + + // This is purely advisory and not an indication of provisioning + // success or failure. This is only here for callers that want to + // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress). + // DHCPv4 or static IPv4 configuration failure or success can be + // determined by whether or not the passed-in DhcpResults object is + // null or not. + @Override + public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) { + mCb.onNewDhcpResults(fromStableParcelable(dhcpResults)); + } + + @Override + public void onProvisioningSuccess(LinkPropertiesParcelable newLp) { + mCb.onProvisioningSuccess(fromStableParcelable(newLp)); + } + @Override + public void onProvisioningFailure(LinkPropertiesParcelable newLp) { + mCb.onProvisioningFailure(fromStableParcelable(newLp)); + } + + // Invoked on LinkProperties changes. + @Override + public void onLinkPropertiesChange(LinkPropertiesParcelable newLp) { + mCb.onLinkPropertiesChange(fromStableParcelable(newLp)); + } + + // Called when the internal IpReachabilityMonitor (if enabled) has + // detected the loss of a critical number of required neighbors. + @Override + public void onReachabilityLost(String logMsg) { + mCb.onReachabilityLost(logMsg); + } + + // Called when the IpClient state machine terminates. + @Override + public void onQuit() { + mCb.onQuit(); + } + + // Install an APF program to filter incoming packets. + @Override + public void installPacketFilter(byte[] filter) { + mCb.installPacketFilter(filter); + } + + // Asynchronously read back the APF program & data buffer from the wifi driver. + // Due to Wifi HAL limitations, the current implementation only supports dumping the entire + // buffer. In response to this request, the driver returns the data buffer asynchronously + // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message. + @Override + public void startReadPacketFilter() { + mCb.startReadPacketFilter(); + } + + // If multicast filtering cannot be accomplished with APF, this function will be called to + // actuate multicast filtering using another means. + @Override + public void setFallbackMulticastFilter(boolean enabled) { + mCb.setFallbackMulticastFilter(enabled); + } + + // Enabled/disable Neighbor Discover offload functionality. This is + // called, for example, whenever 464xlat is being started or stopped. + @Override + public void setNeighborDiscoveryOffload(boolean enable) { + mCb.setNeighborDiscoveryOffload(enable); + } } /** * Dump logs for the specified IpClient. - * TODO: remove logging from this method once IpClient logs are dumped in NetworkStack dumpsys, - * then remove callers and delete. + * TODO: remove callers and delete */ public static void dumpIpClient( IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args) { - if (!(connector instanceof IpClient.IpClientConnector)) { - pw.println("Invalid connector"); - return; - } - ((IpClient.IpClientConnector) connector).dumpIpClientLogs(fd, pw, args); + pw.println("IpClient logs have moved to dumpsys network_stack"); } } diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java index 7910c9a693104..f7360f52225fa 100644 --- a/services/net/java/android/net/ip/IpServer.java +++ b/services/net/java/android/net/ip/IpServer.java @@ -40,7 +40,7 @@ import android.net.dhcp.IDhcpServer; import android.net.ip.RouterAdvertisementDaemon.RaParams; import android.net.util.InterfaceParams; import android.net.util.InterfaceSet; -import android.net.util.NetdService; +import android.net.shared.NetdService; import android.net.util.SharedLog; import android.os.INetworkManagementService; import android.os.Looper; diff --git a/services/net/java/android/net/util/NetdService.java b/services/net/java/android/net/shared/NetdService.java similarity index 99% rename from services/net/java/android/net/util/NetdService.java rename to services/net/java/android/net/shared/NetdService.java index 80b2c2705038c..be0f5f2d4f340 100644 --- a/services/net/java/android/net/util/NetdService.java +++ b/services/net/java/android/net/shared/NetdService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.net.util; +package android.net.shared; import android.net.INetd; import android.os.RemoteException; diff --git a/services/net/java/android/net/util/InterfaceParams.java b/services/net/java/android/net/util/InterfaceParams.java index 7b060da01a89d..f6bb87369cad1 100644 --- a/services/net/java/android/net/util/InterfaceParams.java +++ b/services/net/java/android/net/util/InterfaceParams.java @@ -16,9 +16,6 @@ package android.net.util; -import static android.net.util.NetworkConstants.ETHER_MTU; -import static android.net.util.NetworkConstants.IPV6_MIN_MTU; - import static com.android.internal.util.Preconditions.checkArgument; import android.net.MacAddress; @@ -44,6 +41,11 @@ public class InterfaceParams { public final MacAddress macAddr; public final int defaultMtu; + // TODO: move the below to NetworkStackConstants when this class is moved to the NetworkStack. + private static final int ETHER_MTU = 1500; + private static final int IPV6_MIN_MTU = 1280; + + public static InterfaceParams getByName(String name) { final NetworkInterface netif = getNetworkInterfaceByName(name); if (netif == null) return null; diff --git a/services/net/java/android/net/util/NetworkConstants.java b/services/net/java/android/net/util/NetworkConstants.java index c183b81362dc9..ea5ce65f6f791 100644 --- a/services/net/java/android/net/util/NetworkConstants.java +++ b/services/net/java/android/net/util/NetworkConstants.java @@ -28,28 +28,6 @@ package android.net.util; public final class NetworkConstants { private NetworkConstants() { throw new RuntimeException("no instance permitted"); } - /** - * Ethernet constants. - * - * See also: - * - https://tools.ietf.org/html/rfc894 - * - https://tools.ietf.org/html/rfc2464 - * - https://tools.ietf.org/html/rfc7042 - * - http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml - * - http://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.xhtml - */ - public static final int ETHER_DST_ADDR_OFFSET = 0; - public static final int ETHER_SRC_ADDR_OFFSET = 6; - public static final int ETHER_ADDR_LEN = 6; - - public static final int ETHER_TYPE_OFFSET = 12; - public static final int ETHER_TYPE_LENGTH = 2; - public static final int ETHER_TYPE_ARP = 0x0806; - public static final int ETHER_TYPE_IPV4 = 0x0800; - public static final int ETHER_TYPE_IPV6 = 0x86dd; - - public static final int ETHER_HEADER_LEN = 14; - public static final byte FF = asByte(0xff); public static final byte[] ETHER_ADDR_BROADCAST = { FF, FF, FF, FF, FF, FF @@ -57,35 +35,13 @@ public final class NetworkConstants { public static final int ETHER_MTU = 1500; - /** - * ARP constants. - * - * See also: - * - https://tools.ietf.org/html/rfc826 - * - http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml - */ - public static final int ARP_PAYLOAD_LEN = 28; // For Ethernet+IPv4. - public static final int ARP_REQUEST = 1; - public static final int ARP_REPLY = 2; - public static final int ARP_HWTYPE_RESERVED_LO = 0; - public static final int ARP_HWTYPE_ETHER = 1; - public static final int ARP_HWTYPE_RESERVED_HI = 0xffff; - /** * IPv4 constants. * * See also: * - https://tools.ietf.org/html/rfc791 */ - public static final int IPV4_HEADER_MIN_LEN = 20; - public static final int IPV4_IHL_MASK = 0xf; - public static final int IPV4_FLAGS_OFFSET = 6; - public static final int IPV4_FRAGMENT_MASK = 0x1fff; - public static final int IPV4_PROTOCOL_OFFSET = 9; - public static final int IPV4_SRC_ADDR_OFFSET = 12; - public static final int IPV4_DST_ADDR_OFFSET = 16; public static final int IPV4_ADDR_BITS = 32; - public static final int IPV4_ADDR_LEN = 4; /** * IPv6 constants. @@ -93,15 +49,10 @@ public final class NetworkConstants { * See also: * - https://tools.ietf.org/html/rfc2460 */ - public static final int IPV6_HEADER_LEN = 40; - public static final int IPV6_PROTOCOL_OFFSET = 6; - public static final int IPV6_SRC_ADDR_OFFSET = 8; - public static final int IPV6_DST_ADDR_OFFSET = 24; public static final int IPV6_ADDR_BITS = 128; public static final int IPV6_ADDR_LEN = 16; public static final int IPV6_MIN_MTU = 1280; public static final int RFC7421_PREFIX_LENGTH = 64; - public static final int RFC6177_MIN_PREFIX_LENGTH = 48; /** * ICMP common (v4/v6) constants. @@ -124,45 +75,7 @@ public final class NetworkConstants { * - https://tools.ietf.org/html/rfc792 */ public static final int ICMPV4_ECHO_REQUEST_TYPE = 8; - - /** - * ICMPv6 constants. - * - * See also: - * - https://tools.ietf.org/html/rfc4443 - * - https://tools.ietf.org/html/rfc4861 - */ - public static final int ICMPV6_HEADER_MIN_LEN = 4; public static final int ICMPV6_ECHO_REQUEST_TYPE = 128; - public static final int ICMPV6_ECHO_REPLY_TYPE = 129; - public static final int ICMPV6_ROUTER_SOLICITATION = 133; - public static final int ICMPV6_ROUTER_ADVERTISEMENT = 134; - public static final int ICMPV6_NEIGHBOR_SOLICITATION = 135; - public static final int ICMPV6_NEIGHBOR_ADVERTISEMENT = 136; - - public static final int ICMPV6_ND_OPTION_MIN_LENGTH = 8; - public static final int ICMPV6_ND_OPTION_LENGTH_SCALING_FACTOR = 8; - public static final int ICMPV6_ND_OPTION_SLLA = 1; - public static final int ICMPV6_ND_OPTION_TLLA = 2; - public static final int ICMPV6_ND_OPTION_MTU = 5; - - - /** - * UDP constants. - * - * See also: - * - https://tools.ietf.org/html/rfc768 - */ - public static final int UDP_HEADER_LEN = 8; - - /** - * DHCP(v4) constants. - * - * See also: - * - https://tools.ietf.org/html/rfc2131 - */ - public static final int DHCP4_SERVER_PORT = 67; - public static final int DHCP4_CLIENT_PORT = 68; /** * DNS constants. @@ -176,9 +89,4 @@ public final class NetworkConstants { * Utility functions. */ public static byte asByte(int i) { return (byte) i; } - - public static String asString(int i) { return Integer.toString(i); } - - public static int asUint(byte b) { return (b & 0xff); } - public static int asUint(short s) { return (s & 0xffff); } } diff --git a/tests/net/Android.mk b/tests/net/Android.mk index 6850673771660..7e1b4008c4733 100644 --- a/tests/net/Android.mk +++ b/tests/net/Android.mk @@ -32,74 +32,6 @@ LOCAL_COMPATIBILITY_SUITE := device-tests LOCAL_CERTIFICATE := platform -# These are not normally accessible from apps so they must be explicitly included. -LOCAL_JNI_SHARED_LIBRARIES := \ - android.hidl.token@1.0 \ - libartbase \ - libbacktrace \ - libbase \ - libbinder \ - libbinderthreadstate \ - libc++ \ - libcrypto \ - libcutils \ - libdexfile \ - libframeworksnettestsjni \ - libhidl-gen-utils \ - libhidlbase \ - libhidltransport \ - libhwbinder \ - liblog \ - liblzma \ - libnativehelper \ - libpackagelistparser \ - libpcre2 \ - libprocessgroup \ - libselinux \ - libui \ - libutils \ - libvintf \ - libvndksupport \ - libtinyxml2 \ - libunwindstack \ - libutilscallstack \ - libziparchive \ - libz \ - netd_aidl_interface-cpp - LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk include $(BUILD_PACKAGE) - -######################################################################### -# Build JNI Shared Library -######################################################################### - -LOCAL_PATH:= $(LOCAL_PATH)/jni - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_CFLAGS := -Wall -Wextra -Werror - -LOCAL_C_INCLUDES := \ - libpcap \ - hardware/google/apf - -LOCAL_SRC_FILES := $(call all-cpp-files-under) - -LOCAL_SHARED_LIBRARIES := \ - libbinder \ - liblog \ - libcutils \ - libnativehelper \ - netd_aidl_interface-cpp - -LOCAL_STATIC_LIBRARIES := \ - libpcap \ - libapf - -LOCAL_MODULE := libframeworksnettestsjni - -include $(BUILD_SHARED_LIBRARY) From c6304b87416882a9ed71069de0572fb3181c734c Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Wed, 23 Jan 2019 16:24:30 +0900 Subject: [PATCH 2/2] Create a wrapper for IpClient The wrapper allows migrating clients of the IpClient in the NetworkStack independently. Test: atest FrameworksNetTests NetworkStackTests FrameworksWifiTests Bug: 112869080 Change-Id: I1250730c07166298bee2816f05351ba95416994a --- .../net/java/android/net/dhcp/DhcpClient.java | 29 ++ .../net/java/android/net/ip/IpClient.java | 320 ++++++++++++++++++ .../net/java/android/net/ip/IpClientUtil.java | 24 +- 3 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 services/net/java/android/net/dhcp/DhcpClient.java create mode 100644 services/net/java/android/net/ip/IpClient.java diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java new file mode 100644 index 0000000000000..cddb91f65d0f8 --- /dev/null +++ b/services/net/java/android/net/dhcp/DhcpClient.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.dhcp; + +/** + * TODO: remove this class after migrating clients. + */ +public class DhcpClient { + public static final int CMD_PRE_DHCP_ACTION = 1003; + public static final int CMD_POST_DHCP_ACTION = 1004; + public static final int CMD_PRE_DHCP_ACTION_COMPLETE = 1006; + + public static final int DHCP_SUCCESS = 1; + public static final int DHCP_FAILURE = 2; +} diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java new file mode 100644 index 0000000000000..a61c2efd64da7 --- /dev/null +++ b/services/net/java/android/net/ip/IpClient.java @@ -0,0 +1,320 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.ip; + +import static android.net.shared.LinkPropertiesParcelableUtil.toStableParcelable; + +import android.content.Context; +import android.net.LinkProperties; +import android.net.Network; +import android.net.ProxyInfo; +import android.net.StaticIpConfiguration; +import android.net.apf.ApfCapabilities; +import android.os.ConditionVariable; +import android.os.INetworkManagementService; +import android.os.RemoteException; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * Proxy for the IpClient in the NetworkStack. To be removed once clients are migrated. + * @hide + */ +public class IpClient { + private static final String TAG = IpClient.class.getSimpleName(); + private static final int IPCLIENT_BLOCK_TIMEOUT_MS = 10_000; + + public static final String DUMP_ARG = "ipclient"; + + private final ConditionVariable mIpClientCv; + private final ConditionVariable mShutdownCv; + + private volatile IIpClient mIpClient; + + /** + * @see IpClientCallbacks + */ + public static class Callback extends IpClientCallbacks {} + + /** + * IpClient callback that allows clients to block until provisioning is complete. + */ + public static class WaitForProvisioningCallback extends Callback { + private final ConditionVariable mCV = new ConditionVariable(); + private LinkProperties mCallbackLinkProperties; + + /** + * Block until either {@link #onProvisioningSuccess(LinkProperties)} or + * {@link #onProvisioningFailure(LinkProperties)} is called. + */ + public LinkProperties waitForProvisioning() { + mCV.block(); + return mCallbackLinkProperties; + } + + @Override + public void onProvisioningSuccess(LinkProperties newLp) { + mCallbackLinkProperties = newLp; + mCV.open(); + } + + @Override + public void onProvisioningFailure(LinkProperties newLp) { + mCallbackLinkProperties = null; + mCV.open(); + } + } + + private class CallbackImpl extends IpClientUtil.IpClientCallbacksProxy { + /** + * Create a new IpClientCallbacksProxy. + */ + CallbackImpl(IpClientCallbacks cb) { + super(cb); + } + + @Override + public void onIpClientCreated(IIpClient ipClient) { + mIpClient = ipClient; + mIpClientCv.open(); + super.onIpClientCreated(ipClient); + } + + @Override + public void onQuit() { + mShutdownCv.open(); + super.onQuit(); + } + } + + /** + * Create a new IpClient. + */ + public IpClient(Context context, String iface, Callback callback) { + mIpClientCv = new ConditionVariable(false); + mShutdownCv = new ConditionVariable(false); + + IpClientUtil.makeIpClient(context, iface, new CallbackImpl(callback)); + } + + /** + * @see IpClient#IpClient(Context, String, IpClient.Callback) + */ + public IpClient(Context context, String iface, Callback callback, + INetworkManagementService nms) { + this(context, iface, callback); + } + + private interface IpClientAction { + void useIpClient(IIpClient ipClient) throws RemoteException; + } + + private void doWithIpClient(IpClientAction action) { + mIpClientCv.block(IPCLIENT_BLOCK_TIMEOUT_MS); + try { + action.useIpClient(mIpClient); + } catch (RemoteException e) { + Log.e(TAG, "Error communicating with IpClient", e); + } + } + + /** + * Notify IpClient that PreDhcpAction is completed. + */ + public void completedPreDhcpAction() { + doWithIpClient(c -> c.completedPreDhcpAction()); + } + + /** + * Confirm the provisioning configuration. + */ + public void confirmConfiguration() { + doWithIpClient(c -> c.confirmConfiguration()); + } + + /** + * Notify IpClient that packet filter read is complete. + */ + public void readPacketFilterComplete(byte[] data) { + doWithIpClient(c -> c.readPacketFilterComplete(data)); + } + + /** + * Shutdown the IpClient altogether. + */ + public void shutdown() { + doWithIpClient(c -> c.shutdown()); + } + + /** + * Start the IpClient provisioning. + */ + public void startProvisioning(ProvisioningConfiguration config) { + doWithIpClient(c -> c.startProvisioning(config.toStableParcelable())); + } + + /** + * Stop the IpClient. + */ + public void stop() { + doWithIpClient(c -> c.stop()); + } + + /** + * Set the IpClient TCP buffer sizes. + */ + public void setTcpBufferSizes(String tcpBufferSizes) { + doWithIpClient(c -> c.setTcpBufferSizes(tcpBufferSizes)); + } + + /** + * Set the IpClient HTTP proxy. + */ + public void setHttpProxy(ProxyInfo proxyInfo) { + doWithIpClient(c -> c.setHttpProxy(toStableParcelable(proxyInfo))); + } + + /** + * Set the IpClient multicast filter. + */ + public void setMulticastFilter(boolean enabled) { + doWithIpClient(c -> c.setMulticastFilter(enabled)); + } + + /** + * Dump IpClient logs. + */ + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + doWithIpClient(c -> IpClientUtil.dumpIpClient(c, fd, pw, args)); + } + + /** + * Block until IpClient shutdown. + */ + public void awaitShutdown() { + mShutdownCv.block(IPCLIENT_BLOCK_TIMEOUT_MS); + } + + /** + * Create a new ProvisioningConfiguration. + */ + public static ProvisioningConfiguration.Builder buildProvisioningConfiguration() { + return new ProvisioningConfiguration.Builder(); + } + + /** + * TODO: remove after migrating clients to use the shared configuration class directly. + * @see android.net.shared.ProvisioningConfiguration + */ + public static class ProvisioningConfiguration + extends android.net.shared.ProvisioningConfiguration { + public ProvisioningConfiguration(android.net.shared.ProvisioningConfiguration other) { + super(other); + } + + /** + * @see android.net.shared.ProvisioningConfiguration.Builder + */ + public static class Builder extends android.net.shared.ProvisioningConfiguration.Builder { + // Override all methods to have a return type matching this Builder + @Override + public Builder withoutIPv4() { + super.withoutIPv4(); + return this; + } + + @Override + public Builder withoutIPv6() { + super.withoutIPv6(); + return this; + } + + @Override + public Builder withoutMultinetworkPolicyTracker() { + super.withoutMultinetworkPolicyTracker(); + return this; + } + + @Override + public Builder withoutIpReachabilityMonitor() { + super.withoutIpReachabilityMonitor(); + return this; + } + + @Override + public Builder withPreDhcpAction() { + super.withPreDhcpAction(); + return this; + } + + @Override + public Builder withPreDhcpAction(int dhcpActionTimeoutMs) { + super.withPreDhcpAction(dhcpActionTimeoutMs); + return this; + } + + @Override + public Builder withStaticConfiguration(StaticIpConfiguration staticConfig) { + super.withStaticConfiguration(staticConfig); + return this; + } + + @Override + public Builder withApfCapabilities(ApfCapabilities apfCapabilities) { + super.withApfCapabilities(apfCapabilities); + return this; + } + + @Override + public Builder withProvisioningTimeoutMs(int timeoutMs) { + super.withProvisioningTimeoutMs(timeoutMs); + return this; + } + + @Override + public Builder withRandomMacAddress() { + super.withRandomMacAddress(); + return this; + } + + @Override + public Builder withStableMacAddress() { + super.withStableMacAddress(); + return this; + } + + @Override + public Builder withNetwork(Network network) { + super.withNetwork(network); + return this; + } + + @Override + public Builder withDisplayName(String displayName) { + super.withDisplayName(displayName); + return this; + } + + @Override + public ProvisioningConfiguration build() { + return new ProvisioningConfiguration(mConfig); + } + } + } +} diff --git a/services/net/java/android/net/ip/IpClientUtil.java b/services/net/java/android/net/ip/IpClientUtil.java index ddf7de386653b..2a2a67a92a86a 100644 --- a/services/net/java/android/net/ip/IpClientUtil.java +++ b/services/net/java/android/net/ip/IpClientUtil.java @@ -83,9 +83,29 @@ public class IpClientUtil { .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); } - private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { + /** + * Create a new IpClient. + * + *

This is a convenience method to allow clients to use {@link IpClientCallbacksProxy} + * instead of {@link IIpClientCallbacks}. + * @see {@link NetworkStack#makeIpClient(String, IIpClientCallbacks)} + */ + public static void makeIpClient( + Context context, String ifName, IpClientCallbacksProxy callback) { + context.getSystemService(NetworkStack.class) + .makeIpClient(ifName, callback); + } + + /** + * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}. + */ + public static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { protected final IpClientCallbacks mCb; - IpClientCallbacksProxy(IpClientCallbacks cb) { + + /** + * Create a new IpClientCallbacksProxy. + */ + public IpClientCallbacksProxy(IpClientCallbacks cb) { mCb = cb; }