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

Commit 48836ac9 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Automerger Merge Worker
Browse files

Don't crash if the PREF64 expires when IpClient is stopped. am: cf37ca43 am:...

Don't crash if the PREF64 expires when IpClient is stopped. am: cf37ca43 am: b451c135 am: 783bbb4d am: 6b1637c3

Change-Id: I1ae88ce951bba0f39aeadd0300cf9a453eba3bd9
parents 985a8c51 6b1637c3
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -238,6 +238,7 @@ public class IpClientLinkObserver implements NetworkObserver {
        // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in
        // mLinkProperties, as desired.
        mDnsServerRepository = new DnsServerRepository(mConfig.minRdnssLifetime);
        mNetlinkMonitor.clearAlarms();
        mLinkProperties.clear();
        mLinkProperties.setInterfaceName(mInterfaceName);
    }
@@ -281,18 +282,27 @@ public class IpClientLinkObserver implements NetworkObserver {
            mIfindex = ifindex;
        }

        void clearAlarms() {
            cancelPref64Alarm();
        }

        private final AlarmManager.OnAlarmListener mExpirePref64Alarm = () -> {
            // Ignore the alarm if cancelPref64Alarm has already been called.
            //
            // TODO: in the rare case where the alarm fires and posts the lambda to the handler
            // thread while we are processing an RA that changes the lifetime of the same prefix,
            // this code will run anyway even if the alarm is rescheduled or cancelled. If the
            // lifetime in the RA is zero this doesn't matter (we just harmlessly cancel the alarm
            // one extra time) but if the lifetime is nonzero then the prefix will be added and
            // immediately removed by this code.
            // lifetime in the RA is zero this code will correctly do nothing, but if the lifetime
            // is nonzero then the prefix will be added and immediately removed by this code.
            if (mNat64PrefixExpiry == 0) return;
            updatePref64(mShim.getNat64Prefix(mLinkProperties),
                    mNat64PrefixExpiry, mNat64PrefixExpiry);
        };

        private void cancelPref64Alarm() {
            // Clear the expiry in case the alarm just fired and has not been processed yet.
            if (mNat64PrefixExpiry == 0) return;
            mNat64PrefixExpiry = 0;
            mAlarmManager.cancel(mExpirePref64Alarm);
        }

@@ -342,7 +352,6 @@ public class IpClientLinkObserver implements NetworkObserver {
                schedulePref64Alarm();
            } else {
                mShim.setNat64Prefix(mLinkProperties, null);
                mNat64PrefixExpiry = 0;
                cancelPref64Alarm();
            }

+19 −0
Original line number Diff line number Diff line
@@ -1527,6 +1527,25 @@ public class IpClientIntegrationTest {
        mIpc.getHandler().post(() -> lastAlarm.onAlarm());
        expectAlarmCancelled(inOrder, pref64Alarm);
        expectNat64PrefixUpdate(inOrder, null);

        // Re-announce the prefix.
        pref64 = new StructNdOptPref64(prefix, 600).toByteBuffer();
        ra = buildRaPacket(pio, rdnss, pref64);
        mPacketReader.sendResponse(ra);
        final OnAlarmListener clearAlarm = expectAlarmSet(inOrder, "PREF64", 600);
        expectNat64PrefixUpdate(inOrder, prefix);
        reset(mCb, mAlarm);

        // Check that the alarm is cancelled when IpClient is stopped.
        mIpc.stop();
        HandlerUtilsKt.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
        expectAlarmCancelled(inOrder, clearAlarm);
        expectNat64PrefixUpdate(inOrder, null);

        // Check that even if the alarm was already in the message queue while it was cancelled, it
        // is safely ignored.
        mIpc.getHandler().post(() -> clearAlarm.onAlarm());
        HandlerUtilsKt.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
    }

    private void addIpAddressAndWaitForIt(final String iface) throws Exception {