Snap for 8982257 from 8da06cba7fdc2d2516545152def34ea4e5eb359b to mainline-conscrypt-release Change-Id: I39571758bb0992154a276c9c872bd67cbfb5acb7
diff --git a/Android.bp b/Android.bp index 4b3d558..aa0f42d 100644 --- a/Android.bp +++ b/Android.bp
@@ -153,6 +153,12 @@ srcs: [ "apishim/31/**/*.java", ], + static_libs: [ + // Libs building against module API can only be linked against when building against + // module API (so NetworkStackApi30Shims or NetworkStackApi29Shims can't use it, since they + // use system_30 and system_29 respectively). + "net-utils-framework-common", + ], libs: [ "NetworkStackShimsCommon", "NetworkStackApi29Shims", @@ -169,9 +175,6 @@ srcs: [ "apishim/33/**/*.java", ], - static_libs: [ - "net-utils-framework-common", - ], libs: [ "NetworkStackShimsCommon", "NetworkStackApi29Shims", @@ -189,15 +192,16 @@ // Shims for APIs being added to the current development version of Android. These APIs are not // stable and have no defined version number. These could be called 10000, but they use the next // integer so if the next SDK release happens to use that integer, we don't need to rename them. +// Jarjar rules are generated based on the stable shims, which do not contain this library. As a +// result, no static_lib that needs jarjar should be used here. In general, static_libs should not +// be used in this library at all; instead they can be in one of the earlier, shim libraries which +// are part of the stable shims and scanned when generating jarjar rules. java_library { name: "NetworkStackApi34Shims", defaults: ["NetworkStackShimsDefaults", "ConnectivityNextEnableDefaults"], srcs: [ "apishim/34/**/*.java", ], - static_libs: [ - "net-utils-framework-common", - ], libs: [ "NetworkStackShimsCommon", "NetworkStackApi29Shims", @@ -268,7 +272,6 @@ name: "NetworkStackAndroidLibraryDefaults", srcs: [ ":framework-networkstack-shared-srcs", - ":networkstack-module-utils-srcs", ], libs: ["unsupportedappusage"], static_libs: [ @@ -284,6 +287,7 @@ "statsprotos", "captiveportal-lib", "net-utils-device-common", + "net-utils-device-common-ip", "net-utils-device-common-netlink", ], plugins: ["java_api_finder"], @@ -306,7 +310,6 @@ visibility: [ "//frameworks/base/tests/net/integration", "//packages/modules/Connectivity/Tethering/tests/integration", - "//packages/modules/Connectivity/tests/cts/net", "//packages/modules/NetworkStack/tests/unit", "//packages/modules/NetworkStack/tests/integration", ], @@ -326,7 +329,6 @@ "//frameworks/base/packages/Connectivity/tests/integration", "//frameworks/base/tests/net/integration", "//packages/modules/Connectivity/Tethering/tests/integration", - "//packages/modules/Connectivity/tests/cts/net", "//packages/modules/Connectivity/tests/integration", "//packages/modules/NetworkStack/tests/unit", "//packages/modules/NetworkStack/tests/integration", @@ -334,15 +336,52 @@ lint: { strict_updatability_linting: true }, } -filegroup { +java_library { + name: "DhcpPacketLib", + defaults: ["NetworkStackReleaseApiLevel"], + srcs: [ + "src/android/net/DhcpResults.java", + "src/android/net/dhcp/Dhcp*Packet.java", + ], + libs: [ + "androidx.annotation_annotation", + "framework-annotations-lib", + ], + static_libs: [ + "modules-utils-build", + "net-utils-framework-common", + "networkstack-client", + ], + // If this library is ever used outside of tests, it should not use "Dhcp*Packet", and specify + // its contents explicitly. + visibility: ["//packages/modules/Connectivity/tests/cts/net"], +} + +java_genrule { name: "NetworkStackJarJarRules", - srcs: ["jarjar-rules-shared.txt"], + tool_files: [ + // com.android.networkstack.apishim is already in the target package that is not jarjared, + // so it does not matter whether ApiStable or ApiCurrent is used to generate the jarjar + // rules. Use ApiStable to be based on most stable release configuration and be buildable + // in all branches. + ":NetworkStackApiStableLib{.jar}", + "jarjar-excludes.txt", + ], + tools: [ + "jarjar-rules-generator", + ], + out: ["NetworkStackJarJarRules.txt"], + cmd: "$(location jarjar-rules-generator) " + + "--jars $(location :NetworkStackApiStableLib{.jar}) " + + "--prefix com.android.networkstack " + + "--excludes $(location jarjar-excludes.txt) " + + "--output $(out)", visibility: [ "//packages/modules/NetworkStack/tests/unit", "//packages/modules/NetworkStack/tests/integration", "//packages/modules/Connectivity/tests:__subpackages__", "//packages/modules/Connectivity/Tethering/tests/integration", - ] + ], } // Common defaults for compiling the actual APK, based on the NetworkStackApiXBase android libraries
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d616750..9fe8b1d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml
@@ -58,14 +58,15 @@ The service is protected by NETWORK_SETTINGS permissions as there is no better networking-related permission that exists on Q, is sufficiently protected (signature), and can be obtained via shell permissions. --> - <service android:name="com.android.server.TestNetworkStackService" + <!-- (The name starting with a dot means the package prefix is the APK package name) --> + <service android:name=".TestNetworkStackService" android:permission="android.permission.NETWORK_SETTINGS" android:exported="true"> <intent-filter> <action android:name="android.net.INetworkStackConnector.Test"/> </intent-filter> </service> - <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService" + <service android:name=".ipmemorystore.RegularMaintenanceJobService" android:permission="android.permission.BIND_JOB_SERVICE" > </service> </application>
diff --git a/AndroidManifest_InProcess.xml b/AndroidManifest_InProcess.xml index 7934826..40d74a5 100644 --- a/AndroidManifest_InProcess.xml +++ b/AndroidManifest_InProcess.xml
@@ -33,7 +33,7 @@ <action android:name="android.net.INetworkStackConnector.InProcess"/> </intent-filter> </service> - <service android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService" + <service android:name="com.android.networkstack.ipmemorystore.RegularMaintenanceJobService" android:process="system" android:permission="android.permission.BIND_JOB_SERVICE" > </service>
diff --git a/TEST_MAPPING b/TEST_MAPPING index 5dd1654..1d0f234 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING
@@ -10,32 +10,13 @@ "name": "NetworkStackIntegrationTests" } ], - "auto-postsubmit": [ - // Test tag for automotive targets. These are only running in postsubmit so as to harden the - // automotive targets to avoid introducing additional test flake and build time. The plan for - // presubmit testing for auto is to augment the existing tests to cover auto use cases as well. - // Additionally, this tag is used in targeted test suites to limit resource usage on the test - // infra during the hardening phase. - // TODO: this tag to be removed once the above is no longer an issue. - { - "name": "NetworkStackTests" - }, - { - "name": "NetworkStackNextTests" - }, - { - "name": "NetworkStackIntegrationTests" - } - ], "mainline-presubmit": [ // These are unit tests only, so they don't actually require any modules to be installed. // We must specify at least one module here or the tests won't run. Use the same set as CTS // so in theory the infra would not need to reinstall/reboot devices to run both. { "name": "NetworkStackTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]" - } - ], - "mainline-postsubmit": [ + }, { "name": "NetworkStackIntegrationTests[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]" }
diff --git a/common/moduleutils/Android.bp b/common/moduleutils/Android.bp deleted file mode 100644 index c0ee3f4..0000000 --- a/common/moduleutils/Android.bp +++ /dev/null
@@ -1,71 +0,0 @@ -// -// 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. -// - -// Shared utility sources to be used by multiple network modules -// TODO: remove all frameworks/base dependencies on packages/modules/NetworkStack and -// frameworks/base/packages/Tethering by moving these files to frameworks/libs/net. -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -// TODO: remove this filegroup together with services.net -filegroup { - name: "net-module-utils-srcs", - srcs: [ - "src/android/net/shared/NetdUtils.java", - "src/android/net/util/SharedLog.java", - ], - visibility: [ - "//frameworks/base/services/net", - ] -} - -filegroup { - name: "connectivity-module-utils-srcs", - srcs: [ - "src/android/net/util/SharedLog.java", - "src/android/net/shared/NetdUtils.java", - "src/android/net/shared/NetworkMonitorUtils.java", - ], - visibility: [ - "//packages/modules/Connectivity/service", - ] -} - -filegroup { - name: "networkstack-module-utils-srcs", - srcs: ["src/**/*.java"], - visibility: [ - "//packages/modules/NetworkStack", - ] -} - -// Shared utility sources to be used by tethering modules -filegroup { - name: "tethering-module-utils-srcs", - srcs: [ - "src/android/net/ip/ConntrackMonitor.java", - "src/android/net/ip/InterfaceController.java", - "src/android/net/ip/IpNeighborMonitor.java", - "src/android/net/ip/NetlinkMonitor.java", - "src/android/net/shared/NetdUtils.java", - "src/android/net/util/SharedLog.java", - ], - visibility: [ - "//frameworks/base/packages/Tethering", - "//packages/modules/Connectivity/Tethering" - ], -}
diff --git a/common/moduleutils/src/android/net/ip/ConntrackMonitor.java b/common/moduleutils/src/android/net/ip/ConntrackMonitor.java deleted file mode 100644 index 43005cd..0000000 --- a/common/moduleutils/src/android/net/ip/ConntrackMonitor.java +++ /dev/null
@@ -1,204 +0,0 @@ -/* - * Copyright (C) 2020 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 com.android.net.module.util.netlink.ConntrackMessage.DYING_MASK; -import static com.android.net.module.util.netlink.ConntrackMessage.ESTABLISHED_MASK; - -import android.net.util.SharedLog; -import android.os.Handler; -import android.system.OsConstants; - -import androidx.annotation.NonNull; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.net.module.util.netlink.ConntrackMessage; -import com.android.net.module.util.netlink.NetlinkConstants; -import com.android.net.module.util.netlink.NetlinkMessage; - -import java.util.Objects; - - -/** - * ConntrackMonitor. - * - * Monitors the netfilter conntrack notifications and presents to callers - * ConntrackEvents describing each event. - * - * @hide - */ -public class ConntrackMonitor extends NetlinkMonitor { - private static final String TAG = ConntrackMonitor.class.getSimpleName(); - private static final boolean DBG = false; - private static final boolean VDBG = false; - - // Reference kernel/uapi/linux/netfilter/nfnetlink_compat.h - public static final int NF_NETLINK_CONNTRACK_NEW = 1; - public static final int NF_NETLINK_CONNTRACK_UPDATE = 2; - public static final int NF_NETLINK_CONNTRACK_DESTROY = 4; - - // The socket receive buffer size in bytes. If too many conntrack messages are sent too - // quickly, the conntrack messages can overflow the socket receive buffer. This can happen - // if too many connections are disconnected by losing network and so on. Use a large-enough - // buffer to avoid the error ENOBUFS while listening to the conntrack messages. - private static final int SOCKET_RECV_BUFSIZE = 6 * 1024 * 1024; - - /** - * A class for describing parsed netfilter conntrack events. - */ - public static class ConntrackEvent { - /** - * Conntrack event type. - */ - public final short msgType; - /** - * Original direction conntrack tuple. - */ - public final ConntrackMessage.Tuple tupleOrig; - /** - * Reply direction conntrack tuple. - */ - public final ConntrackMessage.Tuple tupleReply; - /** - * Connection status. A bitmask of ip_conntrack_status enum flags. - */ - public final int status; - /** - * Conntrack timeout. - */ - public final int timeoutSec; - - public ConntrackEvent(ConntrackMessage msg) { - this.msgType = msg.getHeader().nlmsg_type; - this.tupleOrig = msg.tupleOrig; - this.tupleReply = msg.tupleReply; - this.status = msg.status; - this.timeoutSec = msg.timeoutSec; - } - - @VisibleForTesting - public ConntrackEvent(short msgType, ConntrackMessage.Tuple tupleOrig, - ConntrackMessage.Tuple tupleReply, int status, int timeoutSec) { - this.msgType = msgType; - this.tupleOrig = tupleOrig; - this.tupleReply = tupleReply; - this.status = status; - this.timeoutSec = timeoutSec; - } - - @Override - @VisibleForTesting - public boolean equals(Object o) { - if (!(o instanceof ConntrackEvent)) return false; - ConntrackEvent that = (ConntrackEvent) o; - return this.msgType == that.msgType - && Objects.equals(this.tupleOrig, that.tupleOrig) - && Objects.equals(this.tupleReply, that.tupleReply) - && this.status == that.status - && this.timeoutSec == that.timeoutSec; - } - - @Override - public int hashCode() { - return Objects.hash(msgType, tupleOrig, tupleReply, status, timeoutSec); - } - - @Override - public String toString() { - return "ConntrackEvent{" - + "msg_type{" - + NetlinkConstants.stringForNlMsgType(msgType, OsConstants.NETLINK_NETFILTER) - + "}, " - + "tuple_orig{" + tupleOrig + "}, " - + "tuple_reply{" + tupleReply + "}, " - + "status{" - + status + "(" + ConntrackMessage.stringForIpConntrackStatus(status) + ")" - + "}, " - + "timeout_sec{" + Integer.toUnsignedLong(timeoutSec) + "}" - + "}"; - } - - /** - * Check the established NAT session conntrack message. - * - * @param msg the conntrack message to check. - * @return true if an established NAT message, false if not. - */ - public static boolean isEstablishedNatSession(@NonNull ConntrackMessage msg) { - if (msg.getMessageType() != NetlinkConstants.IPCTNL_MSG_CT_NEW) return false; - if (msg.tupleOrig == null) return false; - if (msg.tupleReply == null) return false; - if (msg.timeoutSec == 0) return false; - if ((msg.status & ESTABLISHED_MASK) != ESTABLISHED_MASK) return false; - - return true; - } - - /** - * Check the dying NAT session conntrack message. - * Note that IPCTNL_MSG_CT_DELETE event has no CTA_TIMEOUT attribute. - * - * @param msg the conntrack message to check. - * @return true if a dying NAT message, false if not. - */ - public static boolean isDyingNatSession(@NonNull ConntrackMessage msg) { - if (msg.getMessageType() != NetlinkConstants.IPCTNL_MSG_CT_DELETE) return false; - if (msg.tupleOrig == null) return false; - if (msg.tupleReply == null) return false; - if (msg.timeoutSec != 0) return false; - if ((msg.status & DYING_MASK) != DYING_MASK) return false; - - return true; - } - } - - /** - * A callback to caller for conntrack event. - */ - public interface ConntrackEventConsumer { - /** - * Every conntrack event received on the netlink socket is passed in - * here. - */ - void accept(@NonNull ConntrackEvent event); - } - - private final ConntrackEventConsumer mConsumer; - - public ConntrackMonitor(@NonNull Handler h, @NonNull SharedLog log, - @NonNull ConntrackEventConsumer cb) { - super(h, log, TAG, OsConstants.NETLINK_NETFILTER, NF_NETLINK_CONNTRACK_NEW - | NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY, SOCKET_RECV_BUFSIZE); - mConsumer = cb; - } - - @Override - public void processNetlinkMessage(NetlinkMessage nlMsg, final long whenMs) { - if (!(nlMsg instanceof ConntrackMessage)) { - mLog.e("non-conntrack msg: " + nlMsg); - return; - } - - final ConntrackMessage conntrackMsg = (ConntrackMessage) nlMsg; - if (!(ConntrackEvent.isEstablishedNatSession(conntrackMsg) - || ConntrackEvent.isDyingNatSession(conntrackMsg))) { - return; - } - - mConsumer.accept(new ConntrackEvent(conntrackMsg)); - } -}
diff --git a/common/moduleutils/src/android/net/ip/InterfaceController.java b/common/moduleutils/src/android/net/ip/InterfaceController.java deleted file mode 100644 index e8fc72c..0000000 --- a/common/moduleutils/src/android/net/ip/InterfaceController.java +++ /dev/null
@@ -1,211 +0,0 @@ -/* - * 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.INetd.IF_STATE_DOWN; -import static android.net.INetd.IF_STATE_UP; - -import android.net.INetd; -import android.net.InterfaceConfigurationParcel; -import android.net.LinkAddress; -import android.net.util.SharedLog; -import android.os.RemoteException; -import android.os.ServiceSpecificException; -import android.system.OsConstants; - -import java.net.Inet4Address; -import java.net.InetAddress; - - -/** - * Encapsulates the multiple IP configuration operations performed on an interface. - * - * TODO: refactor/eliminate the redundant ways to set and clear addresses. - * - * @hide - */ -public class InterfaceController { - private final static boolean DBG = false; - - private final String mIfName; - private final INetd mNetd; - private final SharedLog mLog; - - public InterfaceController(String ifname, INetd netd, SharedLog log) { - mIfName = ifname; - mNetd = netd; - mLog = log; - } - - /** - * Set the IPv4 address and also optionally bring the interface up or down. - */ - public boolean setInterfaceConfiguration(final LinkAddress ipv4Addr, - final Boolean setIfaceUp) { - if (!(ipv4Addr.getAddress() instanceof Inet4Address)) { - throw new IllegalArgumentException("Invalid or mismatched Inet4Address"); - } - // Note: currently netd only support INetd#IF_STATE_UP and #IF_STATE_DOWN. - // Other flags would be ignored. - - final InterfaceConfigurationParcel ifConfig = new InterfaceConfigurationParcel(); - ifConfig.ifName = mIfName; - ifConfig.ipv4Addr = ipv4Addr.getAddress().getHostAddress(); - ifConfig.prefixLength = ipv4Addr.getPrefixLength(); - // Netd ignores hwaddr in interfaceSetCfg. - ifConfig.hwAddr = ""; - if (setIfaceUp == null) { - // Empty array means no change. - ifConfig.flags = new String[0]; - } else { - // Netd ignores any flag that's not IF_STATE_UP or IF_STATE_DOWN in interfaceSetCfg. - ifConfig.flags = setIfaceUp.booleanValue() - ? new String[] {IF_STATE_UP} : new String[] {IF_STATE_DOWN}; - } - try { - mNetd.interfaceSetCfg(ifConfig); - } catch (RemoteException | ServiceSpecificException e) { - logError("Setting IPv4 address to %s/%d failed: %s", - ifConfig.ipv4Addr, ifConfig.prefixLength, e); - return false; - } - return true; - } - - /** - * Set the IPv4 address of the interface. - */ - public boolean setIPv4Address(final LinkAddress address) { - return setInterfaceConfiguration(address, null); - } - - /** - * Clear the IPv4Address of the interface. - */ - public boolean clearIPv4Address() { - return setIPv4Address(new LinkAddress("0.0.0.0/0")); - } - - private boolean setEnableIPv6(boolean enabled) { - try { - mNetd.interfaceSetEnableIPv6(mIfName, enabled); - } catch (RemoteException | ServiceSpecificException e) { - logError("%s IPv6 failed: %s", (enabled ? "enabling" : "disabling"), e); - return false; - } - return true; - } - - /** - * Enable IPv6 on the interface. - */ - public boolean enableIPv6() { - return setEnableIPv6(true); - } - - /** - * Disable IPv6 on the interface. - */ - public boolean disableIPv6() { - return setEnableIPv6(false); - } - - /** - * Enable or disable IPv6 privacy extensions on the interface. - * @param enabled Whether the extensions should be enabled. - */ - public boolean setIPv6PrivacyExtensions(boolean enabled) { - try { - mNetd.interfaceSetIPv6PrivacyExtensions(mIfName, enabled); - } catch (RemoteException | ServiceSpecificException e) { - logError("error %s IPv6 privacy extensions: %s", - (enabled ? "enabling" : "disabling"), e); - return false; - } - return true; - } - - /** - * Set IPv6 address generation mode on the interface. - * - * <p>IPv6 should be disabled before changing the mode. - */ - public boolean setIPv6AddrGenModeIfSupported(int mode) { - try { - mNetd.setIPv6AddrGenMode(mIfName, mode); - } catch (RemoteException e) { - logError("Unable to set IPv6 addrgen mode: %s", e); - return false; - } catch (ServiceSpecificException e) { - if (e.errorCode != OsConstants.EOPNOTSUPP) { - logError("Unable to set IPv6 addrgen mode: %s", e); - return false; - } - } - return true; - } - - /** - * Add an address to the interface. - */ - public boolean addAddress(LinkAddress addr) { - return addAddress(addr.getAddress(), addr.getPrefixLength()); - } - - /** - * Add an address to the interface. - */ - public boolean addAddress(InetAddress ip, int prefixLen) { - try { - mNetd.interfaceAddAddress(mIfName, ip.getHostAddress(), prefixLen); - } catch (ServiceSpecificException | RemoteException e) { - logError("failed to add %s/%d: %s", ip, prefixLen, e); - return false; - } - return true; - } - - /** - * Remove an address from the interface. - */ - public boolean removeAddress(InetAddress ip, int prefixLen) { - try { - mNetd.interfaceDelAddress(mIfName, ip.getHostAddress(), prefixLen); - } catch (ServiceSpecificException | RemoteException e) { - logError("failed to remove %s/%d: %s", ip, prefixLen, e); - return false; - } - return true; - } - - /** - * Remove all addresses from the interface. - */ - public boolean clearAllAddresses() { - try { - mNetd.interfaceClearAddrs(mIfName); - } catch (Exception e) { - logError("Failed to clear addresses: %s", e); - return false; - } - return true; - } - - private void logError(String fmt, Object... args) { - mLog.e(String.format(fmt, args)); - } -}
diff --git a/common/moduleutils/src/android/net/ip/IpNeighborMonitor.java b/common/moduleutils/src/android/net/ip/IpNeighborMonitor.java deleted file mode 100644 index a16fdf2..0000000 --- a/common/moduleutils/src/android/net/ip/IpNeighborMonitor.java +++ /dev/null
@@ -1,179 +0,0 @@ -/* - * Copyright (C) 2017 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.system.OsConstants.NETLINK_ROUTE; - -import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH; -import static com.android.net.module.util.netlink.NetlinkConstants.hexify; -import static com.android.net.module.util.netlink.NetlinkConstants.stringForNlMsgType; - -import android.net.MacAddress; -import android.net.util.SharedLog; -import android.os.Handler; -import android.system.ErrnoException; -import android.system.OsConstants; -import android.util.Log; - -import com.android.net.module.util.netlink.NetlinkMessage; -import com.android.net.module.util.netlink.NetlinkSocket; -import com.android.net.module.util.netlink.RtNetlinkNeighborMessage; -import com.android.net.module.util.netlink.StructNdMsg; - -import java.net.InetAddress; -import java.util.StringJoiner; - - -/** - * IpNeighborMonitor. - * - * Monitors the kernel rtnetlink neighbor notifications and presents to callers - * NeighborEvents describing each event. Callers can provide a consumer instance - * to both filter (e.g. by interface index and IP address) and handle the - * generated NeighborEvents. - * - * @hide - */ -public class IpNeighborMonitor extends NetlinkMonitor { - private static final String TAG = IpNeighborMonitor.class.getSimpleName(); - private static final boolean DBG = false; - private static final boolean VDBG = false; - - /** - * Make the kernel perform neighbor reachability detection (IPv4 ARP or IPv6 ND) - * for the given IP address on the specified interface index. - * - * @return 0 if the request was successfully passed to the kernel; otherwise return - * a non-zero error code. - */ - public static int startKernelNeighborProbe(int ifIndex, InetAddress ip) { - final String msgSnippet = "probing ip=" + ip.getHostAddress() + "%" + ifIndex; - if (DBG) { Log.d(TAG, msgSnippet); } - - final byte[] msg = RtNetlinkNeighborMessage.newNewNeighborMessage( - 1, ip, StructNdMsg.NUD_PROBE, ifIndex, null); - - try { - NetlinkSocket.sendOneShotKernelMessage(NETLINK_ROUTE, msg); - } catch (ErrnoException e) { - Log.e(TAG, "Error " + msgSnippet + ": " + e); - return -e.errno; - } - - return 0; - } - - public static class NeighborEvent { - final long elapsedMs; - final short msgType; - final int ifindex; - final InetAddress ip; - final short nudState; - final MacAddress macAddr; - - public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip, - short nudState, MacAddress macAddr) { - this.elapsedMs = elapsedMs; - this.msgType = msgType; - this.ifindex = ifindex; - this.ip = ip; - this.nudState = nudState; - this.macAddr = macAddr; - } - - boolean isConnected() { - return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState); - } - - boolean isValid() { - return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState); - } - - @Override - public String toString() { - final StringJoiner j = new StringJoiner(",", "NeighborEvent{", "}"); - return j.add("@" + elapsedMs) - .add(stringForNlMsgType(msgType, NETLINK_ROUTE)) - .add("if=" + ifindex) - .add(ip.getHostAddress()) - .add(StructNdMsg.stringForNudState(nudState)) - .add("[" + macAddr + "]") - .toString(); - } - } - - public interface NeighborEventConsumer { - // Every neighbor event received on the netlink socket is passed in - // here. Subclasses should filter for events of interest. - public void accept(NeighborEvent event); - } - - private final NeighborEventConsumer mConsumer; - - public IpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb) { - super(h, log, TAG, NETLINK_ROUTE, OsConstants.RTMGRP_NEIGH); - mConsumer = (cb != null) ? cb : (event) -> { /* discard */ }; - } - - @Override - public void processNetlinkMessage(NetlinkMessage nlMsg, final long whenMs) { - if (!(nlMsg instanceof RtNetlinkNeighborMessage)) { - mLog.e("non-rtnetlink neighbor msg: " + nlMsg); - return; - } - - final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) nlMsg; - final short msgType = neighMsg.getHeader().nlmsg_type; - final StructNdMsg ndMsg = neighMsg.getNdHeader(); - if (ndMsg == null) { - mLog.e("RtNetlinkNeighborMessage without ND message header!"); - return; - } - - final int ifindex = ndMsg.ndm_ifindex; - final InetAddress destination = neighMsg.getDestination(); - final short nudState = - (msgType == RTM_DELNEIGH) - ? StructNdMsg.NUD_NONE - : ndMsg.ndm_state; - - final NeighborEvent event = new NeighborEvent( - whenMs, msgType, ifindex, destination, nudState, - getMacAddress(neighMsg.getLinkLayerAddress())); - - if (VDBG) { - Log.d(TAG, neighMsg.toString()); - } - if (DBG) { - Log.d(TAG, event.toString()); - } - - mConsumer.accept(event); - } - - private static MacAddress getMacAddress(byte[] linkLayerAddress) { - if (linkLayerAddress != null) { - try { - return MacAddress.fromBytes(linkLayerAddress); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Failed to parse link-layer address: " + hexify(linkLayerAddress)); - } - } - - return null; - } -}
diff --git a/common/moduleutils/src/android/net/ip/NetlinkMonitor.java b/common/moduleutils/src/android/net/ip/NetlinkMonitor.java deleted file mode 100644 index e58b44e..0000000 --- a/common/moduleutils/src/android/net/ip/NetlinkMonitor.java +++ /dev/null
@@ -1,196 +0,0 @@ -/* - * Copyright (C) 2020 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.util.SocketUtils.makeNetlinkSocketAddress; -import static android.system.OsConstants.AF_NETLINK; -import static android.system.OsConstants.ENOBUFS; -import static android.system.OsConstants.SOCK_DGRAM; -import static android.system.OsConstants.SOCK_NONBLOCK; -import static android.system.OsConstants.SOL_SOCKET; -import static android.system.OsConstants.SO_RCVBUF; - -import static com.android.net.module.util.netlink.NetlinkConstants.hexify; - -import android.annotation.NonNull; -import android.net.util.SharedLog; -import android.net.util.SocketUtils; -import android.os.Handler; -import android.os.SystemClock; -import android.system.ErrnoException; -import android.system.Os; -import android.util.Log; - -import com.android.net.module.util.PacketReader; -import com.android.net.module.util.netlink.NetlinkErrorMessage; -import com.android.net.module.util.netlink.NetlinkMessage; -import com.android.net.module.util.netlink.NetlinkSocket; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.net.SocketAddress; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * A simple base class to listen for netlink broadcasts. - * - * Opens a netlink socket of the given family and binds to the specified groups. Polls the socket - * from the event loop of the passed-in {@link Handler}, and calls the subclass-defined - * {@link #processNetlinkMessage} method on the handler thread for each netlink message that - * arrives. Currently ignores all netlink errors. - */ -public class NetlinkMonitor extends PacketReader { - protected final SharedLog mLog; - protected final String mTag; - private final int mFamily; - private final int mBindGroups; - private final int mSockRcvbufSize; - - private static final boolean DBG = false; - - // Default socket receive buffer size. This means the specific buffer size is not set. - private static final int DEFAULT_SOCKET_RECV_BUFSIZE = -1; - - /** - * Constructs a new {@code NetlinkMonitor} instance. - * - * @param h The Handler on which to poll for messages and on which to call - * {@link #processNetlinkMessage}. - * @param log A SharedLog to log to. - * @param tag The log tag to use for log messages. - * @param family the Netlink socket family to, e.g., {@code NETLINK_ROUTE}. - * @param bindGroups the netlink groups to bind to. - * @param sockRcvbufSize the specific socket receive buffer size in bytes. -1 means that don't - * set the specific socket receive buffer size in #createFd and use the default value in - * /proc/sys/net/core/rmem_default file. See SO_RCVBUF in man-pages/socket. - */ - public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag, - int family, int bindGroups, int sockRcvbufSize) { - super(h, NetlinkSocket.DEFAULT_RECV_BUFSIZE); - mLog = log.forSubComponent(tag); - mTag = tag; - mFamily = family; - mBindGroups = bindGroups; - mSockRcvbufSize = sockRcvbufSize; - } - - public NetlinkMonitor(@NonNull Handler h, @NonNull SharedLog log, @NonNull String tag, - int family, int bindGroups) { - this(h, log, tag, family, bindGroups, DEFAULT_SOCKET_RECV_BUFSIZE); - } - - @Override - protected FileDescriptor createFd() { - FileDescriptor fd = null; - - try { - fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily); - if (mSockRcvbufSize != DEFAULT_SOCKET_RECV_BUFSIZE) { - try { - Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, mSockRcvbufSize); - } catch (ErrnoException e) { - Log.wtf(mTag, "Failed to set SO_RCVBUF to " + mSockRcvbufSize, e); - } - } - Os.bind(fd, makeNetlinkSocketAddress(0, mBindGroups)); - NetlinkSocket.connectToKernel(fd); - - if (DBG) { - final SocketAddress nlAddr = Os.getsockname(fd); - Log.d(mTag, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); - } - } catch (ErrnoException | SocketException e) { - logError("Failed to create rtnetlink socket", e); - closeSocketQuietly(fd); - return null; - } - - return fd; - } - - @Override - protected void handlePacket(byte[] recvbuf, int length) { - final long whenMs = SystemClock.elapsedRealtime(); - final ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf, 0, length); - byteBuffer.order(ByteOrder.nativeOrder()); - - while (byteBuffer.remaining() > 0) { - try { - final int position = byteBuffer.position(); - final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer, mFamily); - if (nlMsg == null || nlMsg.getHeader() == null) { - byteBuffer.position(position); - mLog.e("unparsable netlink msg: " + hexify(byteBuffer)); - break; - } - - if (nlMsg instanceof NetlinkErrorMessage) { - mLog.e("netlink error: " + nlMsg); - continue; - } - - processNetlinkMessage(nlMsg, whenMs); - } catch (Exception e) { - mLog.e("Error handling netlink message", e); - } - } - } - - @Override - protected void logError(String msg, Exception e) { - mLog.e(msg, e); - } - - // Ignoring ENOBUFS may miss any important netlink messages, there are some messages which - // cannot be recovered by dumping current state once missed since kernel doesn't keep state - // for it. In addition, dumping current state will not result in any RTM_DELxxx messages, so - // reconstructing current state from a dump will be difficult. However, for those netlink - // messages don't cause any state changes, e.g. RTM_NEWLINK with current link state, maybe - // it's okay to ignore them, because these netlink messages won't cause any changes on the - // LinkProperties. Given the above trade-offs, try to ignore ENOBUFS and that's similar to - // what netd does today. - // - // TODO: log metrics when ENOBUFS occurs, or even force a disconnect, it will help see how - // often this error occurs on fields with the associated socket receive buffer size. - @Override - protected boolean handleReadError(ErrnoException e) { - logError("readPacket error: ", e); - if (e.errno == ENOBUFS) { - Log.wtf(mTag, "Errno: ENOBUFS"); - return false; - } - return true; - } - - // TODO: move NetworkStackUtils to frameworks/libs/net for NetworkStackUtils#closeSocketQuietly. - private void closeSocketQuietly(FileDescriptor fd) { - try { - SocketUtils.closeSocket(fd); - } catch (IOException ignored) { - } - } - - /** - * Processes one netlink message. Must be overridden by subclasses. - * @param nlMsg the message to process. - * @param whenMs the timestamp, as measured by {@link SystemClock#elapsedRealtime}, when the - * message was received. - */ - protected void processNetlinkMessage(NetlinkMessage nlMsg, long whenMs) { } -}
diff --git a/common/moduleutils/src/android/net/shared/LinkPropertiesParcelableUtil.java b/common/moduleutils/src/android/net/shared/LinkPropertiesParcelableUtil.java deleted file mode 100644 index 1729da6..0000000 --- a/common/moduleutils/src/android/net/shared/LinkPropertiesParcelableUtil.java +++ /dev/null
@@ -1,47 +0,0 @@ -/* - * 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.shared; - -import android.annotation.Nullable; -import android.net.LinkProperties; -import android.net.ProxyInfo; - -/** - * Collection of utility methods to convert to and from stable AIDL parcelables for LinkProperties - * and its attributes. - * @hide - */ -public final class LinkPropertiesParcelableUtil { - // Temporary methods to facilitate migrating clients away from LinkPropertiesParcelable - // TODO: remove the following methods after migrating clients. - - /** - * @deprecated conversion to stable parcelable is no longer necessary. - */ - @Deprecated - public static LinkProperties toStableParcelable(@Nullable LinkProperties lp) { - return lp; - } - - /** - * @deprecated conversion to stable parcelable is no longer necessary. - */ - @Deprecated - public static ProxyInfo toStableParcelable(@Nullable ProxyInfo info) { - return info; - } -}
diff --git a/common/moduleutils/src/android/net/shared/NetdUtils.java b/common/moduleutils/src/android/net/shared/NetdUtils.java deleted file mode 100644 index f801e16..0000000 --- a/common/moduleutils/src/android/net/shared/NetdUtils.java +++ /dev/null
@@ -1,79 +0,0 @@ -/* - * 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.shared; - -import static android.system.OsConstants.EBUSY; - -import android.net.INetd; -import android.net.TetherConfigParcel; -import android.os.RemoteException; -import android.os.ServiceSpecificException; -import android.os.SystemClock; -import android.util.Log; - -/** - * Implements common operations on INetd - * @hide - */ -public class NetdUtils { - private static final String TAG = NetdUtils.class.getSimpleName(); - - /** Start tethering. */ - public static void tetherStart(final INetd netd, final boolean usingLegacyDnsProxy, - final String[] dhcpRange) throws RemoteException, ServiceSpecificException { - final TetherConfigParcel config = new TetherConfigParcel(); - config.usingLegacyDnsProxy = usingLegacyDnsProxy; - config.dhcpRanges = dhcpRange; - netd.tetherStartWithConfiguration(config); - } - - /** - * Retry Netd#networkAddInterface for EBUSY error code. - * If the same interface (e.g., wlan0) is in client mode and then switches to tethered mode. - * There can be a race where puts the interface into the local network but interface is still - * in use in netd because the ConnectivityService thread hasn't processed the disconnect yet. - * See b/158269544 for detail. - */ - private static void networkAddInterface(final INetd netd, final String iface, - int maxAttempts, int pollingIntervalMs) - throws ServiceSpecificException, RemoteException { - for (int i = 1; i <= maxAttempts; i++) { - try { - netd.networkAddInterface(INetd.LOCAL_NET_ID, iface); - return; - } catch (ServiceSpecificException e) { - if (e.errorCode == EBUSY && i < maxAttempts) { - SystemClock.sleep(pollingIntervalMs); - continue; - } - - Log.e(TAG, "Retry Netd#networkAddInterface failure: " + e); - throw e; - } - } - } - - /** Reset interface for tethering. */ - public static void untetherInterface(final INetd netd, String iface) - throws RemoteException, ServiceSpecificException { - try { - netd.tetherInterfaceRemove(iface); - } finally { - netd.networkRemoveInterface(INetd.LOCAL_NET_ID, iface); - } - } -}
diff --git a/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java b/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java deleted file mode 100644 index 583a356..0000000 --- a/common/moduleutils/src/android/net/shared/NetworkMonitorUtils.java +++ /dev/null
@@ -1,114 +0,0 @@ -/* - * 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.shared; - -import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; -import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; -import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID; -import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; -import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; - -import android.annotation.NonNull; -import android.net.NetworkCapabilities; - -import com.android.modules.utils.build.SdkLevel; -import com.android.networkstack.apishim.common.NetworkAgentConfigShim; - -/** @hide */ -public class NetworkMonitorUtils { - // This class is used by both NetworkMonitor and ConnectivityService, so it cannot use - // NetworkStack shims, but at the same time cannot use non-system APIs. - // TRANSPORT_TEST is test API as of R (so it is enforced to always be 7 and can't be changed), - // and it is being added as a system API in S. - // TODO: use NetworkCapabilities.TRANSPORT_TEST once NetworkStack builds against API 31. - private static final int TRANSPORT_TEST = 7; - - // This class is used by both NetworkMonitor and ConnectivityService, so it cannot use - // NetworkStack shims, but at the same time cannot use non-system APIs. - // NET_CAPABILITY_NOT_VCN_MANAGED is system API as of S (so it is enforced to always be 28 and - // can't be changed). - // TODO: use NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED once NetworkStack builds against - // API 31. - public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; - - // Network conditions broadcast constants - public static final String ACTION_NETWORK_CONDITIONS_MEASURED = - "android.net.conn.NETWORK_CONDITIONS_MEASURED"; - public static final String EXTRA_CONNECTIVITY_TYPE = "extra_connectivity_type"; - public static final String EXTRA_NETWORK_TYPE = "extra_network_type"; - public static final String EXTRA_RESPONSE_RECEIVED = "extra_response_received"; - public static final String EXTRA_IS_CAPTIVE_PORTAL = "extra_is_captive_portal"; - public static final String EXTRA_CELL_ID = "extra_cellid"; - public static final String EXTRA_SSID = "extra_ssid"; - public static final String EXTRA_BSSID = "extra_bssid"; - /** real time since boot */ - public static final String EXTRA_REQUEST_TIMESTAMP_MS = "extra_request_timestamp_ms"; - public static final String EXTRA_RESPONSE_TIMESTAMP_MS = "extra_response_timestamp_ms"; - public static final String PERMISSION_ACCESS_NETWORK_CONDITIONS = - "android.permission.ACCESS_NETWORK_CONDITIONS"; - - /** - * Return whether validation is required for private DNS in strict mode. - * @param nc Network capabilities of the network to test. - */ - public static boolean isPrivateDnsValidationRequired(@NonNull final NetworkCapabilities nc) { - final boolean isVcnManaged = SdkLevel.isAtLeastS() - && !nc.hasCapability(NET_CAPABILITY_NOT_VCN_MANAGED); - final boolean isOemPaid = nc.hasCapability(NET_CAPABILITY_OEM_PAID) - && nc.hasCapability(NET_CAPABILITY_TRUSTED); - final boolean isDefaultCapable = nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) - && nc.hasCapability(NET_CAPABILITY_TRUSTED); - - // TODO: Consider requiring validation for DUN networks. - if (nc.hasCapability(NET_CAPABILITY_INTERNET) - && (isVcnManaged || isOemPaid || isDefaultCapable)) { - return true; - } - - // Test networks that also have one of the major transport types are attempting to replicate - // that transport on a test interface (for example, test ethernet networks with - // EthernetManager#setIncludeTestInterfaces). Run validation on them for realistic tests. - // See also comments on EthernetManager#setIncludeTestInterfaces and on TestNetworkManager. - if (nc.hasTransport(TRANSPORT_TEST) && nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) && ( - nc.hasTransport(TRANSPORT_WIFI) - || nc.hasTransport(TRANSPORT_CELLULAR) - || nc.hasTransport(TRANSPORT_BLUETOOTH) - || nc.hasTransport(TRANSPORT_ETHERNET))) { - return true; - } - - return false; - } - - /** - * Return whether validation is required for a network. - * @param config Configuration of the network to test. - * @param nc Network capabilities of the network to test. - */ - public static boolean isValidationRequired(@NonNull final NetworkAgentConfigShim config, - @NonNull final NetworkCapabilities nc) { - // TODO: Consider requiring validation for DUN networks. - if (!nc.hasCapability(NET_CAPABILITY_NOT_VPN)) { - return config.isVpnValidationRequired(); - } - return isPrivateDnsValidationRequired(nc); - } -}
diff --git a/common/moduleutils/src/android/net/util/SharedLog.java b/common/moduleutils/src/android/net/util/SharedLog.java deleted file mode 100644 index c569689..0000000 --- a/common/moduleutils/src/android/net/util/SharedLog.java +++ /dev/null
@@ -1,249 +0,0 @@ -/* - * Copyright (C) 2017 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.util; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.text.TextUtils; -import android.util.Log; - -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.time.LocalDateTime; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Iterator; -import java.util.StringJoiner; - - -/** - * Class to centralize logging functionality for tethering. - * - * All access to class methods other than dump() must be on the same thread. - * - * @hide - */ -public class SharedLog { - private static final int DEFAULT_MAX_RECORDS = 500; - private static final String COMPONENT_DELIMITER = "."; - - private enum Category { - NONE, - ERROR, - MARK, - WARN, - } - - private final LocalLog mLocalLog; - // The tag to use for output to the system log. This is not output to the - // LocalLog because that would be redundant. - private final String mTag; - // The component (or subcomponent) of a system that is sharing this log. - // This can grow in depth if components call forSubComponent() to obtain - // their SharedLog instance. The tag is not included in the component for - // brevity. - private final String mComponent; - - public SharedLog(String tag) { - this(DEFAULT_MAX_RECORDS, tag); - } - - public SharedLog(int maxRecords, String tag) { - this(new LocalLog(maxRecords), tag, tag); - } - - private SharedLog(LocalLog localLog, String tag, String component) { - mLocalLog = localLog; - mTag = tag; - mComponent = component; - } - - public String getTag() { - return mTag; - } - - /** - * Create a SharedLog based on this log with an additional component prefix on each logged line. - */ - public SharedLog forSubComponent(String component) { - if (!isRootLogInstance()) { - component = mComponent + COMPONENT_DELIMITER + component; - } - return new SharedLog(mLocalLog, mTag, component); - } - - /** - * Dump the contents of this log. - * - * <p>This method may be called on any thread. - */ - public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - mLocalLog.dump(writer); - } - - /** - * Reverse dump the contents of this log. - * - * <p>This method may be called on any thread. - */ - public void reverseDump(PrintWriter writer) { - mLocalLog.reverseDump(writer); - } - - ////// - // Methods that both log an entry and emit it to the system log. - ////// - - /** - * Log an error due to an exception. This does not include the exception stacktrace. - * - * <p>The log entry will be also added to the system log. - * @see #e(String, Throwable) - */ - public void e(Exception e) { - Log.e(mTag, record(Category.ERROR, e.toString())); - } - - /** - * Log an error message. - * - * <p>The log entry will be also added to the system log. - */ - public void e(String msg) { - Log.e(mTag, record(Category.ERROR, msg)); - } - - /** - * Log an error due to an exception, with the exception stacktrace if provided. - * - * <p>The error and exception message appear in the shared log, but the stacktrace is only - * logged in general log output (logcat). The log entry will be also added to the system log. - */ - public void e(@NonNull String msg, @Nullable Throwable exception) { - if (exception == null) { - e(msg); - return; - } - Log.e(mTag, record(Category.ERROR, msg + ": " + exception.getMessage()), exception); - } - - /** - * Log an informational message. - * - * <p>The log entry will be also added to the system log. - */ - public void i(String msg) { - Log.i(mTag, record(Category.NONE, msg)); - } - - /** - * Log a warning message. - * - * <p>The log entry will be also added to the system log. - */ - public void w(String msg) { - Log.w(mTag, record(Category.WARN, msg)); - } - - ////// - // Methods that only log an entry (and do NOT emit to the system log). - ////// - - /** - * Log a general message to be only included in the in-memory log. - * - * <p>The log entry will *not* be added to the system log. - */ - public void log(String msg) { - record(Category.NONE, msg); - } - - /** - * Log a general, formatted message to be only included in the in-memory log. - * - * <p>The log entry will *not* be added to the system log. - * @see String#format(String, Object...) - */ - public void logf(String fmt, Object... args) { - log(String.format(fmt, args)); - } - - /** - * Log a message with MARK level. - * - * <p>The log entry will *not* be added to the system log. - */ - public void mark(String msg) { - record(Category.MARK, msg); - } - - private String record(Category category, String msg) { - final String entry = logLine(category, msg); - mLocalLog.append(entry); - return entry; - } - - private String logLine(Category category, String msg) { - final StringJoiner sj = new StringJoiner(" "); - if (!isRootLogInstance()) sj.add("[" + mComponent + "]"); - if (category != Category.NONE) sj.add(category.toString()); - return sj.add(msg).toString(); - } - - // Check whether this SharedLog instance is nominally the top level in - // a potential hierarchy of shared logs (the root of a tree), - // or is a subcomponent within the hierarchy. - private boolean isRootLogInstance() { - return TextUtils.isEmpty(mComponent) || mComponent.equals(mTag); - } - - private static final class LocalLog { - private final Deque<String> mLog; - private final int mMaxLines; - - LocalLog(int maxLines) { - mMaxLines = Math.max(0, maxLines); - mLog = new ArrayDeque<>(mMaxLines); - } - - synchronized void append(String logLine) { - if (mMaxLines <= 0) return; - while (mLog.size() >= mMaxLines) { - mLog.remove(); - } - mLog.add(LocalDateTime.now() + " - " + logLine); - } - - /** - * Dumps the content of local log to print writer with each log entry - * - * @param pw printer writer to write into - */ - synchronized void dump(PrintWriter pw) { - for (final String s : mLog) { - pw.println(s); - } - } - - synchronized void reverseDump(PrintWriter pw) { - final Iterator<String> itr = mLog.descendingIterator(); - while (itr.hasNext()) { - pw.println(itr.next()); - } - } - } -}
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp index c363a2b..038caad 100644 --- a/common/networkstackclient/Android.bp +++ b/common/networkstackclient/Android.bp
@@ -204,7 +204,7 @@ "//packages/apps/Bluetooth", "//packages/modules/Bluetooth/android/app", "//packages/modules/NetworkStack", - "//packages/modules/Wifi/service", + "//packages/modules/Wifi/service:__subpackages__", ], apex_available: [ "//apex_available:platform",
diff --git a/common/networkstackclient/src/android/net/shared/ProvisioningConfiguration.java b/common/networkstackclient/src/android/net/shared/ProvisioningConfiguration.java index 3bf6744..3a2a1bd 100644 --- a/common/networkstackclient/src/android/net/shared/ProvisioningConfiguration.java +++ b/common/networkstackclient/src/android/net/shared/ProvisioningConfiguration.java
@@ -333,7 +333,7 @@ @Override public int hashCode() { - return Objects.hash(mId, mPayload); + return Objects.hash(mId, Arrays.hashCode(mPayload)); } @Override
diff --git a/jarjar-excludes.txt b/jarjar-excludes.txt new file mode 100644 index 0000000..42a9219 --- /dev/null +++ b/jarjar-excludes.txt
@@ -0,0 +1,4 @@ +# Services referenced in the manifest. They could be moved to a different package as there are no +# hardcoded reference to them in AOSP, but it is possible that OEM customizations are relying on +# the naming. +com\.android\.server\.NetworkStackService(\$.+)?
diff --git a/jarjar-rules-shared.txt b/jarjar-rules-shared.txt deleted file mode 100644 index e8c9c19..0000000 --- a/jarjar-rules-shared.txt +++ /dev/null
@@ -1,16 +0,0 @@ -rule com.android.internal.util.** android.net.networkstack.util.@1 -rule com.google.protobuf.** com.android.networkstack.protobuf.@1 - -# Classes from net-utils-framework-common -rule com.android.net.module.util.** com.android.networkstack.util.@1 - -# Ignore DhcpResultsParcelable, but jarjar DhcpResults -# TODO: move DhcpResults into services.net and delete from here -rule android.net.DhcpResultsParcelable* @0 -rule android.net.DhcpResults* android.net.networkstack.DhcpResults@1 -rule android.util.LocalLog* android.net.networkstack.util.LocalLog@1 - -rule android.util.IndentingPrintWriter* android.net.networkstack.util.AndroidUtilIndentingPrintWriter@1 - -# Classes from modules-utils-build_system -rule com.android.modules.utils.build.** com.android.networkstack.utils.build.@1 \ No newline at end of file
diff --git a/jni/network_stack_utils_jni.cpp b/jni/network_stack_utils_jni.cpp index 6408856..d7f6d78 100644 --- a/jni/network_stack_utils_jni.cpp +++ b/jni/network_stack_utils_jni.cpp
@@ -38,7 +38,8 @@ #include <android/log.h> namespace android { -constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = "android/net/util/NetworkStackUtils"; +constexpr const char NETWORKSTACKUTILS_PKG_NAME[] = + "com/android/networkstack/util/NetworkStackUtils"; static const uint32_t kEtherTypeOffset = offsetof(ether_header, ether_type); static const uint32_t kEtherHeaderLen = sizeof(ether_header); @@ -126,8 +127,7 @@ int fd = netjniutils::GetNativeFileDescriptor(env, javaFd); if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) != 0) { - jniThrowExceptionFmt(env, "java/net/SocketException", - "setsockopt(SO_ATTACH_FILTER): %s", strerror(errno)); + jniThrowErrnoException(env, "setsockopt(SO_ATTACH_FILTER)", errno); } }
diff --git a/proguard.flags b/proguard.flags index 7f8f207..511a6b3 100644 --- a/proguard.flags +++ b/proguard.flags
@@ -1,14 +1,14 @@ --keepclassmembers class android.net.ip.IpClient { +-keepclassmembers class com.android.networkstack.android.net.ip.IpClient { static final int CMD_*; static final int EVENT_*; } --keepclassmembers class android.net.dhcp.DhcpClient { +-keepclassmembers class com.android.networkstack.android.net.dhcp.DhcpClient { static final int CMD_*; static final int EVENT_*; } --keepclassmembers public class * extends com.android.networkstack.util.Struct { +-keepclassmembers public class * extends com.android.networkstack.com.android.net.module.util.Struct { *; } @@ -17,4 +17,4 @@ # This replicates the base proguard rule used by the build by default # (proguard_basic_keeps.flags), but needs to be specified here because the # com.google.protobuf package is jarjared to the below package. --keepclassmembers class * extends com.android.networkstack.protobuf.MessageLite { <fields>; } +-keepclassmembers class * extends com.android.networkstack.com.google.protobuf.MessageLite { <fields>; }
diff --git a/src/android/net/DhcpResults.java b/src/android/net/DhcpResults.java index ed75282..7c271c3 100644 --- a/src/android/net/DhcpResults.java +++ b/src/android/net/DhcpResults.java
@@ -18,8 +18,6 @@ import android.annotation.Nullable; import android.annotation.SuppressLint; -import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -42,30 +40,22 @@ public final class DhcpResults implements Parcelable { private static final String TAG = "DhcpResults"; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public LinkAddress ipAddress; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public InetAddress gateway; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public final ArrayList<InetAddress> dnsServers = new ArrayList<>(); - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String domains; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Inet4Address serverAddress; /** Vendor specific information (from RFC 2132). */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String vendorInfo; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int leaseDuration; /** Link MTU option. 0 means unset. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int mtu; public String serverHostName;
diff --git a/src/android/net/NetworkStackIpMemoryStore.java b/src/android/net/NetworkStackIpMemoryStore.java index 850faaf..5426db0 100644 --- a/src/android/net/NetworkStackIpMemoryStore.java +++ b/src/android/net/NetworkStackIpMemoryStore.java
@@ -20,13 +20,15 @@ import androidx.annotation.NonNull; +import com.android.networkstack.ipmemorystore.IpMemoryStoreService; + import java.util.concurrent.ExecutionException; import java.util.function.Consumer; /** * service used to communicate with the ip memory store service in network stack, * which is running in the same module. - * @see com.android.server.connectivity.ipmemorystore.IpMemoryStoreService + * @see IpMemoryStoreService * @hide */ public class NetworkStackIpMemoryStore extends IpMemoryStoreClient {
diff --git a/src/android/net/apf/ApfFilter.java b/src/android/net/apf/ApfFilter.java index 4d98568..905aa9a 100644 --- a/src/android/net/apf/ApfFilter.java +++ b/src/android/net/apf/ApfFilter.java
@@ -49,7 +49,6 @@ import android.net.metrics.ApfStats; import android.net.metrics.IpConnectivityLog; import android.net.metrics.RaEvent; -import android.net.util.NetworkStackUtils; import android.os.PowerManager; import android.os.SystemClock; import android.system.ErrnoException; @@ -67,6 +66,7 @@ import com.android.net.module.util.CollectionUtils; import com.android.net.module.util.ConnectivityUtils; import com.android.net.module.util.InterfaceParams; +import com.android.networkstack.util.NetworkStackUtils; import java.io.FileDescriptor; import java.io.IOException; @@ -191,7 +191,7 @@ // Thread to listen for RAs. @VisibleForTesting - class ReceiveThread extends Thread { + public class ReceiveThread extends Thread { private final byte[] mPacket = new byte[1514]; private final FileDescriptor mSocket; private final long mStart = SystemClock.elapsedRealtime(); @@ -348,9 +348,9 @@ private final IpConnectivityLog mMetricsLog; @VisibleForTesting - byte[] mHardwareAddress; + public byte[] mHardwareAddress; @VisibleForTesting - ReceiveThread mReceiveThread; + public ReceiveThread mReceiveThread; @GuardedBy("this") private long mUniqueCounter; @GuardedBy("this") @@ -386,7 +386,7 @@ private int mIPv4PrefixLength; @VisibleForTesting - ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams, + public ApfFilter(Context context, ApfConfiguration config, InterfaceParams ifParams, IpClientCallbacksWrapper ipClientCallback, IpConnectivityLog log) { mApfCapabilities = config.apfCapabilities; mIpClientCallback = ipClientCallback; @@ -466,7 +466,7 @@ * filters to ignore useless RAs. */ @VisibleForTesting - void maybeStartFilter() { + public void maybeStartFilter() { FileDescriptor socket; try { mHardwareAddress = mInterfaceParams.macAddr.toByteArray(); @@ -546,7 +546,7 @@ // A class to hold information about an RA. @VisibleForTesting - class Ra { + public class Ra { // From RFC4861: private static final int ICMP6_RA_HEADER_LEN = 16; private static final int ICMP6_RA_CHECKSUM_OFFSET = @@ -771,7 +771,8 @@ // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with // specifications. - Ra(byte[] packet, int length) throws InvalidRaException { + @VisibleForTesting + public Ra(byte[] packet, int length) throws InvalidRaException { if (length < ICMP6_RA_OPTION_OFFSET) { throw new InvalidRaException("Not an ICMP6 router advertisement: too short"); } @@ -1619,7 +1620,7 @@ */ @GuardedBy("this") @VisibleForTesting - void installNewProgramLocked() { + public void installNewProgramLocked() { purgeExpiredRasLocked(); ArrayList<Ra> rasToFilter = new ArrayList<>(); final byte[] program; @@ -1730,7 +1731,7 @@ * @return a ProcessRaResult enum describing what action was performed. */ @VisibleForTesting - synchronized ProcessRaResult processRa(byte[] packet, int length) { + public synchronized ProcessRaResult processRa(byte[] packet, int length) { if (VDBG) hexDump("Read packet = ", packet, length); // Have we seen this RA before?
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java index bf4d910..db51186 100644 --- a/src/android/net/apf/ApfGenerator.java +++ b/src/android/net/apf/ApfGenerator.java
@@ -16,6 +16,8 @@ package android.net.apf; +import com.android.internal.annotations.VisibleForTesting; + import java.util.ArrayList; import java.util.HashMap; @@ -372,7 +374,8 @@ * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if * the requested version is unsupported. */ - ApfGenerator(int version) throws IllegalInstructionException { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public ApfGenerator(int version) throws IllegalInstructionException { mVersion = version; requireApfVersion(MIN_APF_VERSION); }
diff --git a/src/android/net/dhcp/DhcpClient.java b/src/android/net/dhcp/DhcpClient.java index c88b653..a540cef 100644 --- a/src/android/net/dhcp/DhcpClient.java +++ b/src/android/net/dhcp/DhcpClient.java
@@ -31,11 +31,6 @@ import static android.net.dhcp.DhcpPacket.INADDR_ANY; import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST; import static android.net.dhcp.DhcpPacket.INFINITE_LEASE; -import static android.net.util.NetworkStackUtils.DHCP_INIT_REBOOT_VERSION; -import static android.net.util.NetworkStackUtils.DHCP_IPV6_ONLY_PREFERRED_VERSION; -import static android.net.util.NetworkStackUtils.DHCP_IP_CONFLICT_DETECT_VERSION; -import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION; -import static android.net.util.NetworkStackUtils.closeSocketQuietly; import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; import static android.system.OsConstants.AF_INET; @@ -56,6 +51,12 @@ import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY; import static com.android.net.module.util.NetworkStackConstants.IPV4_CONFLICT_ANNOUNCE_NUM; import static com.android.net.module.util.NetworkStackConstants.IPV4_CONFLICT_PROBE_NUM; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_INIT_REBOOT_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_IPV6_ONLY_PREFERRED_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_IP_CONFLICT_DETECT_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_SLOW_RETRANSMISSION_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.closeSocketQuietly; import android.content.Context; import android.net.DhcpResults; @@ -73,7 +74,6 @@ import android.net.metrics.IpConnectivityLog; import android.net.networkstack.aidl.dhcp.DhcpOption; import android.net.util.HostnameTransliterator; -import android.net.util.NetworkStackUtils; import android.net.util.SocketUtils; import android.os.Build; import android.os.Handler; @@ -107,6 +107,7 @@ import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.arp.ArpPacket; import com.android.networkstack.metrics.IpProvisioningMetrics; +import com.android.networkstack.util.NetworkStackUtils; import java.io.ByteArrayOutputStream; import java.io.FileDescriptor; @@ -349,6 +350,7 @@ private long mTransactionStartMillis; private DhcpResults mDhcpLease; private long mDhcpLeaseExpiry; + private long mT2; private DhcpResults mOffer; private Configuration mConfiguration; private Inet4Address mLastAssignedIpv4Address; @@ -580,6 +582,15 @@ true /* defaultEnabled */); } + /** + * Check whether to adopt slow DHCPREQUEST retransmission approach in Renewing/Rebinding state + * suggested in RFC2131 section 4.4.5. + */ + public boolean isSlowRetransmissionEnabled() { + return mDependencies.isFeatureEnabled(mContext, DHCP_SLOW_RETRANSMISSION_VERSION, + false /* defaultEnabled */); + } + private void recordMetricEnabledFeatures() { if (isDhcpLeaseCacheEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_INITREBOOT); if (isDhcpRapidCommitEnabled()) mMetrics.setDhcpEnabledFeature(DhcpFeature.DF_RAPIDCOMMIT); @@ -688,6 +699,10 @@ Os.bind(mPacketSock, addr); } catch (SocketException | ErrnoException e) { logError("Error creating packet socket", e); + if (e instanceof ErrnoException + && ((ErrnoException) e).errno == 524 /* ENOTSUPP */) { + Log.wtf(TAG, "Errno: ENOTSUPP"); + } closeFd(mPacketSock); mPacketSock = null; return null; @@ -806,6 +821,7 @@ final long remainingDelay = mDhcpLeaseExpiry - now; final long renewDelay = remainingDelay / 2; final long rebindDelay = remainingDelay * 7 / 8; + mT2 = now + rebindDelay; mRenewAlarm.schedule(now + renewDelay); mRebindAlarm.schedule(now + rebindDelay); mExpiryAlarm.schedule(now + remainingDelay); @@ -880,6 +896,7 @@ private void clearDhcpState() { mDhcpLease = null; mDhcpLeaseExpiry = 0; + mT2 = 0; mOffer = null; } @@ -1199,7 +1216,7 @@ return baseTimer + jitter; } - protected void scheduleKick() { + protected void scheduleFastKick() { long now = SystemClock.elapsedRealtime(); long timeout = jitterTimer(mTimer); long alarmTime = now + timeout; @@ -1209,6 +1226,12 @@ mTimer = MAX_TIMEOUT_MS; } } + + protected void scheduleKick() { + // Always adopt the fast kick schedule by default unless this method is overrided + // by subclasses. + scheduleFastKick(); + } } class ObtainingConfigurationState extends LoggingState { @@ -1823,6 +1846,21 @@ // in renew/rebind state or just restart reconfiguration from StoppedState. protected abstract boolean shouldRestartOnNak(); + // Schedule alarm for the next DHCPREQUEST tranmission. Per RFC2131 if the client + // receives no response to its DHCPREQUEST message, the client should wait one-half + // of the remaining time until T2 in RENEWING state, and one-half of the remaining + // lease time in REBINDING state, down to a minimum of 60 seconds before transmitting + // DHCPREQUEST. + private static final long MIN_DELAY_BEFORE_NEXT_REQUEST = 60_000L; + protected void scheduleSlowKick(final long target) { + final long now = SystemClock.elapsedRealtime(); + long remainingDelay = (target - now) / 2; + if (remainingDelay < MIN_DELAY_BEFORE_NEXT_REQUEST) { + remainingDelay = MIN_DELAY_BEFORE_NEXT_REQUEST; + } + mKickAlarm.schedule(now + remainingDelay); + } + protected boolean sendPacket() { return sendRequestPacket( (Inet4Address) mDhcpLease.ipAddress.getAddress(), // ciaddr @@ -1895,13 +1933,18 @@ protected boolean shouldRestartOnNak() { return false; } + + @Override + protected void scheduleKick() { + if (isSlowRetransmissionEnabled()) { + scheduleSlowKick(mT2); + } else { + scheduleFastKick(); + } + } } - class DhcpRebindingState extends DhcpReacquiringState { - public DhcpRebindingState() { - mLeaseMsg = "Rebound"; - } - + class DhcpRebindingBaseState extends DhcpReacquiringState { @Override public void enter() { super.enter(); @@ -1926,7 +1969,29 @@ } } - class DhcpRefreshingAddressState extends DhcpRebindingState { + class DhcpRebindingState extends DhcpRebindingBaseState { + DhcpRebindingState() { + mLeaseMsg = "Rebound"; + } + + @Override + protected void scheduleKick() { + if (isSlowRetransmissionEnabled()) { + scheduleSlowKick(mDhcpLeaseExpiry); + } else { + scheduleFastKick(); + } + } + } + + // The slow retransmission approach complied with RFC2131 should only be applied + // for Renewing and Rebinding state. For this state it's expected to refresh IPv4 + // link address after roam as soon as possible, obviously it should not adopt the + // slow retransmission algorithm. Create a base DhcpRebindingBaseState state and + // have both of DhcpRebindingState and DhcpRefreshingAddressState extend from it, + // then override the scheduleKick method in DhcpRebindingState to comply with slow + // schedule and keep DhcpRefreshingAddressState as-is to use the fast schedule. + class DhcpRefreshingAddressState extends DhcpRebindingBaseState { DhcpRefreshingAddressState() { mLeaseMsg = "Refreshing address"; }
diff --git a/src/android/net/dhcp/DhcpLease.java b/src/android/net/dhcp/DhcpLease.java index 0b9cd7c..d440c42 100644 --- a/src/android/net/dhcp/DhcpLease.java +++ b/src/android/net/dhcp/DhcpLease.java
@@ -142,7 +142,8 @@ @Override public int hashCode() { - return Objects.hash(mClientId, mHwAddr, mNetAddr, mPrefixLength, mHostname, mExpTime); + return Objects.hash(Arrays.hashCode(mClientId), mHwAddr, mNetAddr, mPrefixLength, + mHostname, mExpTime); } static String clientIdToString(byte[] bytes) {
diff --git a/src/android/net/dhcp/DhcpLeaseRepository.java b/src/android/net/dhcp/DhcpLeaseRepository.java index b404296..34c086b 100644 --- a/src/android/net/dhcp/DhcpLeaseRepository.java +++ b/src/android/net/dhcp/DhcpLeaseRepository.java
@@ -30,7 +30,6 @@ import android.net.IpPrefix; import android.net.MacAddress; import android.net.dhcp.DhcpServer.Clock; -import android.net.util.SharedLog; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.ArrayMap; @@ -39,6 +38,8 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import com.android.net.module.util.SharedLog; + import java.net.Inet4Address; import java.util.ArrayList; import java.util.Collections;
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java index 7dc1b99..65145e8 100644 --- a/src/android/net/dhcp/DhcpPacket.java +++ b/src/android/net/dhcp/DhcpPacket.java
@@ -16,6 +16,7 @@ package android.net.dhcp; +import static com.android.modules.utils.build.SdkLevel.isAtLeastR; import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ALL; import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY; @@ -33,7 +34,6 @@ import androidx.annotation.VisibleForTesting; import com.android.net.module.util.Inet4AddressUtils; -import com.android.networkstack.apishim.common.ShimUtils; import java.io.UnsupportedEncodingException; import java.net.Inet4Address; @@ -799,8 +799,7 @@ */ @VisibleForTesting public String getHostname() { - if (mHostName == null - && !ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)) { + if (mHostName == null && !isAtLeastR()) { return SystemProperties.get("net.hostname"); } return mHostName;
diff --git a/src/android/net/dhcp/DhcpServer.java b/src/android/net/dhcp/DhcpServer.java index dbd85a4..3325e74 100644 --- a/src/android/net/dhcp/DhcpServer.java +++ b/src/android/net/dhcp/DhcpServer.java
@@ -23,7 +23,6 @@ import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR; -import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.IPPROTO_UDP; @@ -39,6 +38,7 @@ import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ALL; import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY; import static com.android.net.module.util.NetworkStackConstants.TAG_SYSTEM_DHCP_SERVER; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION; import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingPermission; import static java.lang.Integer.toUnsignedLong; @@ -48,8 +48,6 @@ import android.net.IpPrefix; import android.net.MacAddress; import android.net.TrafficStats; -import android.net.util.NetworkStackUtils; -import android.net.util.SharedLog; import android.net.util.SocketUtils; import android.os.Handler; import android.os.Message; @@ -68,6 +66,8 @@ import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.net.module.util.DeviceConfigUtils; +import com.android.net.module.util.SharedLog; +import com.android.networkstack.util.NetworkStackUtils; import java.io.FileDescriptor; import java.io.IOException;
diff --git a/src/android/net/ip/ConnectivityPacketTracker.java b/src/android/net/ip/ConnectivityPacketTracker.java index a905315..4b92179 100644 --- a/src/android/net/ip/ConnectivityPacketTracker.java +++ b/src/android/net/ip/ConnectivityPacketTracker.java
@@ -24,7 +24,6 @@ import static android.system.OsConstants.SOCK_RAW; import android.net.util.ConnectivityPacketSummary; -import android.net.util.NetworkStackUtils; import android.os.Handler; import android.os.SystemClock; import android.system.ErrnoException; @@ -37,6 +36,7 @@ import com.android.internal.util.TokenBucket; import com.android.net.module.util.InterfaceParams; import com.android.net.module.util.PacketReader; +import com.android.networkstack.util.NetworkStackUtils; import java.io.FileDescriptor; import java.io.IOException;
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java index 4ada67f..97c6990 100644 --- a/src/android/net/ip/IpClient.java +++ b/src/android/net/ip/IpClient.java
@@ -23,9 +23,6 @@ import static android.net.ip.IIpClient.PROV_IPV6_LINKLOCAL; import static android.net.ip.IpReachabilityMonitor.INVALID_REACHABILITY_LOSS_TYPE; import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt; -import static android.net.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION; -import static android.net.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION; -import static android.net.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION; import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; import static android.system.OsConstants.AF_PACKET; @@ -38,6 +35,9 @@ import static com.android.net.module.util.NetworkStackConstants.ETHER_BROADCAST; import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST; import static com.android.net.module.util.NetworkStackConstants.VENDOR_SPECIFIC_IE_ID; +import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_DISABLE_ACCEPT_RA_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GARP_NA_ROAMING_VERSION; +import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_GRATUITOUS_NA_VERSION; import static com.android.server.util.PermissionUtil.enforceNetworkStackCallingPermission; import android.annotation.SuppressLint; @@ -73,8 +73,6 @@ import android.net.shared.ProvisioningConfiguration; import android.net.shared.ProvisioningConfiguration.ScanResultInfo; import android.net.shared.ProvisioningConfiguration.ScanResultInfo.InformationElement; -import android.net.util.NetworkStackUtils; -import android.net.util.SharedLog; import android.os.Build; import android.os.ConditionVariable; import android.os.Handler; @@ -107,6 +105,8 @@ import com.android.internal.util.WakeupMessage; import com.android.net.module.util.DeviceConfigUtils; import com.android.net.module.util.InterfaceParams; +import com.android.net.module.util.SharedLog; +import com.android.net.module.util.ip.InterfaceController; import com.android.networkstack.R; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.networkstack.apishim.SocketUtilsShimImpl; @@ -116,6 +116,7 @@ import com.android.networkstack.metrics.IpProvisioningMetrics; import com.android.networkstack.metrics.NetworkQuirkMetrics; import com.android.networkstack.packets.NeighborAdvertisement; +import com.android.networkstack.util.NetworkStackUtils; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService.NetworkStackServiceManager; @@ -506,20 +507,19 @@ // Specific vendor OUI(3 bytes)/vendor specific type(1 byte) pattern for upstream hotspot // device detection. Add new byte array pattern below in turn. - private static final List<byte[]> METERED_IE_PATTERN_LIST = Collections.unmodifiableList( - Arrays.asList( - new byte[] { (byte) 0x00, (byte) 0x17, (byte) 0xf2, (byte) 0x06 } - )); + private static final List<byte[]> METERED_IE_PATTERN_LIST = Collections.singletonList( + new byte[] { (byte) 0x00, (byte) 0x17, (byte) 0xf2, (byte) 0x06 } + ); // Allows Wi-Fi to pass in DHCP options when particular vendor-specific IEs are present. // Maps each DHCP option code to a list of IEs, any of which will allow that option. private static final Map<Byte, List<byte[]>> DHCP_OPTIONS_ALLOWED = Map.of( - (byte) 60, Arrays.asList( + (byte) 60, Collections.singletonList( // KT OUI: 00:17:C3, type: 17. See b/170928882. - new byte[]{ (byte) 0x00, (byte) 0x17, (byte) 0xc3, (byte) 0x17 }), - (byte) 77, Arrays.asList( + new byte[]{ (byte) 0x00, (byte) 0x17, (byte) 0xc3, (byte) 0x11 }), + (byte) 77, Collections.singletonList( // KT OUI: 00:17:C3, type: 17. See b/170928882. - new byte[]{ (byte) 0x00, (byte) 0x17, (byte) 0xc3, (byte) 0x17 }) + new byte[]{ (byte) 0x00, (byte) 0x17, (byte) 0xc3, (byte) 0x11 }) ); // Initialize configurable particular SSID set supporting DHCP Roaming feature. See @@ -696,7 +696,7 @@ } @VisibleForTesting - IpClient(Context context, String ifName, IIpClientCallbacks callback, + public IpClient(Context context, String ifName, IIpClientCallbacks callback, NetworkObserverRegistry observerRegistry, NetworkStackServiceManager nssManager, Dependencies deps) { super(IpClient.class.getSimpleName() + "." + ifName); @@ -2558,6 +2558,15 @@ case DhcpClient.CMD_CONFIGURE_LINKADDRESS: { final LinkAddress ipAddress = (LinkAddress) msg.obj; if (mInterfaceCtrl.setIPv4Address(ipAddress)) { + // Although it's impossible to happen that DHCP client becomes null in + // RunningState and then NPE is thrown when it attempts to send a message + // on an null object, sometimes it's found during stress tests. If this + // issue does happen, log the terrible failure, that would be helpful to + // see how often this case occurs on fields and the log trace would be + // also useful for debugging(see b/203174383). + if (mDhcpClient == null) { + Log.wtf(mTag, "DhcpClient should never be null in RunningState."); + } mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED); } else { logError("Failed to set IPv4 address.");
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java index bebe7c9..08226ef 100644 --- a/src/android/net/ip/IpClientLinkObserver.java +++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -16,7 +16,6 @@ package android.net.ip; -import static android.net.util.NetworkStackUtils.IPCLIENT_PARSE_NETLINK_EVENTS_VERSION; import static android.system.OsConstants.AF_INET6; import static android.system.OsConstants.AF_UNSPEC; import static android.system.OsConstants.IFF_LOOPBACK; @@ -29,6 +28,7 @@ import static com.android.net.module.util.netlink.NetlinkConstants.RTPROT_KERNEL; import static com.android.net.module.util.netlink.NetlinkConstants.RTPROT_RA; import static com.android.net.module.util.netlink.NetlinkConstants.RT_SCOPE_UNIVERSE; +import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_PARSE_NETLINK_EVENTS_VERSION; import android.app.AlarmManager; import android.content.Context; @@ -37,7 +37,6 @@ import android.net.LinkAddress; import android.net.LinkProperties; import android.net.RouteInfo; -import android.net.util.SharedLog; import android.os.Handler; import android.system.OsConstants; import android.util.Log; @@ -47,6 +46,8 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.InterfaceParams; +import com.android.net.module.util.SharedLog; +import com.android.net.module.util.ip.NetlinkMonitor; import com.android.net.module.util.netlink.NduseroptMessage; import com.android.net.module.util.netlink.NetlinkConstants; import com.android.net.module.util.netlink.NetlinkMessage;
diff --git a/src/android/net/ip/IpReachabilityMonitor.java b/src/android/net/ip/IpReachabilityMonitor.java index 7614cf3..00f6dfa 100644 --- a/src/android/net/ip/IpReachabilityMonitor.java +++ b/src/android/net/ip/IpReachabilityMonitor.java
@@ -20,20 +20,18 @@ import static android.net.metrics.IpReachabilityEvent.NUD_FAILED_ORGANIC; import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST; import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC; -import static android.net.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; +import static com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION; + import android.content.Context; import android.net.ConnectivityManager; import android.net.INetd; import android.net.LinkProperties; import android.net.RouteInfo; -import android.net.ip.IpNeighborMonitor.NeighborEvent; -import android.net.ip.IpNeighborMonitor.NeighborEventConsumer; import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpReachabilityEvent; import android.net.networkstack.aidl.ip.ReachabilityLossReason; -import android.net.util.SharedLog; import android.os.ConditionVariable; import android.os.Handler; import android.os.Looper; @@ -54,6 +52,10 @@ import com.android.internal.util.Preconditions; import com.android.net.module.util.DeviceConfigUtils; import com.android.net.module.util.InterfaceParams; +import com.android.net.module.util.SharedLog; +import com.android.net.module.util.ip.IpNeighborMonitor; +import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEvent; +import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEventConsumer; import com.android.net.module.util.netlink.StructNdMsg; import com.android.networkstack.R; import com.android.networkstack.metrics.IpReachabilityMonitorMetrics; @@ -174,7 +176,8 @@ * Encapsulates IpReachabilityMonitor dependencies on systems that hinder unit testing. * TODO: consider also wrapping MultinetworkPolicyTracker in this interface. */ - interface Dependencies { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public interface Dependencies { void acquireWakeLock(long durationMs); IpNeighborMonitor makeIpNeighborMonitor(Handler h, SharedLog log, NeighborEventConsumer cb); boolean isFeatureEnabled(Context context, String name, boolean defaultEnabled); @@ -238,9 +241,9 @@ } @VisibleForTesting - IpReachabilityMonitor(Context context, InterfaceParams ifParams, Handler h, SharedLog log, - Callback callback, boolean usingMultinetworkPolicyTracker, Dependencies dependencies, - final IpConnectivityLog metricsLog, final INetd netd) { + public IpReachabilityMonitor(Context context, InterfaceParams ifParams, Handler h, + SharedLog log, Callback callback, boolean usingMultinetworkPolicyTracker, + Dependencies dependencies, final IpConnectivityLog metricsLog, final INetd netd) { if (ifParams == null) throw new IllegalArgumentException("null InterfaceParams"); mContext = context;
diff --git a/src/com/android/server/TestNetworkStackService.java b/src/com/android/networkstack/TestNetworkStackService.java similarity index 93% rename from src/com/android/server/TestNetworkStackService.java rename to src/com/android/networkstack/TestNetworkStackService.java index 23981e5..f34300d 100644 --- a/src/com/android/server/TestNetworkStackService.java +++ b/src/com/android/networkstack/TestNetworkStackService.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server; +package com.android.networkstack; import static com.android.server.util.PermissionUtil.isDebuggableBuild; @@ -23,6 +23,8 @@ import androidx.annotation.Nullable; +import com.android.server.NetworkStackService; + /** * A {@link NetworkStackService} that can only be bound to on debuggable builds. */
diff --git a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java b/src/com/android/networkstack/ipmemorystore/IpMemoryStoreDatabase.java similarity index 99% rename from src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java rename to src/com/android/networkstack/ipmemorystore/IpMemoryStoreDatabase.java index f9b6365..8242783 100644 --- a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreDatabase.java +++ b/src/com/android/networkstack/ipmemorystore/IpMemoryStoreDatabase.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; import static com.android.net.module.util.Inet4AddressUtils.intToInet4AddressHTH;
diff --git a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java b/src/com/android/networkstack/ipmemorystore/IpMemoryStoreService.java similarity index 98% rename from src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java rename to src/com/android/networkstack/ipmemorystore/IpMemoryStoreService.java index ae9c875..aa7d698 100644 --- a/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreService.java +++ b/src/com/android/networkstack/ipmemorystore/IpMemoryStoreService.java
@@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; import static android.net.ipmemorystore.Status.ERROR_DATABASE_CANNOT_BE_OPENED; import static android.net.ipmemorystore.Status.ERROR_GENERIC; import static android.net.ipmemorystore.Status.ERROR_ILLEGAL_ARGUMENT; import static android.net.ipmemorystore.Status.SUCCESS; -import static com.android.server.connectivity.ipmemorystore.IpMemoryStoreDatabase.EXPIRY_ERROR; -import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance; +import static com.android.networkstack.ipmemorystore.IpMemoryStoreDatabase.EXPIRY_ERROR; +import static com.android.networkstack.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance; import android.content.Context; import android.database.SQLException;
diff --git a/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java b/src/com/android/networkstack/ipmemorystore/RegularMaintenanceJobService.java similarity index 98% rename from src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java rename to src/com/android/networkstack/ipmemorystore/RegularMaintenanceJobService.java index c8559c8..bc6213c 100644 --- a/src/com/android/server/connectivity/ipmemorystore/RegularMaintenanceJobService.java +++ b/src/com/android/networkstack/ipmemorystore/RegularMaintenanceJobService.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; import android.app.job.JobInfo; import android.app.job.JobParameters;
diff --git a/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java b/src/com/android/networkstack/ipmemorystore/RelevanceUtils.java similarity index 99% rename from src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java rename to src/com/android/networkstack/ipmemorystore/RelevanceUtils.java index 38d5544..6a0c398 100644 --- a/src/com/android/server/connectivity/ipmemorystore/RelevanceUtils.java +++ b/src/com/android/networkstack/ipmemorystore/RelevanceUtils.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; import com.android.internal.annotations.VisibleForTesting;
diff --git a/src/com/android/server/connectivity/ipmemorystore/StatusAndCount.java b/src/com/android/networkstack/ipmemorystore/StatusAndCount.java similarity index 93% rename from src/com/android/server/connectivity/ipmemorystore/StatusAndCount.java rename to src/com/android/networkstack/ipmemorystore/StatusAndCount.java index 2cbe843..a6abdba 100644 --- a/src/com/android/server/connectivity/ipmemorystore/StatusAndCount.java +++ b/src/com/android/networkstack/ipmemorystore/StatusAndCount.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; /** * Small data class to wrap a Status and an int.
diff --git a/src/com/android/server/connectivity/ipmemorystore/Utils.java b/src/com/android/networkstack/ipmemorystore/Utils.java similarity index 96% rename from src/com/android/server/connectivity/ipmemorystore/Utils.java rename to src/com/android/networkstack/ipmemorystore/Utils.java index d8a46ed..c2fb1a4 100644 --- a/src/com/android/server/connectivity/ipmemorystore/Utils.java +++ b/src/com/android/networkstack/ipmemorystore/Utils.java
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; import android.net.ipmemorystore.Blob;
diff --git a/src/com/android/networkstack/metrics/DataStallDetectionStats.java b/src/com/android/networkstack/metrics/DataStallDetectionStats.java index 751d98d..e13d2d4 100644 --- a/src/com/android/networkstack/metrics/DataStallDetectionStats.java +++ b/src/com/android/networkstack/metrics/DataStallDetectionStats.java
@@ -157,8 +157,9 @@ @Override public int hashCode() { - return Objects.hash(mNetworkType, mEvaluationType, mWifiInfo, mCellularInfo, mDns, - mTcpFailRate, mTcpSentSinceLastRecv); + return Objects.hash(mNetworkType, mEvaluationType, Arrays.hashCode(mWifiInfo), + Arrays.hashCode(mCellularInfo), Arrays.hashCode(mDns), mTcpFailRate, + mTcpSentSinceLastRecv); } /**
diff --git a/src/com/android/networkstack/netlink/TcpSocketTracker.java b/src/com/android/networkstack/netlink/TcpSocketTracker.java index 9cc2d60..ec130e6 100644 --- a/src/com/android/networkstack/netlink/TcpSocketTracker.java +++ b/src/com/android/networkstack/netlink/TcpSocketTracker.java
@@ -43,7 +43,6 @@ import android.net.INetd; import android.net.MarkMaskParcel; import android.net.Network; -import android.net.util.NetworkStackUtils; import android.net.util.SocketUtils; import android.os.AsyncTask; import android.os.Build; @@ -70,6 +69,7 @@ import com.android.networkstack.apishim.NetworkShimImpl; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.apishim.common.UnsupportedApiLevelException; +import com.android.networkstack.util.NetworkStackUtils; import java.io.FileDescriptor; import java.io.InterruptedIOException; @@ -433,6 +433,11 @@ if (DBG) Log.d(TAG, str); } + /** Stops monitoring and releases resources. */ + public void quit() { + mDependencies.removeDeviceConfigChangedListener(mConfigListener); + } + /** * Corresponds to {@code struct rtattr} from bionic/libc/kernel/uapi/linux/rtnetlink.h * @@ -615,5 +620,11 @@ DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_CONNECTIVITY, AsyncTask.THREAD_POOL_EXECUTOR, listener); } + + /** Remove device config change listener */ + public void removeDeviceConfigChangedListener( + @NonNull final DeviceConfig.OnPropertiesChangedListener listener) { + DeviceConfig.removeOnPropertiesChangedListener(listener); + } } }
diff --git a/src/android/net/util/NetworkStackUtils.java b/src/com/android/networkstack/util/NetworkStackUtils.java similarity index 87% rename from src/android/net/util/NetworkStackUtils.java rename to src/com/android/networkstack/util/NetworkStackUtils.java index 6dc2a5b..2ec6841 100755 --- a/src/android/net/util/NetworkStackUtils.java +++ b/src/com/android/networkstack/util/NetworkStackUtils.java
@@ -14,10 +14,12 @@ * limitations under the License. */ -package android.net.util; +package com.android.networkstack.util; import android.content.Context; import android.net.MacAddress; +import android.net.util.SocketUtils; +import android.system.ErrnoException; import androidx.annotation.NonNull; @@ -88,37 +90,6 @@ public static final String CAPTIVE_PORTAL_HTTP_URL = "captive_portal_http_url"; /** - * A test URL used to override configuration settings and overlays for the network validation - * HTTPS URL, when set in {@link android.provider.DeviceConfig} configuration. - * - * <p>This URL will be ignored if the host is not "localhost" (it can only be used to test with - * a local test server), and must not be set in production scenarios (as enforced by CTS tests). - * - * <p>{@link #TEST_URL_EXPIRATION_TIME} must also be set to use this setting. - */ - public static final String TEST_CAPTIVE_PORTAL_HTTPS_URL = "test_captive_portal_https_url"; - - /** - * A test URL used to override configuration settings and overlays for the network validation - * HTTP URL, when set in {@link android.provider.DeviceConfig} configuration. - * - * <p>This URL will be ignored if the host is not "localhost" (it can only be used to test with - * a local test server), and must not be set in production scenarios (as enforced by CTS tests). - * - * <p>{@link #TEST_URL_EXPIRATION_TIME} must also be set to use this setting. - */ - public static final String TEST_CAPTIVE_PORTAL_HTTP_URL = "test_captive_portal_http_url"; - - /** - * Expiration time of the test URL, in ms, relative to {@link System#currentTimeMillis()}. - * - * <p>After this expiration time, test URLs will be ignored. They will also be ignored if - * the expiration time is more than 10 minutes in the future, to avoid misconfiguration - * following test runs. - */ - public static final String TEST_URL_EXPIRATION_TIME = "test_url_expiration_time"; - - /** * The URL used for fallback HTTP captive portal detection when previous HTTP * and HTTPS captive portal detection attemps did not return a conclusive answer. */ @@ -211,6 +182,13 @@ "dhcp_ipv6_only_preferred_version"; /** + * Minimum module version at which to enable slow DHCP retransmission approach in renew/rebind + * state suggested in RFC2131 section 4.4.5. + */ + public static final String DHCP_SLOW_RETRANSMISSION_VERSION = + "dhcp_slow_retransmission_version"; + + /** * Minimum module version at which to enable dismissal CaptivePortalLogin app in validated * network feature. CaptivePortalLogin app will also use validation facilities in * {@link NetworkMonitor} to perform portal validation if feature is enabled. @@ -301,7 +279,7 @@ /** * Attaches a socket filter that accepts DHCP packets to the given socket. */ - public static native void attachDhcpFilter(FileDescriptor fd) throws SocketException; + public static native void attachDhcpFilter(FileDescriptor fd) throws ErrnoException; /** * Attaches a socket filter that accepts ICMPv6 router advertisements to the given socket.
diff --git a/src/com/android/server/NetworkStackService.java b/src/com/android/server/NetworkStackService.java index 64cbc24..368a6d4 100644 --- a/src/com/android/server/NetworkStackService.java +++ b/src/com/android/server/NetworkStackService.java
@@ -45,7 +45,6 @@ import android.net.ip.IpClient; import android.net.networkstack.aidl.NetworkMonitorParameters; import android.net.shared.PrivateDnsConfig; -import android.net.util.SharedLog; import android.os.Build; import android.os.HandlerThread; import android.os.IBinder; @@ -60,11 +59,12 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; +import com.android.net.module.util.SharedLog; import com.android.networkstack.NetworkStackNotifier; import com.android.networkstack.R; import com.android.networkstack.apishim.common.ShimUtils; +import com.android.networkstack.ipmemorystore.IpMemoryStoreService; import com.android.server.connectivity.NetworkMonitor; -import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService; import com.android.server.util.PermissionUtil; import java.io.FileDescriptor; @@ -421,8 +421,8 @@ if (cb != null) cb.onStatusAvailable(0); } - @Override - protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, + @Override @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) + public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout, @Nullable String[] args) { checkDumpPermission();
diff --git a/src/com/android/server/connectivity/NetworkMonitor.java b/src/com/android/server/connectivity/NetworkMonitor.java index 19a9f60..d98c5e4 100755 --- a/src/com/android/server/connectivity/NetworkMonitor.java +++ b/src/com/android/server/connectivity/NetworkMonitor.java
@@ -55,38 +55,38 @@ import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS; import static android.net.util.DataStallUtils.DEFAULT_DNS_LOG_SIZE; import static android.net.util.DataStallUtils.DEFAULT_TCP_POLLING_INTERVAL_MS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_URL; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTPS_URL; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTP_URL; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_HTTPS_URLS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_HTTP_URLS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS; -import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT; -import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS; -import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS; -import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_HTTP_URLS; -import static android.net.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK; -import static android.net.util.NetworkStackUtils.DNS_PROBE_PRIVATE_IP_NO_INTERNET_VERSION; -import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL; -import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL; -import static android.net.util.NetworkStackUtils.TEST_URL_EXPIRATION_TIME; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; import static com.android.net.module.util.CollectionUtils.isEmpty; import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA; import static com.android.net.module.util.DeviceConfigUtils.getResBooleanConfig; +import static com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL; +import static com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL; +import static com.android.net.module.util.NetworkStackConstants.TEST_URL_EXPIRATION_TIME; import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_DNS_EVENTS; import static com.android.networkstack.apishim.ConstantsShim.DETECTION_METHOD_TCP_METRICS; import static com.android.networkstack.apishim.ConstantsShim.RECEIVER_NOT_EXPORTED; import static com.android.networkstack.apishim.ConstantsShim.TRANSPORT_TEST; import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX; import static com.android.networkstack.util.DnsUtils.TYPE_ADDRCONFIG; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_URL; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTPS_URL; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_HTTP_URL; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_IGNORE; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_MODE_PROMPT; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_HTTPS_URLS; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_HTTP_URLS; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_USER_AGENT; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS; +import static com.android.networkstack.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT; +import static com.android.networkstack.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS; +import static com.android.networkstack.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_HTTPS_URLS; +import static com.android.networkstack.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_HTTP_URLS; +import static com.android.networkstack.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK; +import static com.android.networkstack.util.NetworkStackUtils.DNS_PROBE_PRIVATE_IP_NO_INTERNET_VERSION; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -114,11 +114,8 @@ import android.net.metrics.NetworkEvent; import android.net.metrics.ValidationProbeEvent; import android.net.networkstack.aidl.NetworkMonitorParameters; -import android.net.shared.NetworkMonitorUtils; import android.net.shared.PrivateDnsConfig; import android.net.util.DataStallUtils.EvaluationType; -import android.net.util.NetworkStackUtils; -import android.net.util.SharedLog; import android.net.util.Stopwatch; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -160,7 +157,9 @@ import com.android.internal.util.StateMachine; import com.android.modules.utils.build.SdkLevel; import com.android.net.module.util.DeviceConfigUtils; +import com.android.net.module.util.NetworkMonitorUtils; import com.android.net.module.util.NetworkStackConstants; +import com.android.net.module.util.SharedLog; import com.android.networkstack.NetworkStackNotifier; import com.android.networkstack.R; import com.android.networkstack.apishim.CaptivePortalDataShimImpl; @@ -177,6 +176,7 @@ import com.android.networkstack.metrics.NetworkValidationMetrics; import com.android.networkstack.netlink.TcpSocketTracker; import com.android.networkstack.util.DnsUtils; +import com.android.networkstack.util.NetworkStackUtils; import com.android.server.NetworkStackService.NetworkStackServiceManager; import org.json.JSONException; @@ -781,7 +781,8 @@ } private boolean isValidationRequired() { - return NetworkMonitorUtils.isValidationRequired(mNetworkAgentConfig, mNetworkCapabilities); + return NetworkMonitorUtils.isValidationRequired( + mNetworkAgentConfig.isVpnValidationRequired(), mNetworkCapabilities); } private boolean isPrivateDnsValidationRequired() { @@ -934,6 +935,9 @@ case CMD_NETWORK_DISCONNECTED: maybeStopCollectionAndSendMetrics(); logNetworkEvent(NetworkEvent.NETWORK_DISCONNECTED); + if (mTcpTracker != null) { + mTcpTracker.quit(); + } quit(); return HANDLED; case CMD_FORCE_REEVALUATION:
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp index 2bf0529..f21cf33 100644 --- a/tests/integration/Android.bp +++ b/tests/integration/Android.bp
@@ -78,6 +78,7 @@ min_sdk_version: "29", target_sdk_version: "30", jarjar_rules: ":NetworkStackJarJarRules", + test_config_template: "AndroidTestTemplate_Integration.xml", } // Network stack next integration tests. @@ -99,6 +100,7 @@ platform_apis: true, test_suites: ["device-tests"], jarjar_rules: ":NetworkStackJarJarRules", + test_config_template: "AndroidTestTemplate_Integration.xml", } // Network stack integration root tests.
diff --git a/tests/integration/AndroidTestTemplate_Integration.xml b/tests/integration/AndroidTestTemplate_Integration.xml new file mode 100644 index 0000000..7ea8ad6 --- /dev/null +++ b/tests/integration/AndroidTestTemplate_Integration.xml
@@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2022 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. +--> +<configuration description="Test config for {MODULE}"> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="{MODULE}.apk" /> + </target_preparer> + + <!-- Needed to push to the app's data directory. Without root, there appears to be no directory + that the shell can write to and that the networkstack can read from. --> + <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="com.android.server.networkstack.integrationtests" /> + <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <!-- By default, include and exclude filters go into /data/local/tmp/ajur/, which these + tests cannot access because they run in the network_stack selinux context. Move + them to the tests' data directory instead. + + This avoids confusing module errors in presubmit when a test fails, the test infra + attempts to retry it, but the retry run results in the test process crashing with a + permission denial trying to read the exclude file. --> + <option name="test-filter-dir" value="/data/data/{PACKAGE}/cache" /> + <option name="hidden-api-checks" value="false"/> + </test> +</configuration>
diff --git a/tests/integration/AndroidTest_Coverage.xml b/tests/integration/AndroidTest_Coverage.xml index 3e7361b..1c63a93 100644 --- a/tests/integration/AndroidTest_Coverage.xml +++ b/tests/integration/AndroidTest_Coverage.xml
@@ -22,6 +22,14 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.server.networkstack.coverage" /> <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> + <!-- By default, include and exclude filters go into /data/local/tmp/ajur/, which these + tests cannot access because they run in the network_stack selinux context. Move + them to the tests' data directory instead. + + This avoids confusing module errors in presubmit when a test fails, the test infra + attempts to retry it, but the retry run results in the test process crashing with a + permission denial trying to read the exclude file. --> + <option name="test-filter-dir" value="/data/data/{PACKAGE}/cache" /> <option name="hidden-api-checks" value="false"/> <option name="device-listeners" value="com.android.modules.utils.testing.NativeCoverageHackInstrumentationListener" /> </test>
diff --git a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java index 959b0b7..1a4dab1 100644 --- a/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java +++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -17,6 +17,12 @@ package android.net.ip; import static android.Manifest.permission.MANAGE_TEST_NETWORKS; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; +import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED; +import static android.net.NetworkCapabilities.TRANSPORT_TEST; import static android.net.dhcp.DhcpClient.EXPIRED_LEASE; import static android.net.dhcp.DhcpPacket.DHCP_BOOTREQUEST; import static android.net.dhcp.DhcpPacket.DHCP_CLIENT; @@ -113,10 +119,14 @@ import android.net.LinkAddress; import android.net.LinkProperties; import android.net.MacAddress; +import android.net.NetworkAgentConfig; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; import android.net.NetworkStackIpMemoryStore; import android.net.RouteInfo; import android.net.TestNetworkInterface; import android.net.TestNetworkManager; +import android.net.TestNetworkSpecifier; import android.net.Uri; import android.net.dhcp.DhcpClient; import android.net.dhcp.DhcpDeclinePacket; @@ -124,7 +134,6 @@ import android.net.dhcp.DhcpPacket; import android.net.dhcp.DhcpPacket.ParseException; import android.net.dhcp.DhcpRequestPacket; -import android.net.ip.IpNeighborMonitor.NeighborEventConsumer; import android.net.ipmemorystore.NetworkAttributes; import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener; import android.net.ipmemorystore.Status; @@ -135,8 +144,6 @@ import android.net.shared.Layer2Information; import android.net.shared.ProvisioningConfiguration; import android.net.shared.ProvisioningConfiguration.ScanResultInfo; -import android.net.util.NetworkStackUtils; -import android.net.util.SharedLog; import android.os.Build; import android.os.Handler; import android.os.HandlerThread; @@ -160,6 +167,9 @@ import com.android.net.module.util.ArrayTrackRecord; import com.android.net.module.util.InterfaceParams; import com.android.net.module.util.Ipv6Utils; +import com.android.net.module.util.SharedLog; +import com.android.net.module.util.ip.IpNeighborMonitor; +import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEventConsumer; import com.android.net.module.util.netlink.StructNdOptPref64; import com.android.net.module.util.structs.LlaOption; import com.android.net.module.util.structs.PrefixInformationOption; @@ -169,20 +179,23 @@ import com.android.networkstack.apishim.ConstantsShim; import com.android.networkstack.apishim.common.ShimUtils; import com.android.networkstack.arp.ArpPacket; +import com.android.networkstack.ipmemorystore.IpMemoryStoreService; import com.android.networkstack.metrics.IpProvisioningMetrics; import com.android.networkstack.metrics.IpReachabilityMonitorMetrics; import com.android.networkstack.metrics.NetworkQuirkMetrics; import com.android.networkstack.packets.NeighborAdvertisement; import com.android.networkstack.packets.NeighborSolicitation; +import com.android.networkstack.util.NetworkStackUtils; import com.android.server.NetworkObserver; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService.NetworkStackServiceManager; -import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; import com.android.testutils.HandlerUtils; import com.android.testutils.TapPacketReader; +import com.android.testutils.TestableNetworkAgent; +import com.android.testutils.TestableNetworkCallback; import org.junit.After; import org.junit.Before; @@ -317,6 +330,8 @@ private TapPacketReader mPacketReader; private FileDescriptor mTapFd; private byte[] mClientMac; + private TestableNetworkAgent mNetworkAgent; + private HandlerThread mNetworkAgentThread; private boolean mIsSignatureRequiredTest; @@ -647,6 +662,12 @@ @After public void tearDown() throws Exception { if (testSkipped()) return; + if (mNetworkAgent != null) { + mNetworkAgent.unregister(); + } + if (mNetworkAgentThread != null) { + mNetworkAgentThread.quitSafely(); + } teardownTapInterface(); mIIpClient.shutdown(); awaitIpClientShutdown(); @@ -896,11 +917,10 @@ false /* broadcast */, message); } - private void sendArpReply(final byte[] clientMac) throws IOException { - final ByteBuffer packet = ArpPacket.buildArpPacket(clientMac /* dst */, - ROUTER_MAC_BYTES /* srcMac */, INADDR_ANY.getAddress() /* target IP */, - clientMac /* target HW address */, CLIENT_ADDR.getAddress() /* sender IP */, - (short) ARP_REPLY); + private void sendArpReply(final byte[] dstMac, final byte[] srcMac, final Inet4Address targetIp, + final Inet4Address senderIp) throws IOException { + final ByteBuffer packet = ArpPacket.buildArpPacket(dstMac, srcMac, targetIp.getAddress(), + dstMac /* target HW address */, senderIp.getAddress(), (short) ARP_REPLY); mPacketReader.sendResponse(packet); } @@ -1114,15 +1134,18 @@ // 2. if duplicated IPv4 address detection is enabled, verify TIMEOUT will affect ARP packets // capture running in other test cases. // 3. if IPv6 is enabled, e.g. withoutIPv6() isn't called when starting provisioning. - private void verifyIPv4OnlyProvisioningSuccess(final Collection<InetAddress> addresses) - throws Exception { + private LinkProperties verifyIPv4OnlyProvisioningSuccess( + final Collection<InetAddress> addresses) throws Exception { final ArgumentCaptor<LinkProperties> captor = ArgumentCaptor.forClass(LinkProperties.class); verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningSuccess(captor.capture()); - LinkProperties lp = captor.getValue(); + final LinkProperties lp = captor.getValue(); assertNotNull(lp); assertNotEquals(0, lp.getDnsServers().size()); assertEquals(addresses.size(), lp.getAddresses().size()); assertTrue(lp.getAddresses().containsAll(addresses)); + assertTrue(hasRouteTo(lp, IPV4_TEST_SUBNET_PREFIX)); // IPv4 directly-connected route + assertTrue(hasRouteTo(lp, IPV4_ANY_ADDRESS_PREFIX)); // IPv4 default route + return lp; } private void doRestoreInitialMtuTest(final boolean shouldChangeMtu, @@ -1283,6 +1306,15 @@ assertEquals(packet.senderIp, CLIENT_ADDR); } + private void assertArpRequest(final ArpPacket packet, final Inet4Address targetIp) { + assertEquals(packet.opCode, ARP_REQUEST); + assertEquals(packet.senderIp, CLIENT_ADDR); + assertEquals(packet.targetIp, targetIp); + assertTrue(Arrays.equals(packet.targetHwAddress.toByteArray(), + MacAddress.fromString("00:00:00:00:00:00").toByteArray())); + assertTrue(Arrays.equals(packet.senderHwAddress.toByteArray(), mClientMac)); + } + private void assertGratuitousARP(final ArpPacket packet) { assertEquals(packet.opCode, ARP_REPLY); assertEquals(packet.senderIp, CLIENT_ADDR); @@ -1308,7 +1340,8 @@ assertArpProbe(arpProbe); if (shouldResponseArpReply) { - sendArpReply(mClientMac); + sendArpReply(mClientMac /* dstMac */, ROUTER_MAC_BYTES /* srcMac */, + INADDR_ANY /* target IP */, CLIENT_ADDR /* sender IP */); } else { sendArpProbe(); } @@ -1519,6 +1552,117 @@ assertEquals(SERVER_ADDR, captor.getValue().getDhcpServerAddress()); } + private void createTestNetworkAgentAndRegister(final LinkProperties lp) throws Exception { + final Context context = InstrumentationRegistry.getInstrumentation().getContext(); + final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); + final TestNetworkSpecifier testNetworkSpecifier = new TestNetworkSpecifier(mIfaceName); + final TestableNetworkCallback cb = new TestableNetworkCallback(); + + // Requesting a network make sure the NetworkAgent is alive during the whole life cycle of + // requested network. + cm.requestNetwork(new NetworkRequest.Builder() + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_INTERNET) + .addTransportType(TRANSPORT_TEST) + .setNetworkSpecifier(testNetworkSpecifier) + .build(), cb); + mNetworkAgent = new TestableNetworkAgent(context, mNetworkAgentThread.getLooper(), + new NetworkCapabilities.Builder() + .removeCapability(NET_CAPABILITY_TRUSTED) + .removeCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_SUSPENDED) + .addCapability(NET_CAPABILITY_NOT_ROAMING) + .addCapability(NET_CAPABILITY_NOT_VPN) + .addTransportType(TRANSPORT_TEST) + .setNetworkSpecifier(testNetworkSpecifier) + .build(), + lp, + new NetworkAgentConfig.Builder().build()); + mNetworkAgent.register(); + mNetworkAgent.markConnected(); + cb.expectAvailableThenValidatedCallbacks(mNetworkAgent.getNetwork(), TEST_TIMEOUT_MS); + } + + private void assertReceivedDhcpRequestPacketCount() throws Exception { + final List<DhcpPacket> packetList = new ArrayList<>(); + DhcpPacket packet; + while ((packet = getNextDhcpPacket(PACKET_TIMEOUT_MS)) != null) { + assertDhcpRequestForReacquire(packet); + packetList.add(packet); + } + assertEquals(1, packetList.size()); + } + + private LinkProperties prepareDhcpReacquireTest() throws Exception { + mNetworkAgentThread = + new HandlerThread(IpClientIntegrationTestCommon.class.getSimpleName()); + mNetworkAgentThread.start(); + + final long currentTime = System.currentTimeMillis(); + setFeatureEnabled(NetworkStackUtils.DHCP_SLOW_RETRANSMISSION_VERSION, true); + performDhcpHandshake(true /* isSuccessLease */, + TEST_LEASE_DURATION_S, true /* isDhcpLeaseCacheEnabled */, + false /* isDhcpRapidCommitEnabled */, TEST_DEFAULT_MTU, + false /* isDhcpIpConflictDetectEnabled */); + final LinkProperties lp = + verifyIPv4OnlyProvisioningSuccess(Collections.singletonList(CLIENT_ADDR)); + assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_DEFAULT_MTU); + return lp; + } + + private OnAlarmListener runDhcpRenewTest(final Handler handler, final LinkProperties lp, + final InOrder inOrder) throws Exception { + // Create a NetworkAgent and register it to ConnectivityService with IPv4 LinkProperties, + // then ConnectivityService will call netd API to configure the IPv4 route on the kernel, + // otherwise, unicast DHCPREQUEST cannot be sent out due to no route to host(EHOSTUNREACH). + runAsShell(MANAGE_TEST_NETWORKS, () -> createTestNetworkAgentAndRegister(lp)); + + // DHCP client is in BOUND state right now, simulate the renewal via triggering renew alarm + // which should happen at T1. E.g. lease duration is 3600s, T1 = lease_duration * 0.5(1800s) + // T2 = lease_duration * 0.875(3150s). + final OnAlarmListener renewAlarm = expectAlarmSet(inOrder, "RENEW", 1800, handler); + final OnAlarmListener rebindAlarm = expectAlarmSet(inOrder, "REBIND", 3150, handler); + + // Trigger renew alarm and force DHCP client enter RenewingState. Device needs to start + // the ARP resolution for the fake DHCP server IPv4 address before sending the unicast + // DHCPREQUEST out, wait for the unicast ARP request and respond to it with ARP reply, + // otherwise, DHCPREQUEST still cannot be sent out due to that there is no correct ARP + // table for the dest IPv4 address. + handler.post(() -> renewAlarm.onAlarm()); + final ArpPacket request = getNextArpPacket(); + assertArpRequest(request, SERVER_ADDR); + sendArpReply(request.senderHwAddress.toByteArray() /* dst */, ROUTER_MAC_BYTES /* srcMac */, + request.senderIp /* target IP */, SERVER_ADDR /* sender IP */); + HandlerUtils.waitForIdle(handler, TEST_TIMEOUT_MS); + + // Verify there should be only one unicast DHCPREQUESTs to be received per RFC2131. + assertReceivedDhcpRequestPacketCount(); + + return rebindAlarm; + } + + @Test @SignatureRequiredTest(reason = "Need to mock the DHCP renew/rebind alarms") + public void testDhcpRenew() throws Exception { + final LinkProperties lp = prepareDhcpReacquireTest(); + final InOrder inOrder = inOrder(mAlarm); + runDhcpRenewTest(mDependencies.mDhcpClient.getHandler(), lp, inOrder); + } + + @Test @SignatureRequiredTest(reason = "Need to mock the DHCP renew/rebind alarms") + public void testDhcpRebind() throws Exception { + final LinkProperties lp = prepareDhcpReacquireTest(); + final Handler handler = mDependencies.mDhcpClient.getHandler(); + final InOrder inOrder = inOrder(mAlarm); + final OnAlarmListener rebindAlarm = runDhcpRenewTest(handler, lp, inOrder); + + // Trigger rebind alarm and forece DHCP client enter RebindingState. DHCP client sends + // broadcast DHCPREQUEST to nearby servers, then check how many DHCPREQUEST packets are + // retransmitted within PACKET_TIMEOUT_MS(5s), there should be only one DHCPREQUEST + // captured per RFC2131. + handler.post(() -> rebindAlarm.onAlarm()); + assertReceivedDhcpRequestPacketCount(); + } + @Test @SignatureRequiredTest(reason = "TODO: evaluate whether signature perms are required") public void testRestoreInitialInterfaceMtu() throws Exception { doRestoreInitialMtuTest(true /* shouldChangeMtu */, false /* shouldRemoveTestInterface */); @@ -2543,6 +2687,13 @@ mIIpClient.updateLayer2Information(roamingInfo); } + private void assertDhcpRequestForReacquire(final DhcpPacket packet) { + assertTrue(packet instanceof DhcpRequestPacket); + assertEquals(packet.mClientIp, CLIENT_ADDR); // client IP + assertNull(packet.mRequestedIp); // requested IP option + assertNull(packet.mServerIdentifier); // server ID + } + private void doDhcpRoamingTest(final boolean hasMismatchedIpAddress, final String displayName, final MacAddress bssid, final boolean expectRoaming, final boolean shouldReplyNakOnRoam) throws Exception { @@ -2580,12 +2731,8 @@ return; } // check DHCPREQUEST broadcast sent to renew IP address. - DhcpPacket packet; - packet = getNextDhcpPacket(); - assertTrue(packet instanceof DhcpRequestPacket); - assertEquals(packet.mClientIp, CLIENT_ADDR); // client IP - assertNull(packet.mRequestedIp); // requested IP option - assertNull(packet.mServerIdentifier); // server ID + final DhcpPacket packet = getNextDhcpPacket(); + assertDhcpRequestForReacquire(packet); final ByteBuffer packetBuffer = shouldReplyNakOnRoam ? buildDhcpNakPacket(packet, "request IP on a wrong subnet") @@ -3027,10 +3174,15 @@ } final int after = getNumOpenFds(); - // Check that the number of open fds is the same as before. - // If this exact match becomes flaky, we could add some tolerance here (e.g., allow 2-3 - // extra fds), since it's likely that any leak would at least leak one FD per loop. - assertEquals("Fd leak after " + iterations + " iterations: ", before, after); + // Check that the number of open fds is the same as before, within some tolerance (e.g., + // garbage collection or other cleanups might have caused an fd to be closed). This + // shouldn't make leak detection much less reliable, since it's likely that any leak would + // at least leak one FD per loop. + final int tolerance = 4; + assertTrue( + "FD leak detected after " + iterations + " iterations: expected " + + before + " +/- " + tolerance + " fds, found " + after, + Math.abs(after - before) <= tolerance); } // TODO: delete when DhcpOption is @JavaOnlyImmutable. @@ -3070,8 +3222,8 @@ @Test public void testDiscoverCustomizedDhcpOptions() throws Exception { - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, false /* isDhcpLeaseCacheEnabled */); @@ -3082,8 +3234,8 @@ @Test public void testDiscoverCustomizedDhcpOptions_nullDhcpOptions() throws Exception { - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(null /* options */, info, false /* isDhcpLeaseCacheEnabled */); @@ -3104,8 +3256,8 @@ @Test public void testDiscoverCustomizedDhcpOptions_disallowedOui() throws Exception { - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, - new byte[]{ 0x00, 0x11, 0x22} /* oui */, (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, + new byte[]{ 0x00, 0x11, 0x22} /* oui */, (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, false /* isDhcpLeaseCacheEnabled */); @@ -3116,8 +3268,8 @@ @Test public void testDiscoverCustomizedDhcpOptions_invalidIeId() throws Exception { - final ScanResultInfo info = makeScanResultInfo(0xde /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xde /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, false /* isDhcpLeaseCacheEnabled */); @@ -3128,7 +3280,7 @@ @Test public void testDiscoverCustomizedDhcpOptions_invalidVendorSpecificType() throws Exception { - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, (byte) 0x10 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, false /* isDhcpLeaseCacheEnabled */); @@ -3145,8 +3297,8 @@ makeDhcpOption((byte) 77, TEST_OEM_USER_CLASS_INFO), // Option 26: MTU makeDhcpOption((byte) 26, HexDump.toByteArray(TEST_DEFAULT_MTU))); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(options, info, false /* isDhcpLeaseCacheEnabled */); @@ -3163,8 +3315,8 @@ makeDhcpOption((byte) 77, TEST_OEM_USER_CLASS_INFO), // NTP_SERVER makeDhcpOption((byte) 42, null)); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(options, info, false /* isDhcpLeaseCacheEnabled */); @@ -3179,8 +3331,8 @@ final List<DhcpOption> options = Arrays.asList( // DHCP_USER_CLASS makeDhcpOption((byte) 77, null)); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(options, info, false /* isDhcpLeaseCacheEnabled */); @@ -3193,8 +3345,8 @@ public void testRequestCustomizedDhcpOptions() throws Exception { setUpRetrievedNetworkAttributesForInitRebootState(); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, true /* isDhcpLeaseCacheEnabled */); @@ -3207,8 +3359,8 @@ public void testRequestCustomizedDhcpOptions_nullDhcpOptions() throws Exception { setUpRetrievedNetworkAttributesForInitRebootState(); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(null /* options */, info, true /* isDhcpLeaseCacheEnabled */); @@ -3233,8 +3385,8 @@ public void testRequestCustomizedDhcpOptions_disallowedOui() throws Exception { setUpRetrievedNetworkAttributesForInitRebootState(); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, - new byte[]{ 0x00, 0x11, 0x22} /* oui */, (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, + new byte[]{ 0x00, 0x11, 0x22} /* oui */, (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, true /* isDhcpLeaseCacheEnabled */); @@ -3247,8 +3399,8 @@ public void testRequestCustomizedDhcpOptions_invalidIeId() throws Exception { setUpRetrievedNetworkAttributesForInitRebootState(); - final ScanResultInfo info = makeScanResultInfo(0xde /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xde /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, true /* isDhcpLeaseCacheEnabled */); @@ -3261,7 +3413,7 @@ public void testRequestCustomizedDhcpOptions_invalidVendorSpecificType() throws Exception { setUpRetrievedNetworkAttributesForInitRebootState(); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, (byte) 0x10 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(TEST_OEM_DHCP_OPTIONS, info, true /* isDhcpLeaseCacheEnabled */); @@ -3280,8 +3432,8 @@ makeDhcpOption((byte) 77, TEST_OEM_USER_CLASS_INFO), // Option 26: MTU makeDhcpOption((byte) 26, HexDump.toByteArray(TEST_DEFAULT_MTU))); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(options, info, true /* isDhcpLeaseCacheEnabled */); @@ -3300,8 +3452,8 @@ makeDhcpOption((byte) 77, TEST_OEM_USER_CLASS_INFO), // NTP_SERVER makeDhcpOption((byte) 42, null)); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(options, info, true /* isDhcpLeaseCacheEnabled */); @@ -3318,8 +3470,8 @@ final List<DhcpOption> options = Arrays.asList( // DHCP_USER_CLASS makeDhcpOption((byte) 77, null)); - final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specificIE */, TEST_OEM_OUI, - (byte) 0x17 /* vendor-specific IE type */); + final ScanResultInfo info = makeScanResultInfo(0xdd /* vendor-specific IE */, TEST_OEM_OUI, + (byte) 0x11 /* vendor-specific IE type */); final DhcpPacket packet = doCustomizedDhcpOptionsTest(options, info, true /* isDhcpLeaseCacheEnabled */);
diff --git a/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt index 2dd984d..17153de 100644 --- a/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt +++ b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt
@@ -33,17 +33,18 @@ import android.system.OsConstants.IPPROTO_UDP import android.system.OsConstants.SOCK_DGRAM import android.system.OsConstants.SOCK_NONBLOCK -import androidx.test.platform.app.InstrumentationRegistry import android.system.OsConstants.SOCK_RAW import android.system.OsConstants.SOL_SOCKET import android.system.OsConstants.SO_RCVTIMEO import android.system.StructTimeval +import androidx.test.platform.app.InstrumentationRegistry import com.android.net.module.util.InterfaceParams import com.android.net.module.util.Ipv6Utils import com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN import com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_ANY import com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_NODES_MULTICAST import com.android.net.module.util.structs.PrefixInformationOption +import com.android.networkstack.util.NetworkStackUtils import com.android.testutils.ArpRequestFilter import com.android.testutils.ETHER_HEADER_LENGTH import com.android.testutils.IPV4_HEADER_LENGTH @@ -56,9 +57,9 @@ import org.junit.Test import java.io.FileDescriptor import java.net.Inet4Address -import kotlin.reflect.KClass import java.net.Inet6Address import java.nio.ByteBuffer +import kotlin.reflect.KClass import kotlin.test.assertEquals import kotlin.test.assertTrue import kotlin.test.fail
diff --git a/tests/unit/src/android/net/apf/ApfTest.java b/tests/unit/src/android/net/apf/ApfTest.java index b2feaf1..bf3b87d 100644 --- a/tests/unit/src/android/net/apf/ApfTest.java +++ b/tests/unit/src/android/net/apf/ApfTest.java
@@ -51,7 +51,6 @@ import android.net.ip.IpClient.IpClientCallbacksWrapper; import android.net.metrics.IpConnectivityLog; import android.net.metrics.RaEvent; -import android.net.util.SharedLog; import android.os.ConditionVariable; import android.os.Parcelable; import android.os.SystemClock; @@ -68,6 +67,7 @@ import com.android.net.module.util.Inet4AddressUtils; import com.android.net.module.util.InterfaceParams; import com.android.net.module.util.NetworkStackConstants; +import com.android.net.module.util.SharedLog; import com.android.networkstack.apishim.NetworkInformationShimImpl; import com.android.server.networkstack.tests.R; @@ -984,7 +984,7 @@ } @Override - void maybeStartFilter() { + public void maybeStartFilter() { mHardwareAddress = MOCK_MAC_ADDR; installNewProgramLocked();
diff --git a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java index 243bf63..95d782d 100644 --- a/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java +++ b/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
@@ -49,13 +49,14 @@ import android.net.IpPrefix; import android.net.MacAddress; import android.net.dhcp.DhcpServer.Clock; -import android.net.util.SharedLog; import android.os.Binder; import android.os.RemoteException; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.net.module.util.SharedLog; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith;
diff --git a/tests/unit/src/android/net/dhcp/DhcpServerTest.java b/tests/unit/src/android/net/dhcp/DhcpServerTest.java index 58f9a36..6d4bc13 100644 --- a/tests/unit/src/android/net/dhcp/DhcpServerTest.java +++ b/tests/unit/src/android/net/dhcp/DhcpServerTest.java
@@ -23,9 +23,9 @@ import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST; import static android.net.dhcp.DhcpServer.CMD_RECEIVE_PACKET; import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS; -import static android.net.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION; import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; +import static com.android.networkstack.util.NetworkStackUtils.DHCP_RAPID_COMMIT_VERSION; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -52,13 +52,13 @@ import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException; import android.net.dhcp.DhcpServer.Clock; import android.net.dhcp.DhcpServer.Dependencies; -import android.net.util.SharedLog; import android.os.ConditionVariable; import android.testing.AndroidTestingRunner; import androidx.test.filters.SmallTest; import com.android.net.module.util.Inet4AddressUtils; +import com.android.net.module.util.SharedLog; import com.android.testutils.HandlerUtils; import org.junit.After;
diff --git a/tests/unit/src/android/net/ip/ConntrackMonitorTest.java b/tests/unit/src/android/net/ip/ConntrackMonitorTest.java deleted file mode 100644 index fc0d52b..0000000 --- a/tests/unit/src/android/net/ip/ConntrackMonitorTest.java +++ /dev/null
@@ -1,336 +0,0 @@ -/* - * Copyright (C) 2020 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.ip.ConntrackMonitor.ConntrackEvent; -import static android.system.OsConstants.AF_UNIX; -import static android.system.OsConstants.IPPROTO_TCP; -import static android.system.OsConstants.SOCK_DGRAM; - -import static com.android.net.module.util.netlink.ConntrackMessage.Tuple; -import static com.android.net.module.util.netlink.ConntrackMessage.TupleIpv4; -import static com.android.net.module.util.netlink.ConntrackMessage.TupleProto; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_DELETE; -import static com.android.net.module.util.netlink.NetlinkConstants.IPCTNL_MSG_CT_NEW; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; - -import android.net.InetAddresses; -import android.net.util.SharedLog; -import android.os.ConditionVariable; -import android.os.Handler; -import android.os.HandlerThread; -import android.system.ErrnoException; -import android.system.Os; - -import androidx.annotation.NonNull; -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import com.android.net.module.util.netlink.NetlinkConstants; -import com.android.net.module.util.netlink.NetlinkSocket; - -import libcore.util.HexEncoding; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.FileDescriptor; -import java.io.InterruptedIOException; -import java.net.Inet4Address; - - -/** - * Tests for ConntrackMonitor. - */ -@RunWith(AndroidJUnit4.class) -@SmallTest -public class ConntrackMonitorTest { - private static final long TIMEOUT_MS = 10_000L; - - @Mock private SharedLog mLog; - @Mock private ConntrackMonitor.ConntrackEventConsumer mConsumer; - - private final HandlerThread mHandlerThread = new HandlerThread( - ConntrackMonitorTest.class.getSimpleName()); - - // Late init since the handler thread has been started. - private Handler mHandler; - private TestConntrackMonitor mConntrackMonitor; - - // A version of [ConntrackMonitor] that reads packets from the socket pair, and instead - // allows the test to write test packets to the socket pair via [sendMessage]. - private class TestConntrackMonitor extends ConntrackMonitor { - TestConntrackMonitor(@NonNull Handler h, @NonNull SharedLog log, - @NonNull ConntrackEventConsumer cb) { - super(h, log, cb); - - mReadFd = new FileDescriptor(); - mWriteFd = new FileDescriptor(); - try { - Os.socketpair(AF_UNIX, SOCK_DGRAM, 0, mWriteFd, mReadFd); - } catch (ErrnoException e) { - fail("Could not create socket pair: " + e); - } - } - - @Override - protected FileDescriptor createFd() { - return mReadFd; - } - - private void sendMessage(byte[] msg) { - mHandler.post(() -> { - try { - NetlinkSocket.sendMessage(mWriteFd, msg, 0 /* offset */, msg.length, - TIMEOUT_MS); - } catch (ErrnoException | InterruptedIOException e) { - fail("Unable to send netfilter message: " + e); - } - }); - } - - private final FileDescriptor mReadFd; - private final FileDescriptor mWriteFd; - } - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mHandlerThread.start(); - mHandler = new Handler(mHandlerThread.getLooper()); - - // ConntrackMonitor needs to be started from the handler thread. - final ConditionVariable initDone = new ConditionVariable(); - mHandler.post(() -> { - TestConntrackMonitor m = new TestConntrackMonitor(mHandler, mLog, mConsumer); - m.start(); - mConntrackMonitor = m; - - initDone.open(); - }); - if (!initDone.block(TIMEOUT_MS)) { - fail("... init monitor timed-out after " + TIMEOUT_MS + "ms"); - } - } - - @After - public void tearDown() throws Exception { - mHandlerThread.quitSafely(); - } - - public static final String CT_V4NEW_TCP_HEX = - // CHECKSTYLE:OFF IndentationCheck - // struct nlmsghdr - "8C000000" + // length = 140 - "0001" + // type = NFNL_SUBSYS_CTNETLINK (1) << 8 | IPCTNL_MSG_CT_NEW (0) - "0006" + // flags = NLM_F_CREATE (1 << 10) | NLM_F_EXCL (1 << 9) - "00000000" + // seqno = 0 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "1234" + // res_id = 0x1234 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 C0A8500C" + // nla_type=CTA_IP_V4_SRC, ip=192.168.80.12 - "0800 0200 8C700874" + // nla_type=CTA_IP_V4_DST, ip=140.112.8.116 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 F3F1 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=62449 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0280" + // nla_type = nested CTA_TUPLE_REPLY - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 8C700874" + // nla_type=CTA_IP_V4_SRC, ip=140.112.8.116 - "0800 0200 6451B301" + // nla_type=CTA_IP_V4_DST, ip=100.81.179.1 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 01BB 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=443 (big endian) - "0600 0300 F3F1 0000" + // nla_type=CTA_PROTO_DST_PORT, port=62449 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0300" + // nla_type = CTA_STATUS - "0000019e" + // nla_value = 0b110011110 (big endian) - // IPS_SEEN_REPLY (1 << 1) | IPS_ASSURED (1 << 2) | - // IPS_CONFIRMED (1 << 3) | IPS_SRC_NAT (1 << 4) | - // IPS_SRC_NAT_DONE (1 << 7) | IPS_DST_NAT_DONE (1 << 8) - // struct nlattr - "0800" + // nla_len = 8 - "0700" + // nla_type = CTA_TIMEOUT - "00000078"; // nla_value = 120 (big endian) - // CHECKSTYLE:ON IndentationCheck - public static final byte[] CT_V4NEW_TCP_BYTES = - HexEncoding.decode(CT_V4NEW_TCP_HEX.replaceAll(" ", "").toCharArray(), false); - - @NonNull - private ConntrackEvent makeTestConntrackEvent(short msgType, int status, int timeoutSec) { - final Inet4Address privateIp = - (Inet4Address) InetAddresses.parseNumericAddress("192.168.80.12"); - final Inet4Address remoteIp = - (Inet4Address) InetAddresses.parseNumericAddress("140.112.8.116"); - final Inet4Address publicIp = - (Inet4Address) InetAddresses.parseNumericAddress("100.81.179.1"); - - return new ConntrackEvent( - (short) (NetlinkConstants.NFNL_SUBSYS_CTNETLINK << 8 | msgType), - new Tuple(new TupleIpv4(privateIp, remoteIp), - new TupleProto((byte) IPPROTO_TCP, (short) 62449, (short) 443)), - new Tuple(new TupleIpv4(remoteIp, publicIp), - new TupleProto((byte) IPPROTO_TCP, (short) 443, (short) 62449)), - status, - timeoutSec); - } - - @Test - public void testConntrackEventNew() throws Exception { - final ConntrackEvent expectedEvent = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, - 0x19e /* status */, 120 /* timeoutSec */); - mConntrackMonitor.sendMessage(CT_V4NEW_TCP_BYTES); - verify(mConsumer, timeout(TIMEOUT_MS)).accept(eq(expectedEvent)); - } - - @Test - public void testConntrackEventEquals() { - final ConntrackEvent event1 = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, 1234 /* status */, - 5678 /* timeoutSec*/); - final ConntrackEvent event2 = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, 1234 /* status */, - 5678 /* timeoutSec*/); - assertEquals(event1, event2); - } - - @Test - public void testConntrackEventNotEquals() { - final ConntrackEvent e = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, 1234 /* status */, - 5678 /* timeoutSec*/); - - final ConntrackEvent typeNotEqual = new ConntrackEvent((short) (e.msgType + 1) /* diff */, - e.tupleOrig, e.tupleReply, e.status, e.timeoutSec); - assertNotEquals(e, typeNotEqual); - - final ConntrackEvent tupleOrigNotEqual = new ConntrackEvent(e.msgType, - null /* diff */, e.tupleReply, e.status, e.timeoutSec); - assertNotEquals(e, tupleOrigNotEqual); - - final ConntrackEvent tupleReplyNotEqual = new ConntrackEvent(e.msgType, - e.tupleOrig, null /* diff */, e.status, e.timeoutSec); - assertNotEquals(e, tupleReplyNotEqual); - - final ConntrackEvent statusNotEqual = new ConntrackEvent(e.msgType, - e.tupleOrig, e.tupleReply, e.status + 1 /* diff */, e.timeoutSec); - assertNotEquals(e, statusNotEqual); - - final ConntrackEvent timeoutSecNotEqual = new ConntrackEvent(e.msgType, - e.tupleOrig, e.tupleReply, e.status, e.timeoutSec + 1 /* diff */); - assertNotEquals(e, timeoutSecNotEqual); - } - - @Test - public void testToString() { - final ConntrackEvent event = makeTestConntrackEvent(IPCTNL_MSG_CT_NEW, - 0x198 /* status */, 120 /* timeoutSec */); - final String expected = "" - + "ConntrackEvent{" - + "msg_type{IPCTNL_MSG_CT_NEW}, " - + "tuple_orig{Tuple{IPPROTO_TCP: 192.168.80.12:62449 -> 140.112.8.116:443}}, " - + "tuple_reply{Tuple{IPPROTO_TCP: 140.112.8.116:443 -> 100.81.179.1:62449}}, " - + "status{408(IPS_CONFIRMED|IPS_SRC_NAT|IPS_SRC_NAT_DONE|IPS_DST_NAT_DONE)}, " - + "timeout_sec{120}}"; - assertEquals(expected, event.toString()); - } - - public static final String CT_V4DELETE_TCP_HEX = - // CHECKSTYLE:OFF IndentationCheck - // struct nlmsghdr - "84000000" + // length = 132 - "0201" + // type = NFNL_SUBSYS_CTNETLINK (1) << 8 | IPCTNL_MSG_CT_DELETE (2) - "0000" + // flags = 0 - "00000000" + // seqno = 0 - "00000000" + // pid = 0 - // struct nfgenmsg - "02" + // nfgen_family = AF_INET - "00" + // version = NFNETLINK_V0 - "1234" + // res_id = 0x1234 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0180" + // nla_type = nested CTA_TUPLE_ORIG - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 C0A8500C" + // nla_type=CTA_IP_V4_SRC, ip=192.168.80.12 - "0800 0200 8C700874" + // nla_type=CTA_IP_V4_DST, ip=140.112.8.116 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 F3F1 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=62449 (big endian) - "0600 0300 01BB 0000" + // nla_type=CTA_PROTO_DST_PORT, port=433 (big endian) - // struct nlattr - "3400" + // nla_len = 52 - "0280" + // nla_type = nested CTA_TUPLE_REPLY - // struct nlattr - "1400" + // nla_len = 20 - "0180" + // nla_type = nested CTA_TUPLE_IP - "0800 0100 8C700874" + // nla_type=CTA_IP_V4_SRC, ip=140.112.8.116 - "0800 0200 6451B301" + // nla_type=CTA_IP_V4_DST, ip=100.81.179.1 - // struct nlattr - "1C00" + // nla_len = 28 - "0280" + // nla_type = nested CTA_TUPLE_PROTO - "0500 0100 06 000000" + // nla_type=CTA_PROTO_NUM, proto=IPPROTO_TCP (6) - "0600 0200 01BB 0000" + // nla_type=CTA_PROTO_SRC_PORT, port=433 (big endian) - "0600 0300 F3F1 0000" + // nla_type=CTA_PROTO_DST_PORT, port=62449 (big endian) - // struct nlattr - "0800" + // nla_len = 8 - "0300" + // nla_type = CTA_STATUS - "0000039E"; // nla_value = 0b1110011110 (big endian) - // IPS_SEEN_REPLY (1 << 1) | IPS_ASSURED (1 << 2) | - // IPS_CONFIRMED (1 << 3) | IPS_SRC_NAT (1 << 4) | - // IPS_SRC_NAT_DONE (1 << 7) | IPS_DST_NAT_DONE (1 << 8) | - // IPS_DYING (1 << 9) - // CHECKSTYLE:ON IndentationCheck - public static final byte[] CT_V4DELETE_TCP_BYTES = - HexEncoding.decode(CT_V4DELETE_TCP_HEX.replaceAll(" ", "").toCharArray(), false); - - @Test - public void testConntrackEventDelete() throws Exception { - final ConntrackEvent expectedEvent = - makeTestConntrackEvent(IPCTNL_MSG_CT_DELETE, 0x39e /* status */, - 0 /* timeoutSec (absent) */); - mConntrackMonitor.sendMessage(CT_V4DELETE_TCP_BYTES); - verify(mConsumer, timeout(TIMEOUT_MS)).accept(eq(expectedEvent)); - } -}
diff --git a/tests/unit/src/android/net/ip/InterfaceControllerTest.java b/tests/unit/src/android/net/ip/InterfaceControllerTest.java deleted file mode 100644 index 02bc73c..0000000 --- a/tests/unit/src/android/net/ip/InterfaceControllerTest.java +++ /dev/null
@@ -1,91 +0,0 @@ -/* - * 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 org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import android.net.INetd; -import android.net.InetAddresses; -import android.net.InterfaceConfigurationParcel; -import android.net.LinkAddress; -import android.net.util.SharedLog; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.util.ArrayList; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class InterfaceControllerTest { - private static final String TEST_IFACE = "testif"; - private static final String TEST_IPV4_ADDR = "192.168.123.28"; - private static final int TEST_PREFIXLENGTH = 31; - - @Mock private INetd mNetd; - @Mock private SharedLog mLog; - @Captor private ArgumentCaptor<InterfaceConfigurationParcel> mConfigCaptor; - - private InterfaceController mController; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - mController = new InterfaceController(TEST_IFACE, mNetd, mLog); - - doNothing().when(mNetd).interfaceSetCfg(mConfigCaptor.capture()); - } - - @Test - public void testSetIPv4Address() throws Exception { - mController.setIPv4Address( - new LinkAddress(InetAddresses.parseNumericAddress(TEST_IPV4_ADDR), - TEST_PREFIXLENGTH)); - verify(mNetd, times(1)).interfaceSetCfg(any()); - final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue(); - assertEquals(TEST_IFACE, parcel.ifName); - assertEquals(TEST_IPV4_ADDR, parcel.ipv4Addr); - assertEquals(TEST_PREFIXLENGTH, parcel.prefixLength); - assertEquals("", parcel.hwAddr); - assertArrayEquals(new String[0], parcel.flags); - } - - @Test - public void testClearIPv4Address() throws Exception { - mController.clearIPv4Address(); - verify(mNetd, times(1)).interfaceSetCfg(any()); - final InterfaceConfigurationParcel parcel = mConfigCaptor.getValue(); - assertEquals(TEST_IFACE, parcel.ifName); - assertEquals("0.0.0.0", parcel.ipv4Addr); - assertEquals(0, parcel.prefixLength); - assertEquals("", parcel.hwAddr); - assertArrayEquals(new String[0], parcel.flags); - } -}
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java index b88317a..8efa9ab 100644 --- a/tests/unit/src/android/net/ip/IpClientTest.java +++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -16,9 +16,10 @@ package android.net.ip; -import static android.net.util.NetworkStackUtils.IPCLIENT_PARSE_NETLINK_EVENTS_VERSION; import static android.system.OsConstants.RT_SCOPE_UNIVERSE; +import static com.android.networkstack.util.NetworkStackUtils.IPCLIENT_PARSE_NETLINK_EVENTS_VERSION; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -69,10 +70,10 @@ import com.android.net.module.util.InterfaceParams; import com.android.networkstack.R; +import com.android.networkstack.ipmemorystore.IpMemoryStoreService; import com.android.server.NetworkObserver; import com.android.server.NetworkObserverRegistry; import com.android.server.NetworkStackService; -import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService; import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
diff --git a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt index cabd14a..10b55d5 100644 --- a/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt +++ b/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.kt
@@ -17,7 +17,6 @@ import android.annotation.SuppressLint import android.content.Context -import android.net.ip.IpNeighborMonitor.NeighborEventConsumer import android.net.INetd import android.net.InetAddresses.parseNumericAddress import android.net.IpPrefix @@ -25,8 +24,7 @@ import android.net.LinkProperties import android.net.RouteInfo import android.net.metrics.IpConnectivityLog -import android.net.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION -import android.net.util.SharedLog +import com.android.networkstack.util.NetworkStackUtils.IP_REACHABILITY_MCAST_RESOLICIT_VERSION import android.os.Handler import android.os.HandlerThread import android.os.MessageQueue @@ -54,6 +52,8 @@ import androidx.test.runner.AndroidJUnit4 import com.android.networkstack.metrics.IpReachabilityMonitorMetrics import com.android.net.module.util.InterfaceParams +import com.android.net.module.util.SharedLog +import com.android.net.module.util.ip.IpNeighborMonitor import com.android.net.module.util.netlink.StructNdMsg.NUD_FAILED import com.android.net.module.util.netlink.StructNdMsg.NUD_REACHABLE import com.android.net.module.util.netlink.StructNdMsg.NUD_STALE
diff --git a/tests/unit/src/android/net/testutils/NetworkStatsUtilsTest.kt b/tests/unit/src/android/net/testutils/NetworkStatsUtilsTest.kt index 7e4ae0b..2e76c52 100644 --- a/tests/unit/src/android/net/testutils/NetworkStatsUtilsTest.kt +++ b/tests/unit/src/android/net/testutils/NetworkStatsUtilsTest.kt
@@ -17,6 +17,9 @@ package android.net.testutils import android.net.NetworkStats +import android.net.NetworkStats.DEFAULT_NETWORK_NO +import android.net.NetworkStats.METERED_NO +import android.net.NetworkStats.ROAMING_NO import android.net.NetworkStats.SET_DEFAULT import android.net.NetworkStats.TAG_NONE import android.os.Build @@ -42,8 +45,10 @@ @Test fun testOrderInsensitiveEquals() { val testEntry = arrayOf( - NetworkStats.Entry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, 128L, 8L, 0L, 2L, 20L), - NetworkStats.Entry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, 512L, 32L, 0L, 0L, 0L)) + NetworkStats.Entry(TEST_IFACE, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 128L, 8L, 0L, 2L, 20L), + NetworkStats.Entry(TEST_IFACE2, 100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, + DEFAULT_NETWORK_NO, 512L, 32L, 0L, 0L, 0L)) // Verify equals of empty stats regardless of initial capacity. val red = NetworkStats(TEST_START, 0)
diff --git a/tests/unit/src/com/android/server/NetworkStackServiceTest.kt b/tests/unit/src/com/android/networkstack/NetworkStackServiceTest.kt similarity index 98% rename from tests/unit/src/com/android/server/NetworkStackServiceTest.kt rename to tests/unit/src/com/android/networkstack/NetworkStackServiceTest.kt index 40abe9e..4c4864b 100644 --- a/tests/unit/src/com/android/server/NetworkStackServiceTest.kt +++ b/tests/unit/src/com/android/networkstack/NetworkStackServiceTest.kt
@@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.server +package com.android.networkstack import android.content.Context import android.net.IIpMemoryStoreCallbacks @@ -40,7 +40,7 @@ import com.android.server.NetworkStackService.NetworkStackConnector import com.android.server.NetworkStackService.PermissionChecker import com.android.server.connectivity.NetworkMonitor -import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService +import com.android.networkstack.ipmemorystore.IpMemoryStoreService import com.android.testutils.DevSdkIgnoreRule import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
diff --git a/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/tests/unit/src/com/android/networkstack/ipmemorystore/IpMemoryStoreServiceTest.java similarity index 99% rename from tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java rename to tests/unit/src/com/android/networkstack/ipmemorystore/IpMemoryStoreServiceTest.java index 73edcc7..976389e 100644 --- a/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java +++ b/tests/unit/src/com/android/networkstack/ipmemorystore/IpMemoryStoreServiceTest.java
@@ -14,9 +14,9 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; -import static com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance; +import static com.android.networkstack.ipmemorystore.RegularMaintenanceJobService.InterruptMaintenance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse;
diff --git a/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java b/tests/unit/src/com/android/networkstack/ipmemorystore/RelevanceUtilsTests.java similarity index 97% rename from tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java rename to tests/unit/src/com/android/networkstack/ipmemorystore/RelevanceUtilsTests.java index 3d3aabc..86f111d 100644 --- a/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java +++ b/tests/unit/src/com/android/networkstack/ipmemorystore/RelevanceUtilsTests.java
@@ -14,9 +14,9 @@ * limitations under the License. */ -package com.android.server.connectivity.ipmemorystore; +package com.android.networkstack.ipmemorystore; -import static com.android.server.connectivity.ipmemorystore.RelevanceUtils.CAPPED_RELEVANCE; +import static com.android.networkstack.ipmemorystore.RelevanceUtils.CAPPED_RELEVANCE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue;
diff --git a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java index f83c02f..6cc4bfb 100644 --- a/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -47,21 +47,21 @@ import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS; import static android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_TCP; import static android.net.util.DataStallUtils.DEFAULT_DATA_STALL_EVALUATION_TYPES; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS; -import static android.net.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS; -import static android.net.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT; -import static android.net.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK; -import static android.net.util.NetworkStackUtils.DNS_PROBE_PRIVATE_IP_NO_INTERNET_VERSION; -import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTPS_URL; -import static android.net.util.NetworkStackUtils.TEST_CAPTIVE_PORTAL_HTTP_URL; -import static android.net.util.NetworkStackUtils.TEST_URL_EXPIRATION_TIME; +import static android.os.Build.VERSION_CODES.S_V2; import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY; +import static com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTPS_URL; +import static com.android.net.module.util.NetworkStackConstants.TEST_CAPTIVE_PORTAL_HTTP_URL; +import static com.android.net.module.util.NetworkStackConstants.TEST_URL_EXPIRATION_TIME; import static com.android.networkstack.util.DnsUtils.PRIVATE_DNS_PROBE_HOST_SUFFIX; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_OTHER_FALLBACK_URLS; +import static com.android.networkstack.util.NetworkStackUtils.CAPTIVE_PORTAL_USE_HTTPS; +import static com.android.networkstack.util.NetworkStackUtils.DEFAULT_CAPTIVE_PORTAL_DNS_PROBE_TIMEOUT; +import static com.android.networkstack.util.NetworkStackUtils.DISMISS_PORTAL_IN_VALIDATED_NETWORK; +import static com.android.networkstack.util.NetworkStackUtils.DNS_PROBE_PRIVATE_IP_NO_INTERNET_VERSION; import static com.android.server.connectivity.NetworkMonitor.INITIAL_REEVALUATE_DELAY_MS; import static com.android.server.connectivity.NetworkMonitor.extractCharset; -import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -124,7 +124,6 @@ import android.net.metrics.IpConnectivityLog; import android.net.networkstack.aidl.NetworkMonitorParameters; import android.net.shared.PrivateDnsConfig; -import android.net.util.SharedLog; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; @@ -150,6 +149,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.modules.utils.build.SdkLevel; +import com.android.net.module.util.SharedLog; import com.android.networkstack.NetworkStackNotifier; import com.android.networkstack.R; import com.android.networkstack.apishim.CaptivePortalDataShimImpl; @@ -601,6 +601,10 @@ 0, mCreatedNetworkMonitors.size()); assertEquals("BroadcastReceiver still registered after disconnect", 0, mRegisteredReceivers.size()); + if (mTstDependencies.isTcpInfoParsingSupported()) { + verify(mTstDependencies, times(networkMonitors.length)) + .removeDeviceConfigChangedListener(any()); + } } private void resetCallbacks() { @@ -1505,10 +1509,10 @@ runCapportApiInvalidUrlTest("ThisIsNotAValidUrl"); } - @Test @IgnoreUpTo(SC_V2) + @Test @IgnoreUpTo(S_V2) public void testVpnReevaluationWhenUnderlyingNetworkChange() throws Exception { // Skip this test if the test is built against SDK < T - assumeTrue(ConstantsShim.VERSION > SC_V2); + assumeTrue(ConstantsShim.VERSION > S_V2); // Start a VPN network final NetworkCapabilities nc = new NetworkCapabilities.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_VPN) @@ -1850,12 +1854,12 @@ @Test public void testIsDataStall_EvaluationTcp() throws Exception { + when(mTstDependencies.isTcpInfoParsingSupported()).thenReturn(true); // Evaluate TCP only. Expect ignoring DNS signal. setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_TCP); WrappedNetworkMonitor wrappedMonitor = makeMonitor(CELL_METERED_CAPABILITIES); assertFalse(wrappedMonitor.isDataStall()); // Packet received. - when(mTstDependencies.isTcpInfoParsingSupported()).thenReturn(true); when(mTst.getLatestReceivedCount()).thenReturn(5); // Trigger a tcp event immediately. setTcpPollingInterval(0);
diff --git a/tests/unit/src/com/android/server/util/SharedLogTest.java b/tests/unit/src/com/android/server/util/SharedLogTest.java deleted file mode 100644 index b1db051..0000000 --- a/tests/unit/src/com/android/server/util/SharedLogTest.java +++ /dev/null
@@ -1,97 +0,0 @@ -/* - * Copyright (C) 2017 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 com.android.server.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import android.net.util.SharedLog; - -import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.ByteArrayOutputStream; -import java.io.PrintWriter; - -@RunWith(AndroidJUnit4.class) -@SmallTest -public class SharedLogTest { - private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}"; - private static final String TIMESTAMP = "HH:MM:SS"; - - @Test - public void testBasicOperation() { - final SharedLog logTop = new SharedLog("top"); - logTop.mark("first post!"); - - final SharedLog logLevel2a = logTop.forSubComponent("twoA"); - final SharedLog logLevel2b = logTop.forSubComponent("twoB"); - logLevel2b.e("2b or not 2b"); - logLevel2b.e("No exception", null); - logLevel2b.e("Wait, here's one", new Exception("Test")); - logLevel2a.w("second post?"); - - final SharedLog logLevel3 = logLevel2a.forSubComponent("three"); - logTop.log("still logging"); - logLevel3.log("3 >> 2"); - logLevel2a.mark("ok: last post"); - - final String[] expected = { - " - MARK first post!", - " - [twoB] ERROR 2b or not 2b", - " - [twoB] ERROR No exception", - // No stacktrace in shared log, only in logcat - " - [twoB] ERROR Wait, here's one: Test", - " - [twoA] WARN second post?", - " - still logging", - " - [twoA.three] 3 >> 2", - " - [twoA] MARK ok: last post", - }; - // Verify the logs are all there and in the correct order. - verifyLogLines(expected, logTop); - - // In fact, because they all share the same underlying LocalLog, - // every subcomponent SharedLog's dump() is identical. - verifyLogLines(expected, logLevel2a); - verifyLogLines(expected, logLevel2b); - verifyLogLines(expected, logLevel3); - } - - private static void verifyLogLines(String[] expected, SharedLog log) { - final ByteArrayOutputStream ostream = new ByteArrayOutputStream(); - final PrintWriter pw = new PrintWriter(ostream, true); - log.dump(null, pw, null); - - final String dumpOutput = ostream.toString(); - assertTrue(dumpOutput != null); - assertTrue(!"".equals(dumpOutput)); - - final String[] lines = dumpOutput.split("\n"); - assertEquals(expected.length, lines.length); - - for (int i = 0; i < expected.length; i++) { - String got = lines[i]; - String want = expected[i]; - assertTrue(String.format("'%s' did not contain '%s'", got, want), got.endsWith(want)); - assertTrue(String.format("'%s' did not contain a %s timestamp", got, TIMESTAMP), - got.replaceFirst(TIMESTAMP_PATTERN, TIMESTAMP).contains(TIMESTAMP)); - } - } -}