From 5372c53b5deef83392384ba334b96b6cb5a7533b Mon Sep 17 00:00:00 2001 From: Aswin Sankar Date: Mon, 1 May 2023 11:49:08 -0700 Subject: Disable MOBIKE for IPv6 ePDGs to avoid UDP encap - According to RFC 4555, IPv6 ePDGs can enable UDP encapsulation when MOBIKE is enabled, even if there is no local or remote NAT. - Android connectivity presently does not allow for IPv6 UDP encapsulations. - UE can still perform IPv6 rekey-based mobility procedures. Bug:274860752 Test: Live test on IPv6 ePDG on NA commercial carrier. New UTs in EpdgTunnelManagerTest Change-Id: I794abaa1a964e8e959967989ccfe5f1140f675d8 Merged-In: I794abaa1a964e8e959967989ccfe5f1140f675d8 --- .../google/android/iwlan/epdg/EpdgSelector.java | 2 +- .../android/iwlan/epdg/EpdgTunnelManager.java | 13 ++-- .../android/iwlan/epdg/EpdgSelectorTest.java | 2 +- .../android/iwlan/epdg/EpdgTunnelManagerTest.java | 74 ++++++++++------------ 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/com/google/android/iwlan/epdg/EpdgSelector.java b/src/com/google/android/iwlan/epdg/EpdgSelector.java index 7dda188..52392fd 100644 --- a/src/com/google/android/iwlan/epdg/EpdgSelector.java +++ b/src/com/google/android/iwlan/epdg/EpdgSelector.java @@ -144,7 +144,7 @@ public class EpdgSelector { public interface EpdgSelectorCallback { /*gives priority ordered list of addresses*/ - void onServerListChanged(int transactionId, ArrayList validIPList); + void onServerListChanged(int transactionId, List validIPList); void onError(int transactionId, IwlanError error); } diff --git a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java index 1656e34..bfe4f95 100644 --- a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java +++ b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java @@ -226,8 +226,7 @@ public class EpdgTunnelManager { private final EpdgSelector.EpdgSelectorCallback mSelectorCallback = new EpdgSelector.EpdgSelectorCallback() { @Override - public void onServerListChanged( - int transactionId, ArrayList validIPList) { + public void onServerListChanged(int transactionId, List validIPList) { sendSelectionRequestComplete( validIPList, new IwlanError(IwlanError.NO_ERROR), transactionId); } @@ -744,7 +743,7 @@ public class EpdgTunnelManager { TAG, "Bringing up tunnel for apn: " + apnName - + "ePDG : " + + " ePDG: " + mEpdgAddress.getHostAddress()); final int token = incrementAndGetCurrentTokenForApn(apnName); @@ -994,6 +993,12 @@ public class EpdgTunnelManager { } } + // If MOBIKE is configured, ePDGs may force IPv6 UDP encapsulation- as specified by + // RFC 4555- which Android connectivity stack presently does not support. + if (mEpdgAddress instanceof Inet6Address) { + builder.removeIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE); + } + Ike3gppParams.Builder builder3gppParams = null; // TODO(b/239753287): Telus carrier requests DEVICE_IDENTITY, but errors out when parsing @@ -2288,7 +2293,7 @@ public class EpdgTunnelManager { @VisibleForTesting void sendSelectionRequestComplete( - ArrayList validIPList, IwlanError result, int transactionId) { + List validIPList, IwlanError result, int transactionId) { mEpdgServerSelectionDuration = System.currentTimeMillis() - mEpdgServerSelectionStartTime; mEpdgServerSelectionStartTime = 0; EpdgSelectorResult epdgSelectorResult = diff --git a/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java b/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java index dc9ee2b..b2d514c 100644 --- a/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java +++ b/test/com/google/android/iwlan/epdg/EpdgSelectorTest.java @@ -514,7 +514,7 @@ public class EpdgSelectorTest { new EpdgSelector.EpdgSelectorCallback() { @Override public void onServerListChanged( - int transactionId, ArrayList validIPList) { + int transactionId, List validIPList) { assertEquals(transactionId, 1234); for (InetAddress mInetAddress : validIPList) { diff --git a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java index f42fcb0..76ceec8 100644 --- a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java +++ b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java @@ -105,23 +105,23 @@ public class EpdgTunnelManagerTest { public static final int DEFAULT_TOKEN = 0; private static final String EPDG_ADDRESS = "127.0.0.1"; + private static final String EPDG_ADDRESS_IPV6 = "2600:387:f:707::1"; private static final String TEST_APN_NAME = "www.xyz.com"; - private static final ArrayList EXPECTED_LOCAL_ADDRESSES = - new ArrayList<>(List.of(InetAddresses.parseNumericAddress("201.1.100.10"))); - private static final ArrayList EXPECTED_IPV6_LOCAL_ADDRESSES = - new ArrayList<>(List.of(InetAddresses.parseNumericAddress("2001:db8::1:2"))); - private static final ArrayList EXPECTED_EPDG_ADDRESSES = - new ArrayList<>(List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS))); - private static final ArrayList EXPECTED_INTERNAL_ADDRESSES = - new ArrayList<>( - List.of( - new LinkAddress( - InetAddresses.parseNumericAddress("198.50.100.10"), 24))); - private static final ArrayList EXPECTED_PCSCF_ADDRESSES = - new ArrayList<>(List.of(InetAddresses.parseNumericAddress("198.51.100.10"))); - private static final ArrayList EXPECTED_DNS_ADDRESSES = - new ArrayList<>(List.of(InetAddresses.parseNumericAddress("198.50.100.10"))); + private static final List EXPECTED_LOCAL_ADDRESSES = + List.of(InetAddresses.parseNumericAddress("201.1.100.10")); + private static final List EXPECTED_IPV6_LOCAL_ADDRESSES = + List.of(InetAddresses.parseNumericAddress("2001:db8::1:2")); + private static final List EXPECTED_EPDG_ADDRESSES = + List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS)); + private static final List EXPECTED_EPDG_ADDRESSES_IPV6 = + List.of(InetAddresses.parseNumericAddress(EPDG_ADDRESS_IPV6)); + private static final List EXPECTED_INTERNAL_ADDRESSES = + List.of(new LinkAddress(InetAddresses.parseNumericAddress("198.50.100.10"), 24)); + private static final List EXPECTED_PCSCF_ADDRESSES = + List.of(InetAddresses.parseNumericAddress("198.51.100.10")); + private static final List EXPECTED_DNS_ADDRESSES = + List.of(InetAddresses.parseNumericAddress("198.50.100.10")); private EpdgTunnelManager mEpdgTunnelManager; @@ -354,7 +354,8 @@ public class EpdgTunnelManagerTest { any()); } - private void setupTunnelBringup(String apnName, int transactionId) throws Exception { + private void setupTunnelBringup( + String apnName, List epdgAddresses, int transactionId) throws Exception { setupMockForGetConfig(null); doReturn(null) .when(mMockIkeSessionCreator) @@ -377,12 +378,12 @@ public class EpdgTunnelManagerTest { mTestLooper.dispatchAll(); mEpdgTunnelManager.sendSelectionRequestComplete( - EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), transactionId); + epdgAddresses, new IwlanError(IwlanError.NO_ERROR), transactionId); mTestLooper.dispatchAll(); } private void setupTunnelBringup() throws Exception { - setupTunnelBringup(TEST_APN_NAME, 1 /* transactionId */); + setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, 1 /* transactionId */); } @Test @@ -476,30 +477,25 @@ public class EpdgTunnelManagerTest { @Test public void testBringUpTunnelWithMobilityOptions() throws Exception { - doReturn(null) - .when(mMockIkeSessionCreator) + setupTunnelBringup(); + ArgumentCaptor ikeSessionParamsCaptor = + ArgumentCaptor.forClass(IkeSessionParams.class); + verify(mMockIkeSessionCreator, atLeastOnce()) .createIkeSession( eq(mMockContext), - any(IkeSessionParams.class), + ikeSessionParamsCaptor.capture(), any(ChildSessionParams.class), any(Executor.class), any(IkeSessionCallback.class), any(ChildSessionCallback.class)); + IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue(); + assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)); + assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY)); + } - doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME)); - - boolean ret = - mEpdgTunnelManager.bringUpTunnel( - getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP), - mMockIwlanTunnelCallback, - mMockIwlanTunnelMetrics); - assertTrue(ret); - mTestLooper.dispatchAll(); - - mEpdgTunnelManager.sendSelectionRequestComplete( - EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1); - mTestLooper.dispatchAll(); - + @Test + public void testBringUpTunnelIpv6_verifyMobikeDisabled() throws Exception { + setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES_IPV6, 1); ArgumentCaptor ikeSessionParamsCaptor = ArgumentCaptor.forClass(IkeSessionParams.class); verify(mMockIkeSessionCreator, atLeastOnce()) @@ -511,8 +507,8 @@ public class EpdgTunnelManagerTest { any(IkeSessionCallback.class), any(ChildSessionCallback.class)); IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue(); - assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)); assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY)); + assertFalse(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)); } @Test @@ -2045,7 +2041,7 @@ public class EpdgTunnelManagerTest { int transactionId = 0; // testApnName with token 0 - setupTunnelBringup(TEST_APN_NAME, ++transactionId); + setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, ++transactionId); mEpdgTunnelManager.onConnectedToEpdg(true); IwlanError error = new IwlanError(mMockIkeException); @@ -2059,7 +2055,7 @@ public class EpdgTunnelManagerTest { assertNull(mEpdgTunnelManager.getTunnelConfigForApn(TEST_APN_NAME)); // testApnName1 with token 1 - setupTunnelBringup(TEST_APN_NAME, ++transactionId); + setupTunnelBringup(TEST_APN_NAME, EXPECTED_EPDG_ADDRESSES, ++transactionId); mEpdgTunnelManager.onConnectedToEpdg(true); // signal from obsolete callback (token 0), ignore it @@ -2283,7 +2279,7 @@ public class EpdgTunnelManagerTest { IwlanError error = new IwlanError(IwlanError.IKE_INIT_TIMEOUT, mMockIkeIoException); doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error)); - setupTunnelBringup(testApnName, 1); + setupTunnelBringup(); ArgumentCaptor ikeSessionCallbackCaptor = ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class); -- cgit v1.2.3