Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c6b900e authored by Xiao Ma's avatar Xiao Ma Committed by Automerger Merge Worker
Browse files

Merge "Prevent the potential NPE when toggling interface quickly." am: 3abcdcbf am: ee827df7

Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/1398412

Change-Id: I6be879c834842d8633bab0d060ea120302ae0514
parents 55265b63 ee827df7
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -1583,7 +1583,11 @@ public class IpClient extends StateMachine {
            return;
        }

        if (params.index != mInterfaceParams.index) {
        // Check whether "mInterfaceParams" is null or not to prevent the potential NPE
        // introduced if the interface was initially not found, but came back before this
        // method was called. See b/162808916 for more details. TODO: query the new interface
        // parameters by the interface index instead and check that the index has not changed.
        if (mInterfaceParams == null || params.index != mInterfaceParams.index) {
            Log.w(mTag, "interface: " + mInterfaceName + " has a different index: " + params.index);
            return;
        }
+48 −0
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ public class IpClientIntegrationTest {
        private DhcpClient mDhcpClient;
        private boolean mIsHostnameConfigurationEnabled;
        private String mHostname;
        private boolean mIsInterfaceRecovered;

        public void setDhcpLeaseCacheEnabled(final boolean enable) {
            mIsDhcpLeaseCacheEnabled = enable;
@@ -299,6 +300,23 @@ public class IpClientIntegrationTest {
            mHostname = hostname;
        }

        // Enable this flag to simulate the interface has been added back after removing
        // on the provisioning start. However, the actual tap interface has been removed,
        // interface parameters query will get null when attempting to restore Interface
        // MTU. Create a new InterfaceParams instance and return instead just for interface
        // toggling test case.
        public void simulateInterfaceRecover() {
            mIsInterfaceRecovered = true;
        }

        @Override
        public InterfaceParams getInterfaceParams(String ifname) {
            return mIsInterfaceRecovered
                    ? new InterfaceParams(ifname, 1 /* index */,
                            MacAddress.fromString("00:11:22:33:44:55"))
                    : super.getInterfaceParams(ifname);
        }

        @Override
        public INetd getNetd(Context context) {
            return mNetd;
@@ -1231,6 +1249,36 @@ public class IpClientIntegrationTest {
        assertEquals(NetworkInterface.getByName(mIfaceName).getMTU(), TEST_DEFAULT_MTU);
    }

    @Test
    public void testRestoreInitialInterfaceMtu_removeInterfaceAndAddback() throws Exception {
        doAnswer(invocation -> {
            final LinkProperties lp = invocation.getArgument(0);
            assertEquals(lp.getInterfaceName(), mIfaceName);
            assertEquals(0, lp.getLinkAddresses().size());
            assertEquals(0, lp.getDnsServers().size());

            mDependencies.simulateInterfaceRecover();
            return null;
        }).when(mCb).onProvisioningFailure(any());

        final ProvisioningConfiguration config = new ProvisioningConfiguration.Builder()
                .withoutIpReachabilityMonitor()
                .withoutIPv6()
                .build();

        // Intend to remove the tap interface and force IpClient throw provisioning failure
        // due to that interface is not found.
        removeTapInterface(mTapFd);
        assertNull(InterfaceParams.getByName(mIfaceName));

        mIpc.startProvisioning(config);
        verify(mCb, timeout(TEST_TIMEOUT_MS)).onProvisioningFailure(any());

        // Make sure everything queued by this test was processed (e.g. transition to StoppingState
        // from ClearingIpAddressState) and tearDown will check if IpClient exits normally or crash.
        HandlerUtils.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
    }

    private boolean isRouterSolicitation(final byte[] packetBytes) {
        ByteBuffer packet = ByteBuffer.wrap(packetBytes);
        return packet.getShort(ETHER_TYPE_OFFSET) == (short) ETH_P_IPV6