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

Commit 3abcdcbf authored by Xiao Ma's avatar Xiao Ma Committed by Gerrit Code Review
Browse files

Merge "Prevent the potential NPE when toggling interface quickly."

parents 84ba8158 7dc8ef83
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
@@ -282,6 +282,7 @@ public class IpClientIntegrationTest {
        private DhcpClient mDhcpClient;
        private boolean mIsHostnameConfigurationEnabled;
        private String mHostname;
        private boolean mIsInterfaceRecovered;

        public void setDhcpLeaseCacheEnabled(final boolean enable) {
            mIsDhcpLeaseCacheEnabled = enable;
@@ -300,6 +301,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;
@@ -1232,6 +1250,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