diff options
5 files changed, 447 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/services/core/java/com/android/server/vcn/Vcn.java index 132883e4a041..fd19322cec7f 100644 --- a/services/core/java/com/android/server/vcn/Vcn.java +++ b/services/core/java/com/android/server/vcn/Vcn.java @@ -214,7 +214,8 @@ public class Vcn extends Handler { } /** Retrieves the network score for a VCN Network */ - private int getNetworkScore() { + // Package visibility for use in VcnGatewayConnection + static int getNetworkScore() { // TODO: STOPSHIP (b/173549607): Make this use new NetworkSelection, or some magic "max in // subGrp" value return 52; diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 39c96069f9c6..db372270fee2 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -17,8 +17,11 @@ package com.android.server.vcn; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.server.VcnManagementService.VDBG; @@ -34,8 +37,10 @@ import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkAgent; +import android.net.NetworkAgentConfig; import android.net.NetworkCapabilities; import android.net.RouteInfo; +import android.net.TelephonyNetworkSpecifier; import android.net.annotations.PolicyDirection; import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.ChildSessionConfiguration; @@ -47,10 +52,13 @@ import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.net.vcn.VcnGatewayConnectionConfig; +import android.net.vcn.VcnTransportInfo; +import android.net.wifi.WifiInfo; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Message; import android.os.ParcelUuid; +import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; @@ -64,6 +72,7 @@ import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; +import java.util.Arrays; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -113,6 +122,9 @@ import java.util.concurrent.TimeUnit; public class VcnGatewayConnection extends StateMachine { private static final String TAG = VcnGatewayConnection.class.getSimpleName(); + private static final int[] MERGED_CAPABILITIES = + new int[] {NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_NOT_ROAMING}; + private static final InetAddress DUMMY_ADDR = InetAddresses.parseNumericAddress("192.0.2.0"); private static final int ARG_NOT_PRESENT = Integer.MIN_VALUE; @@ -537,6 +549,8 @@ public class VcnGatewayConnection extends StateMachine { @Override public void onSelectedUnderlyingNetworkChanged( @Nullable UnderlyingNetworkRecord underlying) { + // TODO(b/179091925): Move the delayed-message handling to BaseState + // If underlying is null, all underlying networks have been lost. Disconnect VCN after a // timeout. if (underlying == null) { @@ -921,6 +935,8 @@ public class VcnGatewayConnection extends StateMachine { transitionTo(mDisconnectingState); break; case EVENT_SESSION_CLOSED: + // Disconnecting state waits for EVENT_SESSION_CLOSED to shutdown, and this + // message may not be posted again. Defer to ensure immediate shutdown. deferMessage(msg); transitionTo(mDisconnectingState); @@ -941,7 +957,108 @@ public class VcnGatewayConnection extends StateMachine { } } - private abstract class ConnectedStateBase extends ActiveBaseState {} + private abstract class ConnectedStateBase extends ActiveBaseState { + protected void updateNetworkAgent( + @NonNull IpSecTunnelInterface tunnelIface, + @NonNull NetworkAgent agent, + @NonNull ChildSessionConfiguration childConfig) { + final NetworkCapabilities caps = + buildNetworkCapabilities(mConnectionConfig, mUnderlying); + final LinkProperties lp = + buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig); + + agent.sendNetworkCapabilities(caps); + agent.sendLinkProperties(lp); + } + + protected NetworkAgent buildNetworkAgent( + @NonNull IpSecTunnelInterface tunnelIface, + @NonNull ChildSessionConfiguration childConfig) { + final NetworkCapabilities caps = + buildNetworkCapabilities(mConnectionConfig, mUnderlying); + final LinkProperties lp = + buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig); + + final NetworkAgent agent = + new NetworkAgent( + mVcnContext.getContext(), + mVcnContext.getLooper(), + TAG, + caps, + lp, + Vcn.getNetworkScore(), + new NetworkAgentConfig(), + mVcnContext.getVcnNetworkProvider()) { + @Override + public void unwanted() { + teardownAsynchronously(); + } + }; + + agent.register(); + agent.markConnected(); + + return agent; + } + + protected void applyTransform( + int token, + @NonNull IpSecTunnelInterface tunnelIface, + @NonNull Network underlyingNetwork, + @NonNull IpSecTransform transform, + int direction) { + try { + // TODO: Set underlying network of tunnel interface + + // Transforms do not need to be persisted; the IkeSession will keep them alive + mIpSecManager.applyTunnelModeTransform(tunnelIface, direction, transform); + } catch (IOException e) { + Slog.d(TAG, "Transform application failed for network " + token, e); + sessionLost(token, e); + } + } + + protected void setupInterface( + int token, + @NonNull IpSecTunnelInterface tunnelIface, + @NonNull ChildSessionConfiguration childConfig) { + setupInterface(token, tunnelIface, childConfig, null); + } + + protected void setupInterface( + int token, + @NonNull IpSecTunnelInterface tunnelIface, + @NonNull ChildSessionConfiguration childConfig, + @Nullable ChildSessionConfiguration oldChildConfig) { + try { + final Set<LinkAddress> newAddrs = + new ArraySet<>(childConfig.getInternalAddresses()); + final Set<LinkAddress> existingAddrs = new ArraySet<>(); + if (oldChildConfig != null) { + existingAddrs.addAll(oldChildConfig.getInternalAddresses()); + } + + final Set<LinkAddress> toAdd = new ArraySet<>(); + toAdd.addAll(newAddrs); + toAdd.removeAll(existingAddrs); + + final Set<LinkAddress> toRemove = new ArraySet<>(); + toRemove.addAll(existingAddrs); + toRemove.removeAll(newAddrs); + + for (LinkAddress address : toAdd) { + tunnelIface.addAddress(address.getAddress(), address.getPrefixLength()); + } + + for (LinkAddress address : toRemove) { + tunnelIface.removeAddress(address.getAddress(), address.getPrefixLength()); + } + } catch (IOException e) { + Slog.d(TAG, "Adding address to tunnel failed for token " + token, e); + sessionLost(token, e); + } + } + } /** * Stable state representing a VCN that has a functioning connection to the mobility anchor. @@ -951,7 +1068,89 @@ public class VcnGatewayConnection extends StateMachine { */ class ConnectedState extends ConnectedStateBase { @Override - protected void processStateMsg(Message msg) {} + protected void enterState() throws Exception { + // Successful connection, clear failed attempt counter + mFailedAttempts = 0; + } + + @Override + protected void processStateMsg(Message msg) { + switch (msg.what) { + case EVENT_UNDERLYING_NETWORK_CHANGED: + handleUnderlyingNetworkChanged(msg); + break; + case EVENT_SESSION_CLOSED: + // Disconnecting state waits for EVENT_SESSION_CLOSED to shutdown, and this + // message may not be posted again. Defer to ensure immediate shutdown. + deferMessage(msg); + transitionTo(mDisconnectingState); + break; + case EVENT_SESSION_LOST: + transitionTo(mDisconnectingState); + break; + case EVENT_TRANSFORM_CREATED: + final EventTransformCreatedInfo transformCreatedInfo = + (EventTransformCreatedInfo) msg.obj; + + applyTransform( + mCurrentToken, + mTunnelIface, + mUnderlying.network, + transformCreatedInfo.transform, + transformCreatedInfo.direction); + break; + case EVENT_SETUP_COMPLETED: + mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig; + + setupInterfaceAndNetworkAgent(mCurrentToken, mTunnelIface, mChildConfig); + break; + case EVENT_DISCONNECT_REQUESTED: + handleDisconnectRequested(((EventDisconnectRequestedInfo) msg.obj).reason); + break; + default: + logUnhandledMessage(msg); + break; + } + } + + private void handleUnderlyingNetworkChanged(@NonNull Message msg) { + final UnderlyingNetworkRecord oldUnderlying = mUnderlying; + mUnderlying = ((EventUnderlyingNetworkChangedInfo) msg.obj).newUnderlying; + + if (mUnderlying == null) { + // Ignored for now; a new network may be coming up. If none does, the delayed + // NETWORK_LOST disconnect will be fired, and tear down the session + network. + return; + } + + // mUnderlying assumed non-null, given check above. + // If network changed, migrate. Otherwise, update any existing networkAgent. + if (oldUnderlying == null || !oldUnderlying.network.equals(mUnderlying.network)) { + mIkeSession.setNetwork(mUnderlying.network); + } else { + // oldUnderlying is non-null & underlying network itself has not changed + // (only network properties were changed). + + // Network not yet set up, or child not yet connected. + if (mNetworkAgent != null && mChildConfig != null) { + // If only network properties changed and agent is active, update properties + updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig); + } + } + } + + protected void setupInterfaceAndNetworkAgent( + int token, + @NonNull IpSecTunnelInterface tunnelIface, + @NonNull ChildSessionConfiguration childConfig) { + setupInterface(token, tunnelIface, childConfig); + + if (mNetworkAgent == null) { + mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig); + } else { + updateNetworkAgent(tunnelIface, mNetworkAgent, childConfig); + } + } } /** @@ -966,7 +1165,8 @@ public class VcnGatewayConnection extends StateMachine { @VisibleForTesting(visibility = Visibility.PRIVATE) static NetworkCapabilities buildNetworkCapabilities( - @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig) { + @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig, + @Nullable UnderlyingNetworkRecord underlying) { final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder(); builder.addTransportType(TRANSPORT_CELLULAR); @@ -978,6 +1178,52 @@ public class VcnGatewayConnection extends StateMachine { builder.addCapability(cap); } + if (underlying != null) { + final NetworkCapabilities underlyingCaps = underlying.networkCapabilities; + + // Mirror merged capabilities. + for (int cap : MERGED_CAPABILITIES) { + if (underlyingCaps.hasCapability(cap)) { + builder.addCapability(cap); + } + } + + // Set admin UIDs for ConnectivityDiagnostics use. + final int[] underlyingAdminUids = underlyingCaps.getAdministratorUids(); + Arrays.sort(underlyingAdminUids); // Sort to allow contains check below. + + final int[] adminUids; + if (underlyingCaps.getOwnerUid() > 0 // No owner UID specified + && 0 > Arrays.binarySearch(// Owner UID not found in admin UID list. + underlyingAdminUids, underlyingCaps.getOwnerUid())) { + adminUids = Arrays.copyOf(underlyingAdminUids, underlyingAdminUids.length + 1); + adminUids[adminUids.length - 1] = underlyingCaps.getOwnerUid(); + Arrays.sort(adminUids); + } else { + adminUids = underlyingAdminUids; + } + builder.setAdministratorUids(adminUids); + + // Set TransportInfo for SysUI use (never parcelled out of SystemServer). + if (underlyingCaps.hasTransport(TRANSPORT_WIFI) + && underlyingCaps.getTransportInfo() instanceof WifiInfo) { + final WifiInfo wifiInfo = (WifiInfo) underlyingCaps.getTransportInfo(); + builder.setTransportInfo(new VcnTransportInfo(wifiInfo)); + } else if (underlyingCaps.hasTransport(TRANSPORT_CELLULAR) + && underlyingCaps.getNetworkSpecifier() instanceof TelephonyNetworkSpecifier) { + final TelephonyNetworkSpecifier telNetSpecifier = + (TelephonyNetworkSpecifier) underlyingCaps.getNetworkSpecifier(); + builder.setTransportInfo(new VcnTransportInfo(telNetSpecifier.getSubscriptionId())); + } else { + Slog.wtf( + TAG, + "Unknown transport type or missing TransportInfo/NetworkSpecifier for" + + " non-null underlying network"); + } + } + + // TODO: Make a VcnNetworkSpecifier, and match all underlying subscription IDs. + return builder.build(); } diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java new file mode 100644 index 000000000000..e20070ee4f07 --- /dev/null +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2020 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.server.vcn; + +import static android.net.IpSecManager.DIRECTION_IN; +import static android.net.IpSecManager.DIRECTION_OUT; + +import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Tests for VcnGatewayConnection.ConnectedState */ +@RunWith(AndroidJUnit4.class) +@SmallTest +public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase { + private VcnIkeSession mIkeSession; + + @Before + public void setUp() throws Exception { + super.setUp(); + + mGatewayConnection.setUnderlyingNetwork(TEST_UNDERLYING_NETWORK_RECORD_1); + + mIkeSession = mGatewayConnection.buildIkeSession(); + mGatewayConnection.setIkeSession(mIkeSession); + + mGatewayConnection.transitionTo(mGatewayConnection.mConnectedState); + mTestLooper.dispatchAll(); + } + + @Test + public void testEnterStateCreatesNewIkeSession() throws Exception { + verify(mDeps).newIkeSession(any(), any(), any(), any(), any()); + } + + @Test + public void testNullNetworkDoesNotTriggerDisconnect() throws Exception { + mGatewayConnection + .getUnderlyingNetworkTrackerCallback() + .onSelectedUnderlyingNetworkChanged(null); + mTestLooper.dispatchAll(); + + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + verify(mIkeSession, never()).close(); + } + + @Test + public void testNewNetworkTriggersMigration() throws Exception { + mGatewayConnection + .getUnderlyingNetworkTrackerCallback() + .onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_2); + mTestLooper.dispatchAll(); + + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + verify(mIkeSession, never()).close(); + verify(mIkeSession).setNetwork(TEST_UNDERLYING_NETWORK_RECORD_2.network); + } + + @Test + public void testSameNetworkDoesNotTriggerMigration() throws Exception { + mGatewayConnection + .getUnderlyingNetworkTrackerCallback() + .onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_1); + mTestLooper.dispatchAll(); + + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testCreatedTransformsAreApplied() throws Exception { + for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) { + getChildSessionCallback().onIpSecTransformCreated(makeDummyIpSecTransform(), direction); + mTestLooper.dispatchAll(); + + verify(mIpSecSvc) + .applyTunnelModeTransform( + eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any()); + } + + assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testChildSessionClosedTriggersDisconnect() throws Exception { + getChildSessionCallback().onClosed(); + mTestLooper.dispatchAll(); + + assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState()); + } + + @Test + public void testIkeSessionClosedTriggersDisconnect() throws Exception { + getIkeSessionCallback().onClosed(); + mTestLooper.dispatchAll(); + + assertEquals(mGatewayConnection.mRetryTimeoutState, mGatewayConnection.getCurrentState()); + verify(mIkeSession).close(); + } + + // TODO: Add tests for childOpened() when ChildSessionConfiguration can be mocked or created +} diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java index d741e5cf4b35..f4ac86d73655 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java @@ -16,20 +16,35 @@ package com.android.server.vcn; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import android.annotation.NonNull; import android.content.Context; +import android.net.LinkProperties; +import android.net.Network; import android.net.NetworkCapabilities; +import android.net.TelephonyNetworkSpecifier; import android.net.vcn.VcnGatewayConnectionConfigTest; +import android.net.vcn.VcnTransportInfo; +import android.net.wifi.WifiInfo; import android.os.ParcelUuid; +import android.os.Process; import android.os.test.TestLooper; import android.telephony.SubscriptionInfo; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; +import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord; + import org.junit.Test; import org.junit.runner.RunWith; @@ -42,6 +57,7 @@ import java.util.UUID; @RunWith(AndroidJUnit4.class) @SmallTest public class VcnGatewayConnectionTest { + private static final int TEST_UID = Process.myUid(); private static final ParcelUuid TEST_PARCEL_UUID = new ParcelUuid(UUID.randomUUID()); private static final int TEST_SIM_SLOT_INDEX = 1; private static final int TEST_SUBSCRIPTION_ID_1 = 2; @@ -61,22 +77,59 @@ public class VcnGatewayConnectionTest { @NonNull private final TestLooper mTestLooper; @NonNull private final VcnNetworkProvider mVcnNetworkProvider; @NonNull private final VcnGatewayConnection.Dependencies mDeps; + @NonNull private final WifiInfo mWifiInfo; public VcnGatewayConnectionTest() { mContext = mock(Context.class); mTestLooper = new TestLooper(); mVcnNetworkProvider = mock(VcnNetworkProvider.class); mDeps = mock(VcnGatewayConnection.Dependencies.class); + mWifiInfo = mock(WifiInfo.class); } - @Test - public void testBuildNetworkCapabilities() throws Exception { - final NetworkCapabilities caps = + private void verifyBuildNetworkCapabilitiesCommon(int transportType) { + final NetworkCapabilities underlyingCaps = new NetworkCapabilities(); + underlyingCaps.addTransportType(transportType); + underlyingCaps.addCapability(NET_CAPABILITY_NOT_METERED); + underlyingCaps.addCapability(NET_CAPABILITY_NOT_ROAMING); + + if (transportType == TRANSPORT_WIFI) { + underlyingCaps.setTransportInfo(mWifiInfo); + underlyingCaps.setOwnerUid(TEST_UID); + } else if (transportType == TRANSPORT_CELLULAR) { + underlyingCaps.setAdministratorUids(new int[] {TEST_UID}); + underlyingCaps.setNetworkSpecifier( + new TelephonyNetworkSpecifier(TEST_SUBSCRIPTION_ID_1)); + } + + UnderlyingNetworkRecord record = + new UnderlyingNetworkRecord( + new Network(0), underlyingCaps, new LinkProperties(), false); + final NetworkCapabilities vcnCaps = VcnGatewayConnection.buildNetworkCapabilities( - VcnGatewayConnectionConfigTest.buildTestConfig()); + VcnGatewayConnectionConfigTest.buildTestConfig(), record); + + assertTrue(vcnCaps.hasTransport(TRANSPORT_CELLULAR)); + assertTrue(vcnCaps.hasCapability(NET_CAPABILITY_NOT_METERED)); + assertTrue(vcnCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING)); + assertArrayEquals(new int[] {TEST_UID}, vcnCaps.getAdministratorUids()); + assertTrue(vcnCaps.getTransportInfo() instanceof VcnTransportInfo); - for (int exposedCapability : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) { - assertTrue(caps.hasCapability(exposedCapability)); + final VcnTransportInfo info = (VcnTransportInfo) vcnCaps.getTransportInfo(); + if (transportType == TRANSPORT_WIFI) { + assertEquals(mWifiInfo, info.getWifiInfo()); + } else if (transportType == TRANSPORT_CELLULAR) { + assertEquals(TEST_SUBSCRIPTION_ID_1, info.getSubId()); } } + + @Test + public void testBuildNetworkCapabilitiesUnderlyingWifi() throws Exception { + verifyBuildNetworkCapabilitiesCommon(TRANSPORT_WIFI); + } + + @Test + public void testBuildNetworkCapabilitiesUnderlyingCell() throws Exception { + verifyBuildNetworkCapabilitiesCommon(TRANSPORT_CELLULAR); + } } diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java index 4d92fb9c42f2..873078036a69 100644 --- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java +++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java @@ -27,7 +27,9 @@ import static org.mockito.Mockito.verify; import android.annotation.NonNull; import android.content.Context; +import android.net.IpSecConfig; import android.net.IpSecManager; +import android.net.IpSecTransform; import android.net.IpSecTunnelInterfaceResponse; import android.net.LinkProperties; import android.net.Network; @@ -48,7 +50,10 @@ import java.util.UUID; public class VcnGatewayConnectionTestBase { protected static final ParcelUuid TEST_SUB_GRP = new ParcelUuid(UUID.randomUUID()); - protected static final int TEST_IPSEC_TUNNEL_RESOURCE_ID = 1; + protected static final int TEST_IPSEC_SPI_VALUE = 0x1234; + protected static final int TEST_IPSEC_SPI_RESOURCE_ID = 1; + protected static final int TEST_IPSEC_TRANSFORM_RESOURCE_ID = 2; + protected static final int TEST_IPSEC_TUNNEL_RESOURCE_ID = 3; protected static final String TEST_IPSEC_TUNNEL_IFACE = "IPSEC_IFACE"; protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 = new UnderlyingNetworkRecord( @@ -112,6 +117,10 @@ public class VcnGatewayConnectionTestBase { mGatewayConnection = new VcnGatewayConnection(mVcnContext, TEST_SUB_GRP, mConfig, mDeps); } + protected IpSecTransform makeDummyIpSecTransform() throws Exception { + return new IpSecTransform(mContext, new IpSecConfig()); + } + protected IkeSessionCallback getIkeSessionCallback() { ArgumentCaptor<IkeSessionCallback> captor = ArgumentCaptor.forClass(IkeSessionCallback.class); |