1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.vcn; 18 19 import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE; 20 import static android.net.vcn.VcnGatewayConnectionConfig.DEFAULT_UNDERLYING_NETWORK_TEMPLATES; 21 import static android.net.vcn.VcnGatewayConnectionConfig.UNDERLYING_NETWORK_TEMPLATES_KEY; 22 import static android.net.vcn.VcnGatewayConnectionConfig.VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY; 23 24 import static org.junit.Assert.assertArrayEquals; 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertFalse; 27 import static org.junit.Assert.assertNotEquals; 28 import static org.junit.Assert.assertNotSame; 29 import static org.junit.Assert.assertTrue; 30 import static org.junit.Assert.fail; 31 32 import android.net.NetworkCapabilities; 33 import android.net.ipsec.ike.IkeSessionParams; 34 import android.net.ipsec.ike.IkeTunnelConnectionParams; 35 import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest; 36 import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest; 37 import android.os.PersistableBundle; 38 39 import androidx.test.filters.SmallTest; 40 import androidx.test.runner.AndroidJUnit4; 41 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 45 import java.util.ArrayList; 46 import java.util.Arrays; 47 import java.util.Collections; 48 import java.util.List; 49 import java.util.Set; 50 import java.util.concurrent.TimeUnit; 51 52 @RunWith(AndroidJUnit4.class) 53 @SmallTest 54 public class VcnGatewayConnectionConfigTest { 55 // Public for use in VcnGatewayConnectionTest 56 public static final int[] EXPOSED_CAPS = 57 new int[] { 58 NetworkCapabilities.NET_CAPABILITY_INTERNET, NetworkCapabilities.NET_CAPABILITY_MMS 59 }; 60 public static final int[] UNDERLYING_CAPS = new int[] {NetworkCapabilities.NET_CAPABILITY_DUN}; 61 62 private static final List<VcnUnderlyingNetworkTemplate> UNDERLYING_NETWORK_TEMPLATES = 63 new ArrayList(); 64 65 static { 66 Arrays.sort(EXPOSED_CAPS); 67 Arrays.sort(UNDERLYING_CAPS); 68 69 UNDERLYING_NETWORK_TEMPLATES.add( VcnCellUnderlyingNetworkTemplateTest.getTestNetworkTemplate()70 VcnCellUnderlyingNetworkTemplateTest.getTestNetworkTemplate()); 71 UNDERLYING_NETWORK_TEMPLATES.add( VcnWifiUnderlyingNetworkTemplateTest.getTestNetworkTemplate()72 VcnWifiUnderlyingNetworkTemplateTest.getTestNetworkTemplate()); 73 } 74 75 public static final long[] RETRY_INTERVALS_MS = 76 new long[] { 77 TimeUnit.SECONDS.toMillis(5), 78 TimeUnit.SECONDS.toMillis(30), 79 TimeUnit.MINUTES.toMillis(1), 80 TimeUnit.MINUTES.toMillis(5), 81 TimeUnit.MINUTES.toMillis(15), 82 TimeUnit.MINUTES.toMillis(30) 83 }; 84 public static final int MAX_MTU = 1360; 85 public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT = 120; 86 87 private static final Set<Integer> GATEWAY_OPTIONS = 88 Collections.singleton(VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY); 89 90 public static final IkeTunnelConnectionParams TUNNEL_CONNECTION_PARAMS = 91 TunnelConnectionParamsUtilsTest.buildTestParams(); 92 93 public static final String GATEWAY_CONNECTION_NAME_PREFIX = "gatewayConnectionName-"; 94 private static int sGatewayConnectionConfigCount = 0; 95 buildTestConfig( String gatewayConnectionName, IkeTunnelConnectionParams tunnelConnectionParams)96 private static VcnGatewayConnectionConfig buildTestConfig( 97 String gatewayConnectionName, IkeTunnelConnectionParams tunnelConnectionParams) { 98 return buildTestConfigWithExposedCaps( 99 new VcnGatewayConnectionConfig.Builder( 100 gatewayConnectionName, tunnelConnectionParams), 101 EXPOSED_CAPS); 102 } 103 104 // Public for use in UnderlyingNetworkControllerTest buildTestConfig( List<VcnUnderlyingNetworkTemplate> nwTemplates)105 public static VcnGatewayConnectionConfig buildTestConfig( 106 List<VcnUnderlyingNetworkTemplate> nwTemplates) { 107 final VcnGatewayConnectionConfig.Builder builder = 108 newBuilder() 109 .setVcnUnderlyingNetworkPriorities(nwTemplates) 110 .setMinUdpPort4500NatTimeoutSeconds(MIN_UDP_PORT_4500_NAT_TIMEOUT); 111 112 return buildTestConfigWithExposedCaps(builder, EXPOSED_CAPS); 113 } 114 115 // Public for use in VcnGatewayConnectionTest buildTestConfig()116 public static VcnGatewayConnectionConfig buildTestConfig() { 117 return buildTestConfig(UNDERLYING_NETWORK_TEMPLATES); 118 } 119 120 // Public for use in VcnGatewayConnectionTest newTestBuilderMinimal()121 public static VcnGatewayConnectionConfig.Builder newTestBuilderMinimal() { 122 final VcnGatewayConnectionConfig.Builder builder = newBuilder(); 123 for (int caps : EXPOSED_CAPS) { 124 builder.addExposedCapability(caps); 125 } 126 127 return builder; 128 } 129 newBuilder()130 private static VcnGatewayConnectionConfig.Builder newBuilder() { 131 // Append a unique identifier to the name prefix to guarantee that all created 132 // VcnGatewayConnectionConfigs have a unique name (required by VcnConfig). 133 return new VcnGatewayConnectionConfig.Builder( 134 GATEWAY_CONNECTION_NAME_PREFIX + sGatewayConnectionConfigCount++, 135 TUNNEL_CONNECTION_PARAMS); 136 } 137 newBuilderMinimal()138 private static VcnGatewayConnectionConfig.Builder newBuilderMinimal() { 139 final VcnGatewayConnectionConfig.Builder builder = 140 new VcnGatewayConnectionConfig.Builder( 141 "newBuilderMinimal", TUNNEL_CONNECTION_PARAMS); 142 for (int caps : EXPOSED_CAPS) { 143 builder.addExposedCapability(caps); 144 } 145 146 return builder; 147 } 148 buildTestConfigWithExposedCapsAndOptions( VcnGatewayConnectionConfig.Builder builder, Set<Integer> gatewayOptions, int... exposedCaps)149 private static VcnGatewayConnectionConfig buildTestConfigWithExposedCapsAndOptions( 150 VcnGatewayConnectionConfig.Builder builder, 151 Set<Integer> gatewayOptions, 152 int... exposedCaps) { 153 builder.setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU); 154 155 for (int option : gatewayOptions) { 156 builder.addGatewayOption(option); 157 } 158 159 for (int caps : exposedCaps) { 160 builder.addExposedCapability(caps); 161 } 162 163 return builder.build(); 164 } 165 buildTestConfigWithExposedCaps( VcnGatewayConnectionConfig.Builder builder, int... exposedCaps)166 private static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps( 167 VcnGatewayConnectionConfig.Builder builder, int... exposedCaps) { 168 return buildTestConfigWithExposedCapsAndOptions( 169 builder, Collections.emptySet(), exposedCaps); 170 } 171 172 // Public for use in VcnGatewayConnectionTest buildTestConfigWithExposedCaps(int... exposedCaps)173 public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) { 174 return buildTestConfigWithExposedCaps(newBuilder(), exposedCaps); 175 } 176 buildTestConfigWithGatewayOptions( VcnGatewayConnectionConfig.Builder builder, Set<Integer> gatewayOptions)177 private static VcnGatewayConnectionConfig buildTestConfigWithGatewayOptions( 178 VcnGatewayConnectionConfig.Builder builder, Set<Integer> gatewayOptions) { 179 return buildTestConfigWithExposedCapsAndOptions(builder, gatewayOptions, EXPOSED_CAPS); 180 } 181 182 // Public for use in VcnGatewayConnectionTest buildTestConfigWithGatewayOptions( Set<Integer> gatewayOptions)183 public static VcnGatewayConnectionConfig buildTestConfigWithGatewayOptions( 184 Set<Integer> gatewayOptions) { 185 return buildTestConfigWithExposedCapsAndOptions(newBuilder(), gatewayOptions, EXPOSED_CAPS); 186 } 187 188 @Test testBuilderRequiresNonNullGatewayConnectionName()189 public void testBuilderRequiresNonNullGatewayConnectionName() { 190 try { 191 new VcnGatewayConnectionConfig.Builder( 192 null /* gatewayConnectionName */, TUNNEL_CONNECTION_PARAMS) 193 .build(); 194 195 fail("Expected exception due to invalid gateway connection name"); 196 } catch (NullPointerException e) { 197 } 198 } 199 200 @Test testBuilderRequiresNonNullTunnelConnectionParams()201 public void testBuilderRequiresNonNullTunnelConnectionParams() { 202 try { 203 new VcnGatewayConnectionConfig.Builder( 204 GATEWAY_CONNECTION_NAME_PREFIX, null /* tunnelConnectionParams */) 205 .build(); 206 207 fail("Expected exception due to the absence of tunnel connection parameters"); 208 } catch (NullPointerException e) { 209 } 210 } 211 212 @Test testBuilderRequiresMobikeEnabled()213 public void testBuilderRequiresMobikeEnabled() { 214 try { 215 final IkeSessionParams ikeParams = 216 IkeSessionParamsUtilsTest.createBuilderMinimum() 217 .removeIkeOption(IKE_OPTION_MOBIKE) 218 .build(); 219 final IkeTunnelConnectionParams tunnelParams = 220 TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams); 221 new VcnGatewayConnectionConfig.Builder(GATEWAY_CONNECTION_NAME_PREFIX, tunnelParams); 222 fail("Expected exception due to MOBIKE not enabled"); 223 } catch (IllegalArgumentException e) { 224 } 225 } 226 227 @Test testBuilderRequiresNonEmptyExposedCaps()228 public void testBuilderRequiresNonEmptyExposedCaps() { 229 try { 230 newBuilder().build(); 231 232 fail("Expected exception due to invalid exposed capabilities"); 233 } catch (IllegalArgumentException e) { 234 } 235 } 236 237 @Test testBuilderRequiresNonNullNetworkTemplates()238 public void testBuilderRequiresNonNullNetworkTemplates() { 239 try { 240 newBuilder().setVcnUnderlyingNetworkPriorities(null); 241 fail("Expected exception due to invalid underlyingNetworkTemplates"); 242 } catch (NullPointerException e) { 243 } 244 } 245 246 @Test testBuilderRequiresNonNullRetryInterval()247 public void testBuilderRequiresNonNullRetryInterval() { 248 try { 249 newBuilder().setRetryIntervalsMillis(null); 250 fail("Expected exception due to invalid retryIntervalMs"); 251 } catch (IllegalArgumentException e) { 252 } 253 } 254 255 @Test testBuilderRequiresNonEmptyRetryInterval()256 public void testBuilderRequiresNonEmptyRetryInterval() { 257 try { 258 newBuilder().setRetryIntervalsMillis(new long[0]); 259 fail("Expected exception due to invalid retryIntervalMs"); 260 } catch (IllegalArgumentException e) { 261 } 262 } 263 264 @Test testBuilderRequiresValidMtu()265 public void testBuilderRequiresValidMtu() { 266 try { 267 newBuilder().setMaxMtu(VcnGatewayConnectionConfig.MIN_MTU_V6 - 1); 268 fail("Expected exception due to invalid mtu"); 269 } catch (IllegalArgumentException e) { 270 } 271 } 272 273 @Test testBuilderRequiresValidOption()274 public void testBuilderRequiresValidOption() { 275 try { 276 newBuilder().addGatewayOption(-1); 277 fail("Expected exception due to the invalid VCN gateway option"); 278 } catch (IllegalArgumentException e) { 279 } 280 } 281 282 @Test testBuilderAndGetters()283 public void testBuilderAndGetters() { 284 final VcnGatewayConnectionConfig config = buildTestConfig(); 285 286 assertTrue(config.getGatewayConnectionName().startsWith(GATEWAY_CONNECTION_NAME_PREFIX)); 287 288 int[] exposedCaps = config.getExposedCapabilities(); 289 Arrays.sort(exposedCaps); 290 assertArrayEquals(EXPOSED_CAPS, exposedCaps); 291 292 assertEquals(UNDERLYING_NETWORK_TEMPLATES, config.getVcnUnderlyingNetworkPriorities()); 293 assertEquals(TUNNEL_CONNECTION_PARAMS, config.getTunnelConnectionParams()); 294 295 assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMillis()); 296 assertEquals(MAX_MTU, config.getMaxMtu()); 297 assertTrue(config.isSafeModeEnabled()); 298 299 assertFalse( 300 config.hasGatewayOption( 301 VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY)); 302 } 303 304 @Test testBuilderAndGettersWithOptions()305 public void testBuilderAndGettersWithOptions() { 306 final VcnGatewayConnectionConfig config = 307 buildTestConfigWithGatewayOptions(GATEWAY_OPTIONS); 308 309 for (int option : GATEWAY_OPTIONS) { 310 assertTrue(config.hasGatewayOption(option)); 311 } 312 } 313 314 @Test testBuilderAndGettersSafeModeDisabled()315 public void testBuilderAndGettersSafeModeDisabled() { 316 final VcnGatewayConnectionConfig config = 317 newBuilderMinimal().setSafeModeEnabled(false).build(); 318 319 assertFalse(config.isSafeModeEnabled()); 320 } 321 322 @Test testPersistableBundle()323 public void testPersistableBundle() { 324 final VcnGatewayConnectionConfig config = buildTestConfig(); 325 326 assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle())); 327 } 328 329 @Test testPersistableBundleWithOptions()330 public void testPersistableBundleWithOptions() { 331 final VcnGatewayConnectionConfig config = 332 buildTestConfigWithGatewayOptions(GATEWAY_OPTIONS); 333 334 assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle())); 335 } 336 337 @Test testPersistableBundleSafeModeDisabled()338 public void testPersistableBundleSafeModeDisabled() { 339 final VcnGatewayConnectionConfig config = 340 newBuilderMinimal().setSafeModeEnabled(false).build(); 341 342 assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle())); 343 } 344 345 @Test testParsePersistableBundleWithoutVcnUnderlyingNetworkTemplates()346 public void testParsePersistableBundleWithoutVcnUnderlyingNetworkTemplates() { 347 PersistableBundle configBundle = buildTestConfig().toPersistableBundle(); 348 configBundle.putPersistableBundle(UNDERLYING_NETWORK_TEMPLATES_KEY, null); 349 350 final VcnGatewayConnectionConfig config = new VcnGatewayConnectionConfig(configBundle); 351 assertEquals( 352 DEFAULT_UNDERLYING_NETWORK_TEMPLATES, config.getVcnUnderlyingNetworkPriorities()); 353 } 354 buildTunnelConnectionParams(String ikePsk)355 private static IkeTunnelConnectionParams buildTunnelConnectionParams(String ikePsk) { 356 final IkeSessionParams ikeParams = 357 IkeSessionParamsUtilsTest.createBuilderMinimum() 358 .setAuthPsk(ikePsk.getBytes()) 359 .build(); 360 return TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams); 361 } 362 363 @Test testTunnelConnectionParamsEquals()364 public void testTunnelConnectionParamsEquals() throws Exception { 365 final String connectionName = "testTunnelConnectionParamsEquals.connectionName"; 366 final String psk = "testTunnelConnectionParamsEquals.psk"; 367 368 final IkeTunnelConnectionParams tunnelParams = buildTunnelConnectionParams(psk); 369 final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams); 370 371 final IkeTunnelConnectionParams anotherTunnelParams = buildTunnelConnectionParams(psk); 372 final VcnGatewayConnectionConfig anotherConfig = 373 buildTestConfig(connectionName, anotherTunnelParams); 374 375 assertNotSame(tunnelParams, anotherTunnelParams); 376 assertEquals(tunnelParams, anotherTunnelParams); 377 assertEquals(config, anotherConfig); 378 } 379 380 @Test testTunnelConnectionParamsNotEquals()381 public void testTunnelConnectionParamsNotEquals() throws Exception { 382 final String connectionName = "testTunnelConnectionParamsNotEquals.connectionName"; 383 384 final IkeTunnelConnectionParams tunnelParams = 385 buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskA"); 386 final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams); 387 388 final IkeTunnelConnectionParams anotherTunnelParams = 389 buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskB"); 390 final VcnGatewayConnectionConfig anotherConfig = 391 buildTestConfig(connectionName, anotherTunnelParams); 392 393 assertNotEquals(tunnelParams, anotherTunnelParams); 394 assertNotEquals(config, anotherConfig); 395 } 396 buildTestConfigWithVcnUnderlyingNetworkTemplates( List<VcnUnderlyingNetworkTemplate> networkTemplates)397 private static VcnGatewayConnectionConfig buildTestConfigWithVcnUnderlyingNetworkTemplates( 398 List<VcnUnderlyingNetworkTemplate> networkTemplates) { 399 return buildTestConfigWithExposedCaps( 400 new VcnGatewayConnectionConfig.Builder( 401 "buildTestConfigWithVcnUnderlyingNetworkTemplates", 402 TUNNEL_CONNECTION_PARAMS) 403 .setVcnUnderlyingNetworkPriorities(networkTemplates), 404 EXPOSED_CAPS); 405 } 406 407 @Test testVcnUnderlyingNetworkTemplatesEquality()408 public void testVcnUnderlyingNetworkTemplatesEquality() throws Exception { 409 final VcnGatewayConnectionConfig config = 410 buildTestConfigWithVcnUnderlyingNetworkTemplates(UNDERLYING_NETWORK_TEMPLATES); 411 412 final List<VcnUnderlyingNetworkTemplate> networkTemplatesEqual = new ArrayList(); 413 networkTemplatesEqual.add(VcnCellUnderlyingNetworkTemplateTest.getTestNetworkTemplate()); 414 networkTemplatesEqual.add(VcnWifiUnderlyingNetworkTemplateTest.getTestNetworkTemplate()); 415 final VcnGatewayConnectionConfig configEqual = 416 buildTestConfigWithVcnUnderlyingNetworkTemplates(networkTemplatesEqual); 417 418 final List<VcnUnderlyingNetworkTemplate> networkTemplatesNotEqual = new ArrayList(); 419 networkTemplatesNotEqual.add(VcnWifiUnderlyingNetworkTemplateTest.getTestNetworkTemplate()); 420 final VcnGatewayConnectionConfig configNotEqual = 421 buildTestConfigWithVcnUnderlyingNetworkTemplates(networkTemplatesNotEqual); 422 423 assertEquals(UNDERLYING_NETWORK_TEMPLATES, networkTemplatesEqual); 424 assertEquals(config, configEqual); 425 426 assertNotEquals(UNDERLYING_NETWORK_TEMPLATES, networkTemplatesNotEqual); 427 assertNotEquals(config, configNotEqual); 428 } 429 buildConfigWithGatewayOptionsForEqualityTest( Set<Integer> gatewayOptions)430 private static VcnGatewayConnectionConfig buildConfigWithGatewayOptionsForEqualityTest( 431 Set<Integer> gatewayOptions) { 432 return buildTestConfigWithGatewayOptions( 433 new VcnGatewayConnectionConfig.Builder( 434 "buildConfigWithGatewayOptionsForEqualityTest", TUNNEL_CONNECTION_PARAMS), 435 gatewayOptions); 436 } 437 438 @Test testVcnGatewayOptionsEquality()439 public void testVcnGatewayOptionsEquality() throws Exception { 440 final VcnGatewayConnectionConfig config = 441 buildConfigWithGatewayOptionsForEqualityTest(GATEWAY_OPTIONS); 442 443 final VcnGatewayConnectionConfig configEqual = 444 buildConfigWithGatewayOptionsForEqualityTest(GATEWAY_OPTIONS); 445 446 final VcnGatewayConnectionConfig configNotEqual = 447 buildConfigWithGatewayOptionsForEqualityTest(Collections.emptySet()); 448 449 assertEquals(config, configEqual); 450 assertNotEquals(config, configNotEqual); 451 } 452 453 @Test testSafeModeEnableDisableEquality()454 public void testSafeModeEnableDisableEquality() throws Exception { 455 final VcnGatewayConnectionConfig config = newBuilderMinimal().build(); 456 final VcnGatewayConnectionConfig configEqual = newBuilderMinimal().build(); 457 458 assertEquals(config.isSafeModeEnabled(), configEqual.isSafeModeEnabled()); 459 460 final VcnGatewayConnectionConfig configNotEqual = 461 newBuilderMinimal().setSafeModeEnabled(false).build(); 462 463 assertEquals(config, configEqual); 464 assertNotEquals(config, configNotEqual); 465 } 466 } 467