Merge "Maximize VCN MTU when using IPv6" am: 6d70c7f36a

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2063435

Change-Id: I472face8fa2ad8fb46b72bcc63469d33ccce73fd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Yan Yan
2022-04-18 17:52:29 +00:00
committed by Automerger Merge Worker
6 changed files with 236 additions and 38 deletions

View File

@@ -61,6 +61,7 @@ import android.net.ipsec.ike.ChildSessionParams;
import android.net.ipsec.ike.IkeSession; import android.net.ipsec.ike.IkeSession;
import android.net.ipsec.ike.IkeSessionCallback; 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.IkeSessionParams; import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams; import android.net.ipsec.ike.IkeTunnelConnectionParams;
import android.net.ipsec.ike.exceptions.IkeException; import android.net.ipsec.ike.exceptions.IkeException;
@@ -509,6 +510,42 @@ public class VcnGatewayConnection extends StateMachine {
} }
} }
/**
* Sent when an IKE session connection information has changed.
*
* <p>This signal is always fired before EVENT_SETUP_COMPLETED and EVENT_MIGRATION_COMPLETED.
*
* <p>Only relevant in the Connecting and Connected state.
*
* @param arg1 The session token for the IKE Session whose connection information has changed,
* used to prevent out-of-date signals from propagating.
* @param obj @NonNull An EventIkeConnectionInfoChangedInfo instance with relevant data.
*/
private static final int EVENT_IKE_CONNECTION_INFO_CHANGED = 12;
private static class EventIkeConnectionInfoChangedInfo implements EventInfo {
@NonNull public final IkeSessionConnectionInfo ikeConnectionInfo;
EventIkeConnectionInfoChangedInfo(@NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
this.ikeConnectionInfo = ikeConnectionInfo;
}
@Override
public int hashCode() {
return Objects.hash(ikeConnectionInfo);
}
@Override
public boolean equals(@Nullable Object other) {
if (!(other instanceof EventIkeConnectionInfoChangedInfo)) {
return false;
}
final EventIkeConnectionInfoChangedInfo rhs = (EventIkeConnectionInfoChangedInfo) other;
return Objects.equals(ikeConnectionInfo, rhs.ikeConnectionInfo);
}
}
@VisibleForTesting(visibility = Visibility.PRIVATE) @VisibleForTesting(visibility = Visibility.PRIVATE)
@NonNull @NonNull
final DisconnectedState mDisconnectedState = new DisconnectedState(); final DisconnectedState mDisconnectedState = new DisconnectedState();
@@ -623,6 +660,14 @@ public class VcnGatewayConnection extends StateMachine {
*/ */
private UnderlyingNetworkRecord mUnderlying; private UnderlyingNetworkRecord mUnderlying;
/**
* The current IKE Session connection information
*
* <p>Set in Connected and Migrating states, always @NonNull in Connected, Migrating
* states, @Nullable otherwise.
*/
private IkeSessionConnectionInfo mIkeConnectionInfo;
/** /**
* The active IKE session. * The active IKE session.
* *
@@ -1197,6 +1242,14 @@ public class VcnGatewayConnection extends StateMachine {
exceptionMessage); exceptionMessage);
} }
private void ikeConnectionInfoChanged(
int token, @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
sendMessageAndAcquireWakeLock(
EVENT_IKE_CONNECTION_INFO_CHANGED,
token,
new EventIkeConnectionInfoChangedInfo(ikeConnectionInfo));
}
private void sessionClosed(int token, @Nullable Exception exception) { private void sessionClosed(int token, @Nullable Exception exception) {
if (exception != null) { if (exception != null) {
notifyStatusCallbackForSessionClosed(exception); notifyStatusCallbackForSessionClosed(exception);
@@ -1313,7 +1366,8 @@ public class VcnGatewayConnection extends StateMachine {
case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough
case EVENT_SUBSCRIPTIONS_CHANGED: // Fallthrough case EVENT_SUBSCRIPTIONS_CHANGED: // Fallthrough
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: // Fallthrough case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: // Fallthrough
case EVENT_MIGRATION_COMPLETED: case EVENT_MIGRATION_COMPLETED: // Fallthrough
case EVENT_IKE_CONNECTION_INFO_CHANGED:
logUnexpectedEvent(msg.what); logUnexpectedEvent(msg.what);
break; break;
default: default:
@@ -1592,6 +1646,7 @@ public class VcnGatewayConnection extends StateMachine {
transitionTo(mDisconnectingState); transitionTo(mDisconnectingState);
break; break;
case EVENT_SETUP_COMPLETED: // fallthrough case EVENT_SETUP_COMPLETED: // fallthrough
case EVENT_IKE_CONNECTION_INFO_CHANGED: // fallthrough
case EVENT_TRANSFORM_CREATED: case EVENT_TRANSFORM_CREATED:
// Child setup complete; move to ConnectedState for NetworkAgent registration // Child setup complete; move to ConnectedState for NetworkAgent registration
deferMessage(msg); deferMessage(msg);
@@ -1614,12 +1669,17 @@ public class VcnGatewayConnection extends StateMachine {
protected void updateNetworkAgent( protected void updateNetworkAgent(
@NonNull IpSecTunnelInterface tunnelIface, @NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnNetworkAgent agent, @NonNull VcnNetworkAgent agent,
@NonNull VcnChildSessionConfiguration childConfig) { @NonNull VcnChildSessionConfiguration childConfig,
@NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
final NetworkCapabilities caps = final NetworkCapabilities caps =
buildNetworkCapabilities(mConnectionConfig, mUnderlying, mIsMobileDataEnabled); buildNetworkCapabilities(mConnectionConfig, mUnderlying, mIsMobileDataEnabled);
final LinkProperties lp = final LinkProperties lp =
buildConnectedLinkProperties( buildConnectedLinkProperties(
mConnectionConfig, tunnelIface, childConfig, mUnderlying); mConnectionConfig,
tunnelIface,
childConfig,
mUnderlying,
ikeConnectionInfo);
agent.sendNetworkCapabilities(caps); agent.sendNetworkCapabilities(caps);
agent.sendLinkProperties(lp); agent.sendLinkProperties(lp);
@@ -1630,12 +1690,17 @@ public class VcnGatewayConnection extends StateMachine {
protected VcnNetworkAgent buildNetworkAgent( protected VcnNetworkAgent buildNetworkAgent(
@NonNull IpSecTunnelInterface tunnelIface, @NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig) { @NonNull VcnChildSessionConfiguration childConfig,
@NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
final NetworkCapabilities caps = final NetworkCapabilities caps =
buildNetworkCapabilities(mConnectionConfig, mUnderlying, mIsMobileDataEnabled); buildNetworkCapabilities(mConnectionConfig, mUnderlying, mIsMobileDataEnabled);
final LinkProperties lp = final LinkProperties lp =
buildConnectedLinkProperties( buildConnectedLinkProperties(
mConnectionConfig, tunnelIface, childConfig, mUnderlying); mConnectionConfig,
tunnelIface,
childConfig,
mUnderlying,
ikeConnectionInfo);
final NetworkAgentConfig nac = final NetworkAgentConfig nac =
new NetworkAgentConfig.Builder() new NetworkAgentConfig.Builder()
.setLegacyType(ConnectivityManager.TYPE_MOBILE) .setLegacyType(ConnectivityManager.TYPE_MOBILE)
@@ -1838,7 +1903,11 @@ public class VcnGatewayConnection extends StateMachine {
mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig; mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig;
setupInterfaceAndNetworkAgent( setupInterfaceAndNetworkAgent(
mCurrentToken, mTunnelIface, mChildConfig, oldChildConfig); mCurrentToken,
mTunnelIface,
mChildConfig,
oldChildConfig,
mIkeConnectionInfo);
break; break;
case EVENT_DISCONNECT_REQUESTED: case EVENT_DISCONNECT_REQUESTED:
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj); handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
@@ -1852,6 +1921,10 @@ public class VcnGatewayConnection extends StateMachine {
handleMigrationCompleted(migrationCompletedInfo); handleMigrationCompleted(migrationCompletedInfo);
break; break;
case EVENT_IKE_CONNECTION_INFO_CHANGED:
mIkeConnectionInfo =
((EventIkeConnectionInfoChangedInfo) msg.obj).ikeConnectionInfo;
break;
default: default:
logUnhandledMessage(msg); logUnhandledMessage(msg);
break; break;
@@ -1875,7 +1948,7 @@ public class VcnGatewayConnection extends StateMachine {
migrationCompletedInfo.outTransform, migrationCompletedInfo.outTransform,
IpSecManager.DIRECTION_OUT); IpSecManager.DIRECTION_OUT);
updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig); updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig, mIkeConnectionInfo);
// Trigger re-validation after migration events. // Trigger re-validation after migration events.
mConnectivityManager.reportNetworkConnectivity( mConnectivityManager.reportNetworkConnectivity(
@@ -1906,7 +1979,8 @@ public class VcnGatewayConnection extends StateMachine {
// Network not yet set up, or child not yet connected. // Network not yet set up, or child not yet connected.
if (mNetworkAgent != null && mChildConfig != null) { if (mNetworkAgent != null && mChildConfig != null) {
// If only network properties changed and agent is active, update properties // If only network properties changed and agent is active, update properties
updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig); updateNetworkAgent(
mTunnelIface, mNetworkAgent, mChildConfig, mIkeConnectionInfo);
} }
} }
} }
@@ -1915,13 +1989,14 @@ public class VcnGatewayConnection extends StateMachine {
int token, int token,
@NonNull IpSecTunnelInterface tunnelIface, @NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig, @NonNull VcnChildSessionConfiguration childConfig,
@NonNull VcnChildSessionConfiguration oldChildConfig) { @NonNull VcnChildSessionConfiguration oldChildConfig,
@NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
setupInterface(token, tunnelIface, childConfig, oldChildConfig); setupInterface(token, tunnelIface, childConfig, oldChildConfig);
if (mNetworkAgent == null) { if (mNetworkAgent == null) {
mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig); mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig, ikeConnectionInfo);
} else { } else {
updateNetworkAgent(tunnelIface, mNetworkAgent, childConfig); updateNetworkAgent(tunnelIface, mNetworkAgent, childConfig, ikeConnectionInfo);
// mNetworkAgent not null, so the VCN Network has already been established. Clear // mNetworkAgent not null, so the VCN Network has already been established. Clear
// the failed attempt counter and safe mode alarm since this transition is complete. // the failed attempt counter and safe mode alarm since this transition is complete.
@@ -2098,7 +2173,8 @@ public class VcnGatewayConnection extends StateMachine {
@NonNull VcnGatewayConnectionConfig gatewayConnectionConfig, @NonNull VcnGatewayConnectionConfig gatewayConnectionConfig,
@NonNull IpSecTunnelInterface tunnelIface, @NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig, @NonNull VcnChildSessionConfiguration childConfig,
@Nullable UnderlyingNetworkRecord underlying) { @Nullable UnderlyingNetworkRecord underlying,
@NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
final IkeTunnelConnectionParams ikeTunnelParams = final IkeTunnelConnectionParams ikeTunnelParams =
gatewayConnectionConfig.getTunnelConnectionParams(); gatewayConnectionConfig.getTunnelConnectionParams();
final LinkProperties lp = new LinkProperties(); final LinkProperties lp = new LinkProperties();
@@ -2139,7 +2215,8 @@ public class VcnGatewayConnection extends StateMachine {
MtuUtils.getMtu( MtuUtils.getMtu(
ikeTunnelParams.getTunnelModeChildSessionParams().getSaProposals(), ikeTunnelParams.getTunnelModeChildSessionParams().getSaProposals(),
gatewayConnectionConfig.getMaxMtu(), gatewayConnectionConfig.getMaxMtu(),
underlyingMtu)); underlyingMtu,
ikeConnectionInfo.getLocalAddress() instanceof Inet4Address));
return lp; return lp;
} }
@@ -2154,7 +2231,7 @@ public class VcnGatewayConnection extends StateMachine {
@Override @Override
public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) { public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
logDbg("IkeOpened for token " + mToken); logDbg("IkeOpened for token " + mToken);
// Nothing to do here. ikeConnectionInfoChanged(mToken, ikeSessionConfig.getIkeSessionConnectionInfo());
} }
@Override @Override
@@ -2174,6 +2251,13 @@ public class VcnGatewayConnection extends StateMachine {
logInfo("IkeError for token " + mToken, exception); logInfo("IkeError for token " + mToken, exception);
// Non-fatal, log and continue. // Non-fatal, log and continue.
} }
@Override
public void onIkeSessionConnectionInfoChanged(
@NonNull IkeSessionConnectionInfo connectionInfo) {
logDbg("onIkeSessionConnectionInfoChanged for token " + mToken);
ikeConnectionInfoChanged(mToken, connectionInfo);
}
} }
/** Implementation of ChildSessionCallback, exposed for testing. */ /** Implementation of ChildSessionCallback, exposed for testing. */
@@ -2349,6 +2433,11 @@ public class VcnGatewayConnection extends StateMachine {
mUnderlying = record; mUnderlying = record;
} }
@VisibleForTesting(visibility = Visibility.PRIVATE)
IkeSessionConnectionInfo getIkeConnectionInfo() {
return mIkeConnectionInfo;
}
@VisibleForTesting(visibility = Visibility.PRIVATE) @VisibleForTesting(visibility = Visibility.PRIVATE)
boolean isQuitting() { boolean isQuitting() {
return mIsQuitting.getValue(); return mIsQuitting.getValue();

View File

@@ -51,9 +51,20 @@ public class MtuUtils {
/** /**
* Max ESP overhead possible * Max ESP overhead possible
* *
* <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad + NextHeader) * <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad Length + Next
* Header). Note: Payload data, Pad Length and Next Header will need to be padded to be multiple
* of the block size of a cipher, and at the same time be aligned on a 4-byte boundary.
*/ */
private static final int GENERIC_ESP_OVERHEAD_MAX = 78; private static final int GENERIC_ESP_OVERHEAD_MAX_V4 = 78;
/**
* Max ESP overhead possible
*
* <p>40 (Outer IPv6) + 4 (SPI) + 4 (Seq) + 2 (Pad Length + Next Header). Note: Payload data,
* Pad Length and Next Header will need to be padded to be multiple of the block size of a
* cipher, and at the same time be aligned on a 4-byte boundary.
*/
private static final int GENERIC_ESP_OVERHEAD_MAX_V6 = 50;
/** Maximum overheads of authentication algorithms, keyed on IANA-defined constants */ /** Maximum overheads of authentication algorithms, keyed on IANA-defined constants */
private static final Map<Integer, Integer> AUTH_ALGORITHM_OVERHEAD; private static final Map<Integer, Integer> AUTH_ALGORITHM_OVERHEAD;
@@ -108,7 +119,10 @@ public class MtuUtils {
* </ul> * </ul>
*/ */
public static int getMtu( public static int getMtu(
@NonNull List<ChildSaProposal> childProposals, int maxMtu, int underlyingMtu) { @NonNull List<ChildSaProposal> childProposals,
int maxMtu,
int underlyingMtu,
boolean isIpv4) {
if (underlyingMtu <= 0) { if (underlyingMtu <= 0) {
return IPV6_MIN_MTU; return IPV6_MIN_MTU;
} }
@@ -145,10 +159,13 @@ public class MtuUtils {
} }
} }
final int genericEspOverheadMax =
isIpv4 ? GENERIC_ESP_OVERHEAD_MAX_V4 : GENERIC_ESP_OVERHEAD_MAX_V6;
// Return minimum of maxMtu, and the adjusted MTUs based on algorithms. // Return minimum of maxMtu, and the adjusted MTUs based on algorithms.
final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - GENERIC_ESP_OVERHEAD_MAX; final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - genericEspOverheadMax;
final int normalModeMtu = final int normalModeMtu =
underlyingMtu - maxCryptOverhead - maxAuthOverhead - GENERIC_ESP_OVERHEAD_MAX; underlyingMtu - maxCryptOverhead - maxAuthOverhead - genericEspOverheadMax;
return Math.min(Math.min(maxMtu, combinedModeMtu), normalModeMtu); return Math.min(Math.min(maxMtu, combinedModeMtu), normalModeMtu);
} }
} }

View File

@@ -56,6 +56,7 @@ import android.net.LinkProperties;
import android.net.NetworkAgent; 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.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;
@@ -216,14 +217,23 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
@Test @Test
public void testMigration() throws Exception { public void testMigration() throws Exception {
triggerChildOpened(); triggerChildOpened();
mTestLooper.dispatchAll();
assertEquals(mIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
mGatewayConnection mGatewayConnection
.getUnderlyingNetworkControllerCallback() .getUnderlyingNetworkControllerCallback()
.onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_2); .onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_2);
final IkeSessionConnectionInfo newIkeConnectionInfo =
new IkeSessionConnectionInfo(
TEST_ADDR_V4, TEST_ADDR_V4_2, TEST_UNDERLYING_NETWORK_RECORD_2.network);
getIkeSessionCallback().onIkeSessionConnectionInfoChanged(newIkeConnectionInfo);
getChildSessionCallback() getChildSessionCallback()
.onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform()); .onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform());
mTestLooper.dispatchAll(); mTestLooper.dispatchAll();
assertEquals(newIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
verify(mIpSecSvc, times(2)) verify(mIpSecSvc, times(2))
.setNetworkForTunnelInterface( .setNetworkForTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID), eq(TEST_IPSEC_TUNNEL_RESOURCE_ID),
@@ -246,7 +256,8 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
MtuUtils.getMtu( MtuUtils.getMtu(
saProposals, saProposals,
mConfig.getMaxMtu(), mConfig.getMaxMtu(),
TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.getMtu()); TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.getMtu(),
true /* isIpv4 */);
verify(mNetworkAgent).sendLinkProperties( verify(mNetworkAgent).sendLinkProperties(
argThat(lp -> expectedMtu == lp.getMtu() argThat(lp -> expectedMtu == lp.getMtu()
&& TEST_TCP_BUFFER_SIZES_2.equals(lp.getTcpBufferSizes()))); && TEST_TCP_BUFFER_SIZES_2.equals(lp.getTcpBufferSizes())));
@@ -269,6 +280,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
.when(mMockChildSessionConfig) .when(mMockChildSessionConfig)
.getInternalDnsServers(); .getInternalDnsServers();
getIkeSessionCallback().onOpened(mIkeSessionConfiguration);
getChildSessionCallback().onOpened(mMockChildSessionConfig); getChildSessionCallback().onOpened(mMockChildSessionConfig);
} }
@@ -298,6 +310,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
mTestLooper.dispatchAll(); mTestLooper.dispatchAll();
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState()); assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
assertEquals(mIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
final ArgumentCaptor<LinkProperties> lpCaptor = final ArgumentCaptor<LinkProperties> lpCaptor =
ArgumentCaptor.forClass(LinkProperties.class); ArgumentCaptor.forClass(LinkProperties.class);

View File

@@ -213,7 +213,8 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
VcnGatewayConnectionConfigTest.buildTestConfig(), VcnGatewayConnectionConfigTest.buildTestConfig(),
tunnelIface, tunnelIface,
childSessionConfig, childSessionConfig,
record); record,
mIkeConnectionInfo);
verify(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE); verify(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE);
@@ -226,7 +227,8 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
VcnGatewayConnectionConfigTest.buildTestConfig(), VcnGatewayConnectionConfigTest.buildTestConfig(),
tunnelIface, tunnelIface,
childSessionConfig, childSessionConfig,
record); record,
mIkeConnectionInfo);
verify(mDeps, times(2)).getUnderlyingIfaceMtu(LOOPBACK_IFACE); verify(mDeps, times(2)).getUnderlyingIfaceMtu(LOOPBACK_IFACE);

View File

@@ -47,6 +47,8 @@ import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionCallback;
import android.net.ipsec.ike.IkeSessionConfiguration;
import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.vcn.VcnGatewayConnectionConfig; import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest; import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.os.ParcelUuid; import android.os.ParcelUuid;
@@ -80,6 +82,13 @@ public class VcnGatewayConnectionTestBase {
doReturn(TEST_SUB_GRP).when(TEST_SUB_INFO).getGroupUuid(); doReturn(TEST_SUB_GRP).when(TEST_SUB_INFO).getGroupUuid();
} }
protected static final InetAddress TEST_ADDR = InetAddresses.parseNumericAddress("2001:db8::1");
protected static final InetAddress TEST_ADDR_2 =
InetAddresses.parseNumericAddress("2001:db8::2");
protected static final InetAddress TEST_ADDR_V4 =
InetAddresses.parseNumericAddress("192.0.2.1");
protected static final InetAddress TEST_ADDR_V4_2 =
InetAddresses.parseNumericAddress("192.0.2.2");
protected static final InetAddress TEST_DNS_ADDR = protected static final InetAddress TEST_DNS_ADDR =
InetAddresses.parseNumericAddress("2001:DB8:0:1::"); InetAddresses.parseNumericAddress("2001:DB8:0:1::");
protected static final InetAddress TEST_DNS_ADDR_2 = protected static final InetAddress TEST_DNS_ADDR_2 =
@@ -148,6 +157,9 @@ public class VcnGatewayConnectionTestBase {
@NonNull protected final IpSecService mIpSecSvc; @NonNull protected final IpSecService mIpSecSvc;
@NonNull protected final ConnectivityManager mConnMgr; @NonNull protected final ConnectivityManager mConnMgr;
@NonNull protected final IkeSessionConnectionInfo mIkeConnectionInfo;
@NonNull protected final IkeSessionConfiguration mIkeSessionConfiguration;
protected VcnIkeSession mMockIkeSession; protected VcnIkeSession mMockIkeSession;
protected VcnGatewayConnection mGatewayConnection; protected VcnGatewayConnection mGatewayConnection;
@@ -173,6 +185,10 @@ public class VcnGatewayConnectionTestBase {
VcnTestUtils.setupSystemService( VcnTestUtils.setupSystemService(
mContext, mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); mContext, mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class);
mIkeConnectionInfo =
new IkeSessionConnectionInfo(TEST_ADDR, TEST_ADDR_2, mock(Network.class));
mIkeSessionConfiguration = new IkeSessionConfiguration.Builder(mIkeConnectionInfo).build();
doReturn(mContext).when(mVcnContext).getContext(); doReturn(mContext).when(mVcnContext).getContext();
doReturn(mTestLooper.getLooper()).when(mVcnContext).getLooper(); doReturn(mTestLooper.getLooper()).when(mVcnContext).getLooper();
doReturn(mVcnNetworkProvider).when(mVcnContext).getVcnNetworkProvider(); doReturn(mVcnNetworkProvider).when(mVcnContext).getVcnNetworkProvider();

View File

@@ -46,34 +46,85 @@ import java.util.List;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
public class MtuUtilsTest { public class MtuUtilsTest {
@Test private void verifyUnderlyingMtuZero(boolean isIpv4) {
public void testUnderlyingMtuZero() {
assertEquals( assertEquals(
IPV6_MIN_MTU, getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */)); IPV6_MIN_MTU,
getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */, isIpv4));
} }
@Test @Test
public void testClampsToMaxMtu() { public void testUnderlyingMtuZeroV4() {
assertEquals(0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */)); verifyUnderlyingMtuZero(true /* isIpv4 */);
} }
@Test @Test
public void testNormalModeAlgorithmLessThanUnderlyingMtu() { public void testUnderlyingMtuZeroV6() {
final List<ChildSaProposal> saProposals = verifyUnderlyingMtuZero(false /* isIpv4 */);
Arrays.asList( }
private void verifyClampsToMaxMtu(boolean isIpv4) {
assertEquals(
0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */, isIpv4));
}
@Test
public void testClampsToMaxMtuV4() {
verifyClampsToMaxMtu(true /* isIpv4 */);
}
@Test
public void testClampsToMaxMtuV6() {
verifyClampsToMaxMtu(false /* isIpv4 */);
}
private List<ChildSaProposal> buildChildSaProposalsWithNormalModeAlgo() {
return Arrays.asList(
new ChildSaProposal.Builder() new ChildSaProposal.Builder()
.addEncryptionAlgorithm( .addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)
ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)
.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128) .addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
.build()); .build());
}
private void verifyNormalModeAlgorithmLessThanUnderlyingMtu(boolean isIpv4) {
final int actualMtu = final int actualMtu =
getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */); getMtu(
buildChildSaProposalsWithNormalModeAlgo(),
ETHER_MTU /* maxMtu */,
ETHER_MTU /* underlyingMtu */,
isIpv4);
assertTrue(ETHER_MTU > actualMtu); assertTrue(ETHER_MTU > actualMtu);
} }
@Test @Test
public void testCombinedModeAlgorithmLessThanUnderlyingMtu() { public void testNormalModeAlgorithmLessThanUnderlyingMtuV4() {
verifyNormalModeAlgorithmLessThanUnderlyingMtu(true /* isIpv4 */);
}
@Test
public void testNormalModeAlgorithmLessThanUnderlyingMtuV6() {
verifyNormalModeAlgorithmLessThanUnderlyingMtu(false /* isIpv4 */);
}
@Test
public void testMtuIpv4LessThanMtuIpv6() {
final int actualMtuV4 =
getMtu(
buildChildSaProposalsWithNormalModeAlgo(),
ETHER_MTU /* maxMtu */,
ETHER_MTU /* underlyingMtu */,
true /* isIpv4 */);
final int actualMtuV6 =
getMtu(
buildChildSaProposalsWithNormalModeAlgo(),
ETHER_MTU /* maxMtu */,
ETHER_MTU /* underlyingMtu */,
false /* isIpv4 */);
assertTrue(actualMtuV4 < actualMtuV6);
}
private void verifyCombinedModeAlgorithmLessThanUnderlyingMtu(boolean isIpv4) {
final List<ChildSaProposal> saProposals = final List<ChildSaProposal> saProposals =
Arrays.asList( Arrays.asList(
new ChildSaProposal.Builder() new ChildSaProposal.Builder()
@@ -86,7 +137,17 @@ public class MtuUtilsTest {
.build()); .build());
final int actualMtu = final int actualMtu =
getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */); getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */, isIpv4);
assertTrue(ETHER_MTU > actualMtu); assertTrue(ETHER_MTU > actualMtu);
} }
@Test
public void testCombinedModeAlgorithmLessThanUnderlyingMtuV4() {
verifyCombinedModeAlgorithmLessThanUnderlyingMtu(true /* isIpv4 */);
}
@Test
public void testCombinedModeAlgorithmLessThanUnderlyingMtuV6() {
verifyCombinedModeAlgorithmLessThanUnderlyingMtu(false /* isIpv4 */);
}
} }