Snap for 8746144 from 19e420b2000ce979db0b6dbd9c4326f9ed8878bf to mainline-conscrypt-release Change-Id: Ie9ca2a4b1d29f75c9f76f1f75cad735dba812e08
diff --git a/Android.bp b/Android.bp index 7fcd206..4b3d558 100644 --- a/Android.bp +++ b/Android.bp
@@ -181,7 +181,6 @@ "framework-connectivity", "framework-connectivity-t.stubs.module_lib", "framework-tethering", - "android.net.ipsec.ike.stubs.module_lib", ], sdk_version: module_33_version, visibility: ["//visibility:private"], @@ -209,7 +208,6 @@ "framework-connectivity", "framework-connectivity-t.stubs.module_lib", "framework-tethering", - "android.net.ipsec.ike.stubs.module_lib", ], sdk_version: "module_current", visibility: ["//visibility:private"],
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index ad6c2b5..d616750 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml
@@ -19,8 +19,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.networkstack" android:sharedUserId="android.uid.networkstack" - android:versionCode="319999900" - android:versionName="s_aml_319999900" + android:versionCode="339990000" + android:versionName="339990000" coreApp="true" > <!--- Defines the MAINLINE_NETWORK_STACK permission used by the networkstack process. -->
diff --git a/AndroidManifest_Next.xml b/AndroidManifest_Next.xml index 244d465..200a921 100644 --- a/AndroidManifest_Next.xml +++ b/AndroidManifest_Next.xml
@@ -17,7 +17,7 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.networkstack" android:sharedUserId="android.uid.networkstack" - android:versionCode="320000000" + android:versionCode="339990000" android:versionName="T-next" coreApp="true"> </manifest>
diff --git a/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java b/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java deleted file mode 100644 index 2f5fb7d..0000000 --- a/apishim/29/com/android/networkstack/apishim/api29/EthernetManagerShimImpl.java +++ /dev/null
@@ -1,39 +0,0 @@ -/* - * 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. - */ - -package com.android.networkstack.apishim.api29; - -import android.content.Context; -import android.os.Build; - -import androidx.annotation.RequiresApi; - -import com.android.networkstack.apishim.common.EthernetManagerShim; - -/** - * Implementation of {@link EthernetManagerShim} for API 29. - * - * Cannot actually import EthernetManager because that only became @SystemApi in API 30. - */ -@RequiresApi(Build.VERSION_CODES.Q) -public class EthernetManagerShimImpl implements EthernetManagerShim { - /** - * Get a new instance of {@link EthernetManagerShim}. - */ - public static EthernetManagerShim newInstance(Context context) { - return new EthernetManagerShimImpl(); - } -}
diff --git a/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java b/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java deleted file mode 100644 index 2c93d7c..0000000 --- a/apishim/31/com/android/networkstack/apishim/api31/EthernetManagerShimImpl.java +++ /dev/null
@@ -1,48 +0,0 @@ -/* - * 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. - */ - -package com.android.networkstack.apishim.api31; - -import static com.android.modules.utils.build.SdkLevel.isAtLeastS; - -import android.content.Context; -import android.os.Build; - -import androidx.annotation.RequiresApi; - -import com.android.networkstack.apishim.common.EthernetManagerShim; - -/** - * Implementation of {@link EthernetManagerShim} for API 31. - * - * Doesn't have any methods, but must exist because the stable shim API level is currently 31. - * TODO: delete when the stable shim API level becomes 33. - */ -@RequiresApi(Build.VERSION_CODES.S) -public class EthernetManagerShimImpl - extends com.android.networkstack.apishim.api29.EthernetManagerShimImpl { - /** - * Get a new instance of {@link EthernetManagerShim}. - */ - @RequiresApi(Build.VERSION_CODES.Q) - public static EthernetManagerShim newInstance(Context context) { - if (!isAtLeastS()) { - return com.android.networkstack.apishim.api29.EthernetManagerShimImpl - .newInstance(context); - } - return new EthernetManagerShimImpl(); - } -}
diff --git a/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java b/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java deleted file mode 100644 index 5bd6487..0000000 --- a/apishim/33/com/android/networkstack/apishim/api33/EthernetManagerShimImpl.java +++ /dev/null
@@ -1,105 +0,0 @@ -/* - * 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. - */ - -package com.android.networkstack.apishim.api33; - -import static com.android.modules.utils.build.SdkLevel.isAtLeastT; - -import android.content.Context; -import android.net.EthernetManager; -import android.os.Build; - -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; - -import com.android.networkstack.apishim.common.EthernetManagerShim; - -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; - -/** - * Implementation of {@link EthernetManagerShim} for API 33. - */ -@RequiresApi(Build.VERSION_CODES.TIRAMISU) -public class EthernetManagerShimImpl - extends com.android.networkstack.apishim.api31.EthernetManagerShimImpl { - - protected final EthernetManager mEm; - - // This is needed because callers of the shim cannot use EthernetManager.InterfaceStateListener, - // they need to use EthernetManagerShim.InterfaceStateListener instead. But when actually - // registering a callback, the callback type passed to EthernetManager must be a real - // listener, not a shim. This map keeps track of the mapping between the two objects so that - // when a caller calls removeInterfaceStateListener with a shim listener, this class knows what - // real listener to pass to EthernetManager. - private final ConcurrentHashMap<InterfaceStateListener, EthernetManager.InterfaceStateListener> - mListeners = new ConcurrentHashMap<>(); - - protected EthernetManagerShimImpl(Context context) { - mEm = context.getSystemService(EthernetManager.class); - } - - /** - * Get a new instance of {@link EthernetManagerShim}. - */ - @RequiresApi(Build.VERSION_CODES.Q) - public static EthernetManagerShim newInstance(Context context) { - if (!isAtLeastT()) { - return com.android.networkstack.apishim.api31.EthernetManagerShimImpl - .newInstance(context); - } - return new EthernetManagerShimImpl(context); - } - - @Override - public void addInterfaceStateListener(@NonNull Executor executor, - @NonNull InterfaceStateListener listener) { - final EthernetManager.InterfaceStateListener wrapper = (a, b, c, d) -> { - listener.onInterfaceStateChanged(a, b, c, d); - }; - // EthernetManager#addInterfaceStateListener will allow registering the same listener twice, - // but this does not seem very useful and is difficult to support with the wrapper scheme - // used by this shim. Don't allow it. - final EthernetManager.InterfaceStateListener existing = - mListeners.putIfAbsent(listener, wrapper); - if (existing != null) { - throw new IllegalStateException("Attempt to register duplicate listener"); - } - mEm.addInterfaceStateListener(executor, wrapper); - } - - @Override - public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) { - final EthernetManager.InterfaceStateListener wrapper = mListeners.remove(listener); - if (wrapper != null) { - mEm.removeInterfaceStateListener(wrapper); - } - } - - @Override - // This method existed in R and S, but as @TestApi, so should not appear in the shims before T - // because otherwise it could be used by production code on R and S. - public void setIncludeTestInterfaces(boolean include) { - mEm.setIncludeTestInterfaces(include); - } - - @Override - @NonNull - public List<String> getInterfaceList() { - return mEm.getInterfaceList(); - } -}
diff --git a/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java b/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java deleted file mode 100644 index e9a33a1..0000000 --- a/apishim/34/com/android/networkstack/apishim/EthernetManagerShimImpl.java +++ /dev/null
@@ -1,36 +0,0 @@ -/* - * 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. - */ - -package com.android.networkstack.apishim; - -import android.content.Context; -import android.os.Build; - -import androidx.annotation.RequiresApi; - -import com.android.networkstack.apishim.common.EthernetManagerShim; - -/** - * Implementation of {@link EthernetManagerShim} for API 34. - */ -// TODO: when available in all active branches: @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) -@RequiresApi(Build.VERSION_CODES.CUR_DEVELOPMENT) -public class EthernetManagerShimImpl - extends com.android.networkstack.apishim.api33.EthernetManagerShimImpl { - protected EthernetManagerShimImpl(Context context) { - super(context); - } -}
diff --git a/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java b/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java deleted file mode 100644 index 02a08de..0000000 --- a/apishim/common/com/android/networkstack/apishim/common/EthernetManagerShim.java +++ /dev/null
@@ -1,63 +0,0 @@ -/* - * 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. - */ - -package com.android.networkstack.apishim.common; - -import android.net.IpConfiguration; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.List; -import java.util.concurrent.Executor; - -/** API shim for EthernetManager */ -public interface EthernetManagerShim { - int STATE_ABSENT = 0; - int STATE_LINK_DOWN = 1; - int STATE_LINK_UP = 2; - int ROLE_NONE = 0; - int ROLE_CLIENT = 1; - int ROLE_SERVER = 2; - - /** Shim for EthernetManager#InterfaceStateListener. */ - interface InterfaceStateListener { - void onInterfaceStateChanged(@NonNull String iface, int state, int role, - @Nullable IpConfiguration configuration); - } - - /** Shim for EthernetManager#addInterfaceStateListener */ - default void addInterfaceStateListener(@NonNull Executor executor, - @NonNull InterfaceStateListener listener) throws UnsupportedApiLevelException { - throw new UnsupportedApiLevelException(); - } - - /** Shim for EthernetManager#removeInterfaceStateListener */ - default void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) - throws UnsupportedApiLevelException { - throw new UnsupportedApiLevelException("Not supported until API 33"); - } - - /** Shim for EthernetManager#setIncludeTestInterfaces */ - default void setIncludeTestInterfaces(boolean include) throws UnsupportedApiLevelException { - throw new UnsupportedApiLevelException("Not supported until API 30"); - } - - /** Shim for EthernetManager#getInterfaceList */ - default List<String> getInterfaceList() throws UnsupportedApiLevelException { - throw new UnsupportedApiLevelException("Not supported until API 33"); - } -}
diff --git a/common/moduleutils/src/android/net/ip/NetlinkMonitor.java b/common/moduleutils/src/android/net/ip/NetlinkMonitor.java index 17157d8..e58b44e 100644 --- a/common/moduleutils/src/android/net/ip/NetlinkMonitor.java +++ b/common/moduleutils/src/android/net/ip/NetlinkMonitor.java
@@ -18,6 +18,7 @@ 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; @@ -101,7 +102,11 @@ try { fd = Os.socket(AF_NETLINK, SOCK_DGRAM | SOCK_NONBLOCK, mFamily); if (mSockRcvbufSize != DEFAULT_SOCKET_RECV_BUFSIZE) { - Os.setsockoptInt(fd, SOL_SOCKET, SO_RCVBUF, mSockRcvbufSize); + 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); @@ -147,6 +152,32 @@ } } + @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 {
diff --git a/common/networkstackclient/Android.bp b/common/networkstackclient/Android.bp index 53477ac..c363a2b 100644 --- a/common/networkstackclient/Android.bp +++ b/common/networkstackclient/Android.bp
@@ -194,7 +194,6 @@ ], static_libs: [ "networkstack-aidl-latest", - "modules-utils-build", ], visibility: [ "//frameworks/base/packages/Connectivity/service", @@ -205,10 +204,12 @@ "//packages/apps/Bluetooth", "//packages/modules/Bluetooth/android/app", "//packages/modules/NetworkStack", + "//packages/modules/Wifi/service", ], apex_available: [ "//apex_available:platform", "com.android.bluetooth", "com.android.tethering", + "com.android.wifi", ], }
diff --git a/common/networkstackclient/src/android/net/NetworkMonitorManager.java b/common/networkstackclient/src/android/net/NetworkMonitorManager.java index 98598a1..c39c684 100644 --- a/common/networkstackclient/src/android/net/NetworkMonitorManager.java +++ b/common/networkstackclient/src/android/net/NetworkMonitorManager.java
@@ -23,8 +23,6 @@ import android.os.RemoteException; import android.util.Log; -import com.android.modules.utils.build.SdkLevel; - /** * A convenience wrapper for INetworkMonitor. * @@ -150,15 +148,25 @@ } } + // This should not be called starting from S + @Deprecated + public boolean notifyNetworkConnected(LinkProperties lp, NetworkCapabilities nc) { + final long token = Binder.clearCallingIdentity(); + try { + mNetworkMonitor.notifyNetworkConnected(lp, nc); + return true; + } catch (RemoteException e) { + log("Error in notifyNetworkConnected", e); + return false; + } finally { + Binder.restoreCallingIdentity(token); + } + } + public boolean notifyNetworkConnected(NetworkMonitorParameters params) { final long token = Binder.clearCallingIdentity(); try { - if (SdkLevel.isAtLeastT()) { - mNetworkMonitor.notifyNetworkConnectedParcel(params); - } else { - mNetworkMonitor.notifyNetworkConnected(params.linkProperties, - params.networkCapabilities); - } + mNetworkMonitor.notifyNetworkConnectedParcel(params); return true; } catch (RemoteException e) { log("Error in notifyNetworkConnected", e);
diff --git a/src/android/net/dhcp/DhcpInformPacket.java b/src/android/net/dhcp/DhcpInformPacket.java deleted file mode 100644 index 135b8f6..0000000 --- a/src/android/net/dhcp/DhcpInformPacket.java +++ /dev/null
@@ -1,62 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.dhcp; - -import java.net.Inet4Address; -import java.nio.ByteBuffer; - -/** - * This class implements the (unused) DHCP-INFORM packet. - */ -public class DhcpInformPacket extends DhcpPacket { - /** - * Generates an INFORM packet with the specified parameters. - */ - DhcpInformPacket(int transId, short secs, Inet4Address clientIp, Inet4Address yourIp, - Inet4Address nextIp, Inet4Address relayIp, - byte[] clientMac) { - super(transId, secs, clientIp, yourIp, nextIp, relayIp, clientMac, false); - } - - public String toString() { - String s = super.toString(); - return s + " INFORM"; - } - - /** - * Builds an INFORM packet. - */ - public ByteBuffer buildPacket(int encap, short destUdp, short srcUdp) { - ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH); - - fillInPacket(encap, mClientIp, mYourIp, destUdp, srcUdp, result, - DHCP_BOOTREQUEST, false); - result.flip(); - return result; - } - - /** - * Adds additional parameters to the INFORM packet. - */ - void finishPacket(ByteBuffer buffer) { - addTlv(buffer, DHCP_MESSAGE_TYPE, DHCP_MESSAGE_TYPE_INFORM); - addTlv(buffer, DHCP_CLIENT_IDENTIFIER, getClientId()); - addCommonClientTlvs(buffer); - addTlv(buffer, DHCP_PARAMETER_LIST, mRequestedParams); - addTlvEnd(buffer); - } -}
diff --git a/src/android/net/dhcp/DhcpPacket.java b/src/android/net/dhcp/DhcpPacket.java index 63c5b0c..7dc1b99 100644 --- a/src/android/net/dhcp/DhcpPacket.java +++ b/src/android/net/dhcp/DhcpPacket.java
@@ -1346,11 +1346,6 @@ newPacket = new DhcpReleasePacket( transactionId, serverIdentifier, clientIp, relayIp, clientMac); break; - case DHCP_MESSAGE_TYPE_INFORM: - newPacket = new DhcpInformPacket( - transactionId, secs, clientIp, yourIp, nextIp, relayIp, - clientMac); - break; default: throw new ParseException(DhcpErrorEvent.DHCP_UNKNOWN_MSG_TYPE, "Unimplemented DHCP type %d", dhcpType);
diff --git a/src/android/net/ip/IpClientLinkObserver.java b/src/android/net/ip/IpClientLinkObserver.java index f0126e6..bebe7c9 100644 --- a/src/android/net/ip/IpClientLinkObserver.java +++ b/src/android/net/ip/IpClientLinkObserver.java
@@ -45,6 +45,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.InterfaceParams; import com.android.net.module.util.netlink.NduseroptMessage; import com.android.net.module.util.netlink.NetlinkConstants; @@ -160,7 +161,14 @@ // This must match the interface prefix in clatd.c. // TODO: Revert this hack once IpClient and Nat464Xlat work in concert. protected static final String CLAT_PREFIX = "v4-"; - private static final boolean DBG = false; + private static final boolean DBG = true; + + // The default socket receive buffer size in bytes(4MB). If too many netlink messages are + // sent too quickly, those messages can overflow the socket receive buffer. Set a large-enough + // recv buffer size to avoid the ENOBUFS as much as possible. + @VisibleForTesting + static final String CONFIG_SOCKET_RECV_BUFSIZE = "ipclient_netlink_sock_recv_buf_size"; + private static final int SOCKET_RECV_BUFSIZE = 4 * 1024 * 1024; public IpClientLinkObserver(Context context, Handler h, String iface, Callback callback, Configuration config, SharedLog log, IpClient.Dependencies deps) { @@ -178,7 +186,11 @@ mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); mDependencies = deps; mNetlinkMonitor = new MyNetlinkMonitor(h, log, mTag); - mHandler.post(mNetlinkMonitor::start); + mHandler.post(() -> { + if (!mNetlinkMonitor.start()) { + Log.wtf(mTag, "Fail to start NetlinkMonitor."); + } + }); } public void shutdown() { @@ -207,6 +219,15 @@ isAtLeastT() /* default value */); } + private int getSocketReceiveBufferSize() { + final int size = mDependencies.getDeviceConfigPropertyInt(CONFIG_SOCKET_RECV_BUFSIZE, + SOCKET_RECV_BUFSIZE /* default value */); + if (size < 0) { + throw new IllegalArgumentException("Invalid SO_RCVBUF " + size); + } + return size; + } + @Override public void onInterfaceAdded(String iface) { if (isNetlinkEventParsingEnabled()) return; @@ -279,10 +300,10 @@ } private void updateInterfaceDnsServerInfo(long lifetime, final String[] addresses) { - maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses)); final boolean changed = mDnsServerRepository.addServers(lifetime, addresses); final boolean linkState; if (changed) { + maybeLog("interfaceDnsServerInfo", Arrays.toString(addresses)); synchronized (this) { mDnsServerRepository.setDnsServersOn(mLinkProperties); linkState = getInterfaceLinkStateLocked(); @@ -291,7 +312,7 @@ } } - private void updateInterfaceAddress(@NonNull final LinkAddress address, boolean add) { + private boolean updateInterfaceAddress(@NonNull final LinkAddress address, boolean add) { final boolean changed; final boolean linkState; synchronized (this) { @@ -309,9 +330,10 @@ mCallback.onIpv6AddressRemoved(addr); } } + return changed; } - private void updateInterfaceRoute(final RouteInfo route, boolean add) { + private boolean updateInterfaceRoute(final RouteInfo route, boolean add) { final boolean changed; final boolean linkState; synchronized (this) { @@ -325,6 +347,7 @@ if (changed) { mCallback.update(linkState); } + return changed; } private void updateInterfaceRemoved() { @@ -400,11 +423,12 @@ MyNetlinkMonitor(Handler h, SharedLog log, String tag) { super(h, log, tag, OsConstants.NETLINK_ROUTE, !isNetlinkEventParsingEnabled() - ? NetlinkConstants.RTMGRP_ND_USEROPT - : (NetlinkConstants.RTMGRP_ND_USEROPT | NetlinkConstants.RTMGRP_LINK - | NetlinkConstants.RTMGRP_IPV4_IFADDR - | NetlinkConstants.RTMGRP_IPV6_IFADDR - | NetlinkConstants.RTMGRP_IPV6_ROUTE)); + ? NetlinkConstants.RTMGRP_ND_USEROPT + : (NetlinkConstants.RTMGRP_ND_USEROPT | NetlinkConstants.RTMGRP_LINK + | NetlinkConstants.RTMGRP_IPV4_IFADDR + | NetlinkConstants.RTMGRP_IPV6_IFADDR + | NetlinkConstants.RTMGRP_IPV6_ROUTE), + getSocketReceiveBufferSize()); mHandler = h; } @@ -423,6 +447,9 @@ private int mIfindex; void setIfindex(int ifindex) { + if (!isRunning()) { + Log.wtf(mTag, "NetlinkMonitor is not running when setting interface parameter!"); + } mIfindex = ifindex; } @@ -602,12 +629,14 @@ switch (msg.getHeader().nlmsg_type) { case NetlinkConstants.RTM_NEWADDR: - maybeLog("addressUpdated", mIfindex, la); - updateInterfaceAddress(la, true /* add address */); + if (updateInterfaceAddress(la, true /* add address */)) { + maybeLog("addressUpdated", mIfindex, la); + } break; case NetlinkConstants.RTM_DELADDR: - maybeLog("addressRemoved", mIfindex, la); - updateInterfaceAddress(la, false /* remove address */); + if (updateInterfaceAddress(la, false /* remove address */)) { + maybeLog("addressRemoved", mIfindex, la); + } break; default: Log.e(mTag, "Unknown rtnetlink address msg type " + msg.getHeader().nlmsg_type); @@ -632,12 +661,14 @@ mInterfaceName, msg.getRtMsgHeader().type); switch (msg.getHeader().nlmsg_type) { case NetlinkConstants.RTM_NEWROUTE: - maybeLog("routeUpdated", route); - updateInterfaceRoute(route, true /* add route */); + if (updateInterfaceRoute(route, true /* add route */)) { + maybeLog("routeUpdated", route); + } break; case NetlinkConstants.RTM_DELROUTE: - maybeLog("routeRemoved", route); - updateInterfaceRoute(route, false /* remove route */); + if (updateInterfaceRoute(route, false /* remove route */)) { + maybeLog("routeRemoved", route); + } break; default: Log.e(mTag, "Unknown rtnetlink route msg type " + msg.getHeader().nlmsg_type);
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp index 9984a54..2bf0529 100644 --- a/tests/integration/Android.bp +++ b/tests/integration/Android.bp
@@ -36,8 +36,8 @@ name: "NetworkStackIntegrationTestsDefaults", defaults: ["framework-connectivity-test-defaults"], srcs: [ - "src/**/*.java", - "src/**/*.kt", + "common/**/*.java", + "common/**/*.kt", ], static_libs: [ "androidx.annotation_annotation", @@ -57,6 +57,10 @@ android_library { name: "NetworkStackIntegrationTestsLib", defaults: ["NetworkStackIntegrationTestsDefaults"], + srcs: [ + "signature/**/*.java", + "signature/**/*.kt", + ], min_sdk_version: "29", static_libs: [ "NetworkStackApiStableLib", @@ -84,6 +88,10 @@ "NetworkStackIntegrationTestsJniDefaults", "ConnectivityNextEnableDefaults", ], + srcs: [ + "signature/**/*.java", + "signature/**/*.kt", + ], static_libs: [ "NetworkStackApiCurrentLib", ], @@ -93,6 +101,26 @@ jarjar_rules: ":NetworkStackJarJarRules", } +// Network stack integration root tests. +android_test { + name: "NetworkStackRootTests", + defaults: [ + "NetworkStackIntegrationTestsDefaults", + "NetworkStackIntegrationTestsJniDefaults", + ], + srcs: [ + "root/**/*.java", + "root/**/*.kt", + ], + static_libs: [ + "NetworkStackApiCurrentLib", + ], + platform_apis: true, + test_suites: ["general-tests", "mts-networking"], + manifest: "AndroidManifest_root.xml", + jarjar_rules: ":NetworkStackJarJarRules", +} + // Special version of the network stack tests that includes all tests necessary for code coverage // purposes. This is currently the union of NetworkStackTests and NetworkStackIntegrationTests. android_test { @@ -101,7 +129,7 @@ platform_apis: true, min_sdk_version: "29", target_sdk_version: "30", - test_suites: ["device-tests", "mts"], + test_suites: ["device-tests", "mts-networking"], test_config: "AndroidTest_Coverage.xml", defaults: ["NetworkStackIntegrationTestsJniDefaults"], static_libs: [
diff --git a/tests/integration/AndroidManifest_root.xml b/tests/integration/AndroidManifest_root.xml new file mode 100644 index 0000000..02b82c5 --- /dev/null +++ b/tests/integration/AndroidManifest_root.xml
@@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.server.networkstack.roottests"> + + <application android:debuggable="true"> + <uses-library android:name="android.test.runner" /> + </application> + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="com.android.server.networkstack.roottests" + android:label="Networking stack integration root tests"> + </instrumentation> +</manifest>
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java similarity index 97% rename from tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java rename to tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java index 78d0bca..959b0b7 100644 --- a/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java +++ b/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java
@@ -29,6 +29,7 @@ import static android.net.dhcp.DhcpPacket.MIN_V6ONLY_WAIT_MS; import static android.net.dhcp.DhcpResultsParcelableUtil.fromStableParcelable; import static android.net.ip.IpClientLinkObserver.CLAT_PREFIX; +import static android.net.ip.IpClientLinkObserver.CONFIG_SOCKET_RECV_BUFSIZE; import static android.net.ip.IpReachabilityMonitor.MIN_NUD_SOLICIT_NUM; import static android.net.ip.IpReachabilityMonitor.NUD_MCAST_RESOLICIT_NUM; import static android.net.ip.IpReachabilityMonitor.nudEventTypeToInt; @@ -552,10 +553,10 @@ protected abstract void assertIpMemoryNeverStoreNetworkAttributes(String l2Key, long timeout); protected final boolean testSkipped() { - // TODO: split out a test suite for root tests, and fail hard instead of skipping the test - // if it is run on devices where TestNetworkStackServiceClient is not supported - return !useNetworkStackSignature() - && (mIsSignatureRequiredTest || !TestNetworkStackServiceClient.isSupported()); + if (!useNetworkStackSignature() && !TestNetworkStackServiceClient.isSupported()) { + fail("Device running root tests doesn't support TestNetworkStackServiceClient."); + } + return !useNetworkStackSignature() && mIsSignatureRequiredTest; } protected void setDhcpFeatures(final boolean isDhcpLeaseCacheEnabled, @@ -632,6 +633,11 @@ mDependencies.setDeviceConfigProperty(DhcpClient.ARP_PROBE_MAX_MS, 20); mDependencies.setDeviceConfigProperty(DhcpClient.ARP_FIRST_ANNOUNCE_DELAY_MS, 10); mDependencies.setDeviceConfigProperty(DhcpClient.ARP_ANNOUNCE_INTERVAL_MS, 10); + + // Set the initial netlink socket receive buffer size to a minimum of 100KB to ensure test + // cases are still working, meanwhile in order to easily overflow the receive buffer by + // sending as few RAs as possible for test case where it's used to verify ENOBUFS. + mDependencies.setDeviceConfigProperty(CONFIG_SOCKET_RECV_BUFSIZE, 100 * 1024); } private void awaitIpClientShutdown() throws Exception { @@ -1657,13 +1663,16 @@ private void sendRouterAdvertisement(boolean waitForRs, short lifetime) throws Exception { final String dnsServer = "2001:4860:4860::64"; final ByteBuffer pio = buildPioOption(3600, 1800, "2001:db8:1::/64"); - ByteBuffer rdnss = buildRdnssOption(3600, dnsServer); - ByteBuffer ra = buildRaPacket(lifetime, pio, rdnss); + final ByteBuffer rdnss = buildRdnssOption(3600, dnsServer); + sendRouterAdvertisement(waitForRs, lifetime, pio, rdnss); + } + private void sendRouterAdvertisement(boolean waitForRs, short lifetime, + ByteBuffer... options) throws Exception { + final ByteBuffer ra = buildRaPacket(lifetime, options); if (waitForRs) { waitForRouterSolicitation(); } - mPacketReader.sendResponse(ra); } @@ -3764,7 +3773,10 @@ ); } + // Since createTapInterface(boolean, String) method was introduced since T, this method + // cannot be found on Q/R/S platform, ignore this test on T- platform. @Test + @IgnoreUpTo(Build.VERSION_CODES.S_V2) public void testIpClientLinkObserver_onClatInterfaceStateUpdate() throws Exception { ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() .withoutIPv4() @@ -3784,4 +3796,59 @@ removeTestInterface(clatIface.getFileDescriptor().getFileDescriptor()); verify(mCb, timeout(TEST_TIMEOUT_MS)).setNeighborDiscoveryOffload(true); } + + @Test @SignatureRequiredTest(reason = "requires mock callback object") + public void testNetlinkSocketReceiveENOBUFS() throws Exception { + // Only run the test when the flag of parsing netlink events is enabled. + assumeTrue(mIsNetlinkEventParseEnabled); + + ProvisioningConfiguration config = new ProvisioningConfiguration.Builder() + .withoutIPv4() + .build(); + startIpClientProvisioning(config); + doIpv6OnlyProvisioning(); + HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS); + + final Handler handler = mIpc.getHandler(); + // Block IpClient handler. + final CountDownLatch latch = new CountDownLatch(1); + handler.post(() -> { + try { + latch.await(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + fail("latch wait unexpectedly interrupted"); + } + }); + + // Send large amount of RAs to overflow the netlink socket receive buffer. + for (int i = 0; i < 100; i++) { + sendBasicRouterAdvertisement(false /* waitRs */); + } + + // Send another RA with a different IPv6 global prefix. This PIO option should be dropped + // due to the ENOBUFS happens, it means IpClient shouldn't see the new IPv6 global prefix. + final String dnsServer = "2001:4860:4860::64"; + final String prefix = "2001:db8:dead:beef::/64"; + final ByteBuffer pio = buildPioOption(3600, 1800, prefix); + ByteBuffer rdnss = buildRdnssOption(3600, dnsServer); + sendRouterAdvertisement(false /* waitForRs */, (short) 1800, pio, rdnss); + + // Unblock the IpClient handler and ENOBUFS should happen then. + latch.countDown(); + HandlerUtils.waitForIdle(handler, TEST_TIMEOUT_MS); + + reset(mCb); + + // Send RA with 0 router lifetime to see if IpClient can see the loss of IPv6 default route. + // Due to ignoring the ENOBUFS and wait until handler gets idle, IpClient should be still + // able to see the RA with 0 router lifetime and the IPv6 default route will be removed. + // LinkProperties should not include any route to the new prefix 2001:db8:dead:beef::/64. + sendRouterAdvertisementWithZeroLifetime(); + final ArgumentCaptor<LinkProperties> captor = ArgumentCaptor.forClass(LinkProperties.class); + verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(captor.capture()); + final LinkProperties lp = captor.getValue(); + assertNotNull(lp); + assertFalse(hasRouteTo(lp, prefix)); + assertFalse(lp.hasIpv6DefaultRoute()); + } }
diff --git a/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt b/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt similarity index 99% rename from tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt rename to tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt index 47936ac..9f5e5e7 100644 --- a/tests/integration/src/android/net/networkstack/TestNetworkStackServiceClient.kt +++ b/tests/integration/common/android/net/networkstack/TestNetworkStackServiceClient.kt
@@ -78,4 +78,4 @@ fun disconnect() { InstrumentationRegistry.getInstrumentation().context.unbindService(serviceConnection) } -} \ No newline at end of file +}
diff --git a/tests/integration/lint-baseline.xml b/tests/integration/lint-baseline.xml index eadec6f..1868549 100644 --- a/tests/integration/lint-baseline.xml +++ b/tests/integration/lint-baseline.xml
@@ -7,8 +7,8 @@ errorLine1=" assertEquals(SERVER_ADDR, captor.getValue().getDhcpServerAddress());" errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> <location - file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java" - line="1327" + file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java" + line="1513" column="53"/> </issue> @@ -18,8 +18,8 @@ errorLine1=" argThat(lp -> Objects.equals(expected, lp.getNat64Prefix())));" errorLine2=" ~~~~~~~~~~~~~~"> <location - file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java" - line="1623" + file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java" + line="1836" column="59"/> </issue> @@ -29,8 +29,8 @@ errorLine1=" lp -> !Objects.equals(unchanged, lp.getNat64Prefix())));" errorLine2=" ~~~~~~~~~~~~~~"> <location - file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java" - line="1629" + file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java" + line="1842" column="53"/> </issue> @@ -40,8 +40,8 @@ errorLine1=" if (lp.getNat64Prefix() != null) {" errorLine2=" ~~~~~~~~~~~~~~"> <location - file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java" - line="1660" + file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java" + line="1873" column="16"/> </issue> @@ -51,8 +51,8 @@ errorLine1=" assertEquals(prefix, lp.getNat64Prefix());" errorLine2=" ~~~~~~~~~~~~~~"> <location - file="packages/modules/NetworkStack/tests/integration/src/android/net/ip/IpClientIntegrationTestCommon.java" - line="1661" + file="packages/modules/NetworkStack/tests/integration/common/android/net/ip/IpClientIntegrationTestCommon.java" + line="1874" column="37"/> </issue>
diff --git a/tests/integration/src/android/net/ip/IpClientRootTest.kt b/tests/integration/root/android/net/ip/IpClientRootTest.kt similarity index 100% rename from tests/integration/src/android/net/ip/IpClientRootTest.kt rename to tests/integration/root/android/net/ip/IpClientRootTest.kt
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt b/tests/integration/signature/android/net/ip/IpClientSignatureTest.kt similarity index 96% rename from tests/integration/src/android/net/ip/IpClientIntegrationTest.kt rename to tests/integration/signature/android/net/ip/IpClientSignatureTest.kt index fa379d3..c9e33b5 100644 --- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.kt +++ b/tests/integration/signature/android/net/ip/IpClientSignatureTest.kt
@@ -32,7 +32,7 @@ /** * Tests for IpClient, run with signature permissions. */ -class IpClientIntegrationTest : IpClientIntegrationTestCommon() { +class IpClientSignatureTest : IpClientIntegrationTestCommon() { private val mEnabledFeatures = ArrayMap<String, Boolean>() override fun makeIIpClient(ifaceName: String, cb: IIpClientCallbacks): IIpClient {
diff --git a/tests/integration/src/android/net/netlink/InetDiagSocketIntegrationTest.java b/tests/integration/signature/android/net/netlink/InetDiagSocketIntegrationTest.java similarity index 100% rename from tests/integration/src/android/net/netlink/InetDiagSocketIntegrationTest.java rename to tests/integration/signature/android/net/netlink/InetDiagSocketIntegrationTest.java
diff --git a/tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt b/tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt similarity index 100% rename from tests/integration/src/android/net/util/NetworkStackUtilsIntegrationTest.kt rename to tests/integration/signature/android/net/util/NetworkStackUtilsIntegrationTest.kt