Merge "Add experimental support for IPsec tunnel aggregation"
This commit is contained in:
@@ -114,13 +114,28 @@ public class VcnManager {
|
|||||||
public static final String VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY =
|
public static final String VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY =
|
||||||
"vcn_restricted_transports";
|
"vcn_restricted_transports";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Key for maximum number of parallel SAs for tunnel aggregation
|
||||||
|
*
|
||||||
|
* <p>If set to a value > 1, multiple tunnels will be set up, and inbound traffic will be
|
||||||
|
* aggregated over the various tunnels.
|
||||||
|
*
|
||||||
|
* <p>Defaults to 1, unless overridden by carrier config
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public static final String VCN_TUNNEL_AGGREGATION_SA_COUNT_MAX_KEY =
|
||||||
|
"vcn_tunnel_aggregation_sa_count_max";
|
||||||
|
|
||||||
/** List of Carrier Config options to extract from Carrier Config bundles. @hide */
|
/** List of Carrier Config options to extract from Carrier Config bundles. @hide */
|
||||||
@NonNull
|
@NonNull
|
||||||
public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
|
public static final String[] VCN_RELATED_CARRIER_CONFIG_KEYS =
|
||||||
new String[] {
|
new String[] {
|
||||||
VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY,
|
||||||
VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
|
VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY,
|
||||||
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY
|
VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY,
|
||||||
|
VCN_TUNNEL_AGGREGATION_SA_COUNT_MAX_KEY,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final Map<
|
private static final Map<
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import static android.net.vcn.VcnManager.VCN_ERROR_CODE_NETWORK_ERROR;
|
|||||||
|
|
||||||
import static com.android.server.VcnManagementService.LOCAL_LOG;
|
import static com.android.server.VcnManagementService.LOCAL_LOG;
|
||||||
import static com.android.server.VcnManagementService.VDBG;
|
import static com.android.server.VcnManagementService.VDBG;
|
||||||
|
import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
@@ -59,6 +60,7 @@ import android.net.RouteInfo;
|
|||||||
import android.net.TelephonyNetworkSpecifier;
|
import android.net.TelephonyNetworkSpecifier;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.annotations.PolicyDirection;
|
import android.net.annotations.PolicyDirection;
|
||||||
|
import android.net.ipsec.ike.ChildSaProposal;
|
||||||
import android.net.ipsec.ike.ChildSessionCallback;
|
import android.net.ipsec.ike.ChildSessionCallback;
|
||||||
import android.net.ipsec.ike.ChildSessionConfiguration;
|
import android.net.ipsec.ike.ChildSessionConfiguration;
|
||||||
import android.net.ipsec.ike.ChildSessionParams;
|
import android.net.ipsec.ike.ChildSessionParams;
|
||||||
@@ -67,11 +69,14 @@ import android.net.ipsec.ike.IkeSessionCallback;
|
|||||||
import android.net.ipsec.ike.IkeSessionConfiguration;
|
import android.net.ipsec.ike.IkeSessionConfiguration;
|
||||||
import android.net.ipsec.ike.IkeSessionConnectionInfo;
|
import android.net.ipsec.ike.IkeSessionConnectionInfo;
|
||||||
import android.net.ipsec.ike.IkeSessionParams;
|
import android.net.ipsec.ike.IkeSessionParams;
|
||||||
|
import android.net.ipsec.ike.IkeTrafficSelector;
|
||||||
import android.net.ipsec.ike.IkeTunnelConnectionParams;
|
import android.net.ipsec.ike.IkeTunnelConnectionParams;
|
||||||
|
import android.net.ipsec.ike.TunnelModeChildSessionParams;
|
||||||
import android.net.ipsec.ike.exceptions.IkeException;
|
import android.net.ipsec.ike.exceptions.IkeException;
|
||||||
import android.net.ipsec.ike.exceptions.IkeInternalException;
|
import android.net.ipsec.ike.exceptions.IkeInternalException;
|
||||||
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
||||||
import android.net.vcn.VcnGatewayConnectionConfig;
|
import android.net.vcn.VcnGatewayConnectionConfig;
|
||||||
|
import android.net.vcn.VcnManager;
|
||||||
import android.net.vcn.VcnTransportInfo;
|
import android.net.vcn.VcnTransportInfo;
|
||||||
import android.net.wifi.WifiInfo;
|
import android.net.wifi.WifiInfo;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -169,6 +174,9 @@ import java.util.function.Consumer;
|
|||||||
public class VcnGatewayConnection extends StateMachine {
|
public class VcnGatewayConnection extends StateMachine {
|
||||||
private static final String TAG = VcnGatewayConnection.class.getSimpleName();
|
private static final String TAG = VcnGatewayConnection.class.getSimpleName();
|
||||||
|
|
||||||
|
/** Default number of parallel SAs requested */
|
||||||
|
static final int TUNNEL_AGGREGATION_SA_COUNT_MAX_DEFAULT = 1;
|
||||||
|
|
||||||
// Matches DataConnection.NETWORK_TYPE private constant, and magic string from
|
// Matches DataConnection.NETWORK_TYPE private constant, and magic string from
|
||||||
// ConnectivityManager#getNetworkTypeName()
|
// ConnectivityManager#getNetworkTypeName()
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
@@ -1980,6 +1988,22 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
mChildConfig,
|
mChildConfig,
|
||||||
oldChildConfig,
|
oldChildConfig,
|
||||||
mIkeConnectionInfo);
|
mIkeConnectionInfo);
|
||||||
|
|
||||||
|
// Create opportunistic child SAs; this allows SA aggregation in the downlink,
|
||||||
|
// reducing lock/atomic contention in high throughput scenarios. All SAs will
|
||||||
|
// share the same UDP encap socket (and keepalives) as necessary, and are
|
||||||
|
// effectively free.
|
||||||
|
final int parallelTunnelCount =
|
||||||
|
mDeps.getParallelTunnelCount(mLastSnapshot, mSubscriptionGroup);
|
||||||
|
logInfo("Parallel tunnel count: " + parallelTunnelCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < parallelTunnelCount - 1; i++) {
|
||||||
|
mIkeSession.openChildSession(
|
||||||
|
buildOpportunisticChildParams(),
|
||||||
|
new VcnChildSessionCallback(
|
||||||
|
mCurrentToken, true /* isOpportunistic */));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EVENT_DISCONNECT_REQUESTED:
|
case EVENT_DISCONNECT_REQUESTED:
|
||||||
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
|
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
|
||||||
@@ -2350,15 +2374,44 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
public class VcnChildSessionCallback implements ChildSessionCallback {
|
public class VcnChildSessionCallback implements ChildSessionCallback {
|
||||||
private final int mToken;
|
private final int mToken;
|
||||||
|
private final boolean mIsOpportunistic;
|
||||||
|
|
||||||
|
private boolean mIsChildOpened = false;
|
||||||
|
|
||||||
VcnChildSessionCallback(int token) {
|
VcnChildSessionCallback(int token) {
|
||||||
|
this(token, false /* isOpportunistic */);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ChildSessionCallback
|
||||||
|
*
|
||||||
|
* <p>If configured as opportunistic, transforms will not report initial startup, or
|
||||||
|
* associated startup failures. This serves the dual purposes of ensuring that if the server
|
||||||
|
* does not support connection multiplexing, new child SA negotiations will be ignored, and
|
||||||
|
* at the same time, will notify the VCN session if a successfully negotiated opportunistic
|
||||||
|
* child SA is subsequently torn down, which could impact uplink traffic if the SA in use
|
||||||
|
* for outbound/uplink traffic is this opportunistic SA.
|
||||||
|
*
|
||||||
|
* <p>While inbound SAs can be used in parallel, the IPsec stack explicitly selects the last
|
||||||
|
* applied outbound transform for outbound traffic. This means that unlike inbound traffic,
|
||||||
|
* outbound does not benefit from these parallel SAs in the same manner.
|
||||||
|
*/
|
||||||
|
VcnChildSessionCallback(int token, boolean isOpportunistic) {
|
||||||
mToken = token;
|
mToken = token;
|
||||||
|
mIsOpportunistic = isOpportunistic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Internal proxy method for injecting of mocked ChildSessionConfiguration */
|
/** Internal proxy method for injecting of mocked ChildSessionConfiguration */
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
void onOpened(@NonNull VcnChildSessionConfiguration childConfig) {
|
void onOpened(@NonNull VcnChildSessionConfiguration childConfig) {
|
||||||
logDbg("ChildOpened for token " + mToken);
|
logDbg("ChildOpened for token " + mToken);
|
||||||
|
|
||||||
|
if (mIsOpportunistic) {
|
||||||
|
logDbg("ChildOpened for opportunistic child; suppressing event message");
|
||||||
|
mIsChildOpened = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
childOpened(mToken, childConfig);
|
childOpened(mToken, childConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2370,12 +2423,24 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
@Override
|
@Override
|
||||||
public void onClosed() {
|
public void onClosed() {
|
||||||
logDbg("ChildClosed for token " + mToken);
|
logDbg("ChildClosed for token " + mToken);
|
||||||
|
|
||||||
|
if (mIsOpportunistic && !mIsChildOpened) {
|
||||||
|
logDbg("ChildClosed for unopened opportunistic child; ignoring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sessionLost(mToken, null);
|
sessionLost(mToken, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClosedExceptionally(@NonNull IkeException exception) {
|
public void onClosedExceptionally(@NonNull IkeException exception) {
|
||||||
logInfo("ChildClosedExceptionally for token " + mToken, exception);
|
logInfo("ChildClosedExceptionally for token " + mToken, exception);
|
||||||
|
|
||||||
|
if (mIsOpportunistic && !mIsChildOpened) {
|
||||||
|
logInfo("ChildClosedExceptionally for unopened opportunistic child; ignoring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sessionLost(mToken, exception);
|
sessionLost(mToken, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2580,6 +2645,30 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
return mConnectionConfig.getTunnelConnectionParams().getTunnelModeChildSessionParams();
|
return mConnectionConfig.getTunnelConnectionParams().getTunnelModeChildSessionParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ChildSessionParams buildOpportunisticChildParams() {
|
||||||
|
final ChildSessionParams baseParams =
|
||||||
|
mConnectionConfig.getTunnelConnectionParams().getTunnelModeChildSessionParams();
|
||||||
|
|
||||||
|
final TunnelModeChildSessionParams.Builder builder =
|
||||||
|
new TunnelModeChildSessionParams.Builder();
|
||||||
|
for (ChildSaProposal proposal : baseParams.getChildSaProposals()) {
|
||||||
|
builder.addChildSaProposal(proposal);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IkeTrafficSelector inboundSelector : baseParams.getInboundTrafficSelectors()) {
|
||||||
|
builder.addInboundTrafficSelectors(inboundSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IkeTrafficSelector outboundSelector : baseParams.getOutboundTrafficSelectors()) {
|
||||||
|
builder.addOutboundTrafficSelectors(outboundSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setLifetimeSeconds(
|
||||||
|
baseParams.getHardLifetimeSeconds(), baseParams.getSoftLifetimeSeconds());
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||||
VcnIkeSession buildIkeSession(@NonNull Network network) {
|
VcnIkeSession buildIkeSession(@NonNull Network network) {
|
||||||
final int token = ++mCurrentToken;
|
final int token = ++mCurrentToken;
|
||||||
@@ -2680,6 +2769,23 @@ public class VcnGatewayConnection extends StateMachine {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the max number of parallel tunnels allowed for tunnel aggregation. */
|
||||||
|
public int getParallelTunnelCount(
|
||||||
|
TelephonySubscriptionSnapshot snapshot, ParcelUuid subGrp) {
|
||||||
|
PersistableBundleWrapper carrierConfig = snapshot.getCarrierConfigForSubGrp(subGrp);
|
||||||
|
int result = TUNNEL_AGGREGATION_SA_COUNT_MAX_DEFAULT;
|
||||||
|
|
||||||
|
if (carrierConfig != null) {
|
||||||
|
result =
|
||||||
|
carrierConfig.getInt(
|
||||||
|
VcnManager.VCN_TUNNEL_AGGREGATION_SA_COUNT_MAX_KEY,
|
||||||
|
TUNNEL_AGGREGATION_SA_COUNT_MAX_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guard against tunnel count < 1
|
||||||
|
return Math.max(1, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -573,5 +573,10 @@ public class PersistableBundleUtils {
|
|||||||
|
|
||||||
return isEqual(mBundle, other.mBundle);
|
return isEqual(mBundle, other.mBundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return mBundle.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import android.net.NetworkAgent;
|
|||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.ipsec.ike.ChildSaProposal;
|
import android.net.ipsec.ike.ChildSaProposal;
|
||||||
import android.net.ipsec.ike.IkeSessionConnectionInfo;
|
import android.net.ipsec.ike.IkeSessionConnectionInfo;
|
||||||
|
import android.net.ipsec.ike.TunnelModeChildSessionParams;
|
||||||
import android.net.ipsec.ike.exceptions.IkeException;
|
import android.net.ipsec.ike.exceptions.IkeException;
|
||||||
import android.net.ipsec.ike.exceptions.IkeInternalException;
|
import android.net.ipsec.ike.exceptions.IkeInternalException;
|
||||||
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
import android.net.ipsec.ike.exceptions.IkeProtocolException;
|
||||||
@@ -70,6 +71,7 @@ import android.os.PersistableBundle;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionCallback;
|
||||||
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
|
import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
|
||||||
import com.android.server.vcn.util.MtuUtils;
|
import com.android.server.vcn.util.MtuUtils;
|
||||||
|
|
||||||
@@ -90,6 +92,8 @@ import java.util.function.Consumer;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
|
public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
|
||||||
|
private static final int PARALLEL_SA_COUNT = 4;
|
||||||
|
|
||||||
private VcnIkeSession mIkeSession;
|
private VcnIkeSession mIkeSession;
|
||||||
private VcnNetworkAgent mNetworkAgent;
|
private VcnNetworkAgent mNetworkAgent;
|
||||||
private Network mVcnNetwork;
|
private Network mVcnNetwork;
|
||||||
@@ -227,16 +231,29 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
|
|||||||
private void verifyVcnTransformsApplied(
|
private void verifyVcnTransformsApplied(
|
||||||
VcnGatewayConnection vcnGatewayConnection, boolean expectForwardTransform)
|
VcnGatewayConnection vcnGatewayConnection, boolean expectForwardTransform)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
verifyVcnTransformsApplied(
|
||||||
|
vcnGatewayConnection,
|
||||||
|
expectForwardTransform,
|
||||||
|
Collections.singletonList(getChildSessionCallback()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyVcnTransformsApplied(
|
||||||
|
VcnGatewayConnection vcnGatewayConnection,
|
||||||
|
boolean expectForwardTransform,
|
||||||
|
List<VcnChildSessionCallback> callbacks)
|
||||||
|
throws Exception {
|
||||||
for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) {
|
for (int direction : new int[] {DIRECTION_IN, DIRECTION_OUT}) {
|
||||||
getChildSessionCallback().onIpSecTransformCreated(makeDummyIpSecTransform(), direction);
|
for (VcnChildSessionCallback cb : callbacks) {
|
||||||
|
cb.onIpSecTransformCreated(makeDummyIpSecTransform(), direction);
|
||||||
|
}
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
verify(mIpSecSvc)
|
verify(mIpSecSvc, times(callbacks.size()))
|
||||||
.applyTunnelModeTransform(
|
.applyTunnelModeTransform(
|
||||||
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any());
|
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(direction), anyInt(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(mIpSecSvc, expectForwardTransform ? times(1) : never())
|
verify(mIpSecSvc, expectForwardTransform ? times(callbacks.size()) : never())
|
||||||
.applyTunnelModeTransform(
|
.applyTunnelModeTransform(
|
||||||
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(DIRECTION_FWD), anyInt(), any());
|
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(DIRECTION_FWD), anyInt(), any());
|
||||||
|
|
||||||
@@ -416,6 +433,89 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
|
|||||||
verifySafeModeStateAndCallbackFired(1 /* invocationCount */, false /* isInSafeMode */);
|
verifySafeModeStateAndCallbackFired(1 /* invocationCount */, false /* isInSafeMode */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<VcnChildSessionCallback> openChildAndVerifyParallelSasRequested()
|
||||||
|
throws Exception {
|
||||||
|
doReturn(PARALLEL_SA_COUNT)
|
||||||
|
.when(mDeps)
|
||||||
|
.getParallelTunnelCount(eq(TEST_SUBSCRIPTION_SNAPSHOT), eq(TEST_SUB_GRP));
|
||||||
|
|
||||||
|
// Verify scheduled but not canceled when entering ConnectedState
|
||||||
|
verifySafeModeTimeoutAlarmAndGetCallback(false /* expectCanceled */);
|
||||||
|
triggerChildOpened();
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
// Verify new child sessions requested
|
||||||
|
final ArgumentCaptor<VcnChildSessionCallback> captor =
|
||||||
|
ArgumentCaptor.forClass(VcnChildSessionCallback.class);
|
||||||
|
verify(mIkeSession, times(PARALLEL_SA_COUNT - 1))
|
||||||
|
.openChildSession(any(TunnelModeChildSessionParams.class), captor.capture());
|
||||||
|
|
||||||
|
return captor.getAllValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<VcnChildSessionCallback> verifyChildOpenedRequestsAndAppliesParallelSas()
|
||||||
|
throws Exception {
|
||||||
|
List<VcnChildSessionCallback> callbacks = openChildAndVerifyParallelSasRequested();
|
||||||
|
|
||||||
|
verifyVcnTransformsApplied(mGatewayConnection, false, callbacks);
|
||||||
|
|
||||||
|
// Mock IKE calling of onOpened()
|
||||||
|
for (VcnChildSessionCallback cb : callbacks) {
|
||||||
|
cb.onOpened(mock(VcnChildSessionConfiguration.class));
|
||||||
|
}
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
|
||||||
|
return callbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChildOpenedWithParallelSas() throws Exception {
|
||||||
|
verifyChildOpenedRequestsAndAppliesParallelSas();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpportunisticSa_ignoresPreOpenFailures() throws Exception {
|
||||||
|
List<VcnChildSessionCallback> callbacks = openChildAndVerifyParallelSasRequested();
|
||||||
|
|
||||||
|
for (VcnChildSessionCallback cb : callbacks) {
|
||||||
|
cb.onClosed();
|
||||||
|
cb.onClosedExceptionally(mock(IkeException.class));
|
||||||
|
}
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
|
||||||
|
assertEquals(mIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyPostOpenFailuresCloseSession(boolean shouldCloseWithException)
|
||||||
|
throws Exception {
|
||||||
|
List<VcnChildSessionCallback> callbacks = verifyChildOpenedRequestsAndAppliesParallelSas();
|
||||||
|
|
||||||
|
for (VcnChildSessionCallback cb : callbacks) {
|
||||||
|
if (shouldCloseWithException) {
|
||||||
|
cb.onClosed();
|
||||||
|
} else {
|
||||||
|
cb.onClosedExceptionally(mock(IkeException.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mTestLooper.dispatchAll();
|
||||||
|
|
||||||
|
assertEquals(mGatewayConnection.mDisconnectingState, mGatewayConnection.getCurrentState());
|
||||||
|
verify(mIkeSession).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpportunisticSa_handlesPostOpenFailures_onClosed() throws Exception {
|
||||||
|
verifyPostOpenFailuresCloseSession(false /* shouldCloseWithException */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpportunisticSa_handlesPostOpenFailures_onClosedExceptionally()
|
||||||
|
throws Exception {
|
||||||
|
verifyPostOpenFailuresCloseSession(true /* shouldCloseWithException */);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInternalAndDnsAddressesChanged() throws Exception {
|
public void testInternalAndDnsAddressesChanged() throws Exception {
|
||||||
final List<LinkAddress> startingInternalAddrs =
|
final List<LinkAddress> startingInternalAddrs =
|
||||||
|
|||||||
@@ -223,6 +223,9 @@ public class VcnGatewayConnectionTestBase {
|
|||||||
doReturn(mWakeLock)
|
doReturn(mWakeLock)
|
||||||
.when(mDeps)
|
.when(mDeps)
|
||||||
.newWakeLock(eq(mContext), eq(PowerManager.PARTIAL_WAKE_LOCK), any());
|
.newWakeLock(eq(mContext), eq(PowerManager.PARTIAL_WAKE_LOCK), any());
|
||||||
|
doReturn(1)
|
||||||
|
.when(mDeps)
|
||||||
|
.getParallelTunnelCount(eq(TEST_SUBSCRIPTION_SNAPSHOT), eq(TEST_SUB_GRP));
|
||||||
|
|
||||||
setUpWakeupMessage(mTeardownTimeoutAlarm, VcnGatewayConnection.TEARDOWN_TIMEOUT_ALARM);
|
setUpWakeupMessage(mTeardownTimeoutAlarm, VcnGatewayConnection.TEARDOWN_TIMEOUT_ALARM);
|
||||||
setUpWakeupMessage(mDisconnectRequestAlarm, VcnGatewayConnection.DISCONNECT_REQUEST_ALARM);
|
setUpWakeupMessage(mDisconnectRequestAlarm, VcnGatewayConnection.DISCONNECT_REQUEST_ALARM);
|
||||||
|
|||||||
Reference in New Issue
Block a user