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

Commit f78c3512 authored by Benedict Wong's avatar Benedict Wong
Browse files

Add/remove internal addresses from IpSecTunnelInterface

This change corrects a bug where IpSecTunnelInterface was not removing
old addresses, and resulted in EEXIST when trying to re-add an address
to a given interface.

Test: atest FrameworksVcnTests
Change-Id: I43434c801354483a7c7d0092891799bf86da23eb
parent 7d6b4907
Loading
Loading
Loading
Loading
+6 −10
Original line number Diff line number Diff line
@@ -1518,13 +1518,6 @@ public class VcnGatewayConnection extends StateMachine {
            }
        }

        protected void setupInterface(
                int token,
                @NonNull IpSecTunnelInterface tunnelIface,
                @NonNull VcnChildSessionConfiguration childConfig) {
            setupInterface(token, tunnelIface, childConfig, null);
        }

        protected void setupInterface(
                int token,
                @NonNull IpSecTunnelInterface tunnelIface,
@@ -1609,9 +1602,11 @@ public class VcnGatewayConnection extends StateMachine {
                            transformCreatedInfo.direction);
                    break;
                case EVENT_SETUP_COMPLETED:
                    final VcnChildSessionConfiguration oldChildConfig = mChildConfig;
                    mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig;

                    setupInterfaceAndNetworkAgent(mCurrentToken, mTunnelIface, mChildConfig);
                    setupInterfaceAndNetworkAgent(
                            mCurrentToken, mTunnelIface, mChildConfig, oldChildConfig);
                    break;
                case EVENT_DISCONNECT_REQUESTED:
                    handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
@@ -1655,8 +1650,9 @@ public class VcnGatewayConnection extends StateMachine {
        protected void setupInterfaceAndNetworkAgent(
                int token,
                @NonNull IpSecTunnelInterface tunnelIface,
                @NonNull VcnChildSessionConfiguration childConfig) {
            setupInterface(token, tunnelIface, childConfig);
                @NonNull VcnChildSessionConfiguration childConfig,
                @NonNull VcnChildSessionConfiguration oldChildConfig) {
            setupInterface(token, tunnelIface, childConfig, oldChildConfig);

            if (mNetworkAgent == null) {
                mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig);
+63 −4
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

import android.net.ConnectivityManager;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
@@ -60,8 +61,11 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/** Tests for VcnGatewayConnection.ConnectedState */
@@ -169,12 +173,14 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
    }

    private void triggerChildOpened() {
        triggerChildOpened(Collections.singletonList(TEST_INTERNAL_ADDR), TEST_DNS_ADDR);
    }

    private void triggerChildOpened(List<LinkAddress> internalAddresses, InetAddress dnsAddress) {
        final VcnChildSessionConfiguration mMockChildSessionConfig =
                mock(VcnChildSessionConfiguration.class);
        doReturn(Collections.singletonList(TEST_INTERNAL_ADDR))
                .when(mMockChildSessionConfig)
                .getInternalAddresses();
        doReturn(Collections.singletonList(TEST_DNS_ADDR))
        doReturn(internalAddresses).when(mMockChildSessionConfig).getInternalAddresses();
        doReturn(Collections.singletonList(dnsAddress))
                .when(mMockChildSessionConfig)
                .getInternalDnsServers();

@@ -248,6 +254,59 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
        assertFalse(mGatewayConnection.isInSafeMode());
    }

    @Test
    public void testInternalAndDnsAddressesChanged() throws Exception {
        final List<LinkAddress> startingInternalAddrs =
                Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR, TEST_INTERNAL_ADDR_2});
        triggerChildOpened(startingInternalAddrs, TEST_DNS_ADDR);
        mTestLooper.dispatchAll();

        for (LinkAddress addr : startingInternalAddrs) {
            verify(mIpSecSvc)
                    .addAddressToTunnelInterface(
                            eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any());
        }

        verify(mDeps)
                .newNetworkAgent(
                        any(),
                        any(),
                        any(),
                        argThat(
                                lp ->
                                        startingInternalAddrs.equals(lp.getLinkAddresses())
                                                && Collections.singletonList(TEST_DNS_ADDR)
                                                        .equals(lp.getDnsServers())),
                        anyInt(),
                        any(),
                        any(),
                        any(),
                        any());

        // Trigger another connection event, and verify that the addresses change
        final List<LinkAddress> newInternalAddrs =
                Arrays.asList(new LinkAddress[] {TEST_INTERNAL_ADDR_2, TEST_INTERNAL_ADDR_3});
        triggerChildOpened(newInternalAddrs, TEST_DNS_ADDR_2);
        mTestLooper.dispatchAll();

        // Verify addresses on tunnel network added/removed
        for (LinkAddress addr : newInternalAddrs) {
            verify(mIpSecSvc)
                    .addAddressToTunnelInterface(
                            eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(addr), any());
        }
        verify(mIpSecSvc)
                .removeAddressFromTunnelInterface(
                        eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_INTERNAL_ADDR), any());

        // TODO(b/184579891): Also verify link properties updated and sent when sendLinkProperties
        // is mockable

        // Verify that IpSecTunnelInterface only created once
        verify(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any());
        verifyNoMoreInteractions(mIpSecSvc);
    }

    @Test
    public void testSuccessfulConnectionExitsSafeMode() throws Exception {
        verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent(
+7 −1
Original line number Diff line number Diff line
@@ -74,8 +74,14 @@ public class VcnGatewayConnectionTestBase {
    protected static final ParcelUuid TEST_SUB_GRP = new ParcelUuid(UUID.randomUUID());
    protected static final InetAddress TEST_DNS_ADDR =
            InetAddresses.parseNumericAddress("2001:DB8:0:1::");
    protected static final InetAddress TEST_DNS_ADDR_2 =
            InetAddresses.parseNumericAddress("2001:DB8:0:2::");
    protected static final LinkAddress TEST_INTERNAL_ADDR =
            new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:0:2::"), 64);
            new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:1::"), 64);
    protected static final LinkAddress TEST_INTERNAL_ADDR_2 =
            new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:2::"), 64);
    protected static final LinkAddress TEST_INTERNAL_ADDR_3 =
            new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:3::"), 64);

    protected static final int TEST_IPSEC_SPI_VALUE = 0x1234;
    protected static final int TEST_IPSEC_SPI_RESOURCE_ID = 1;