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 com.android.server.vcn; 18 19 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; 20 21 import static com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; 22 import static com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; 23 import static com.android.server.vcn.VcnTestUtils.setupIpSecManager; 24 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertNull; 27 import static org.mockito.Matchers.any; 28 import static org.mockito.Matchers.eq; 29 import static org.mockito.Mockito.CALLS_REAL_METHODS; 30 import static org.mockito.Mockito.atLeastOnce; 31 import static org.mockito.Mockito.doReturn; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.times; 35 import static org.mockito.Mockito.verify; 36 import static org.mockito.Mockito.verifyNoMoreInteractions; 37 38 import android.annotation.NonNull; 39 import android.content.Context; 40 import android.net.ConnectivityDiagnosticsManager; 41 import android.net.ConnectivityManager; 42 import android.net.InetAddresses; 43 import android.net.IpSecConfig; 44 import android.net.IpSecManager; 45 import android.net.IpSecTransform; 46 import android.net.IpSecTunnelInterfaceResponse; 47 import android.net.LinkAddress; 48 import android.net.LinkProperties; 49 import android.net.Network; 50 import android.net.NetworkCapabilities; 51 import android.net.TelephonyNetworkSpecifier; 52 import android.net.ipsec.ike.ChildSessionCallback; 53 import android.net.ipsec.ike.IkeSessionCallback; 54 import android.net.ipsec.ike.IkeSessionConfiguration; 55 import android.net.ipsec.ike.IkeSessionConnectionInfo; 56 import android.net.vcn.FeatureFlags; 57 import android.net.vcn.VcnGatewayConnectionConfig; 58 import android.net.vcn.VcnGatewayConnectionConfigTest; 59 import android.os.ParcelUuid; 60 import android.os.PowerManager; 61 import android.os.test.TestLooper; 62 import android.telephony.SubscriptionInfo; 63 64 import com.android.internal.util.State; 65 import com.android.internal.util.WakeupMessage; 66 import com.android.server.IpSecService; 67 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot; 68 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback; 69 import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionCallback; 70 import com.android.server.vcn.VcnGatewayConnection.VcnIkeSession; 71 import com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent; 72 import com.android.server.vcn.VcnGatewayConnection.VcnWakeLock; 73 import com.android.server.vcn.routeselection.UnderlyingNetworkController; 74 import com.android.server.vcn.routeselection.UnderlyingNetworkRecord; 75 76 import org.junit.Before; 77 import org.mockito.ArgumentCaptor; 78 79 import java.net.InetAddress; 80 import java.util.Collections; 81 import java.util.UUID; 82 import java.util.concurrent.TimeUnit; 83 84 public class VcnGatewayConnectionTestBase { 85 protected static final ParcelUuid TEST_SUB_GRP = new ParcelUuid(UUID.randomUUID()); 86 protected static final SubscriptionInfo TEST_SUB_INFO = mock(SubscriptionInfo.class); 87 88 static { 89 doReturn(TEST_SUB_GRP).when(TEST_SUB_INFO).getGroupUuid(); 90 } 91 92 protected static final InetAddress TEST_ADDR = InetAddresses.parseNumericAddress("2001:db8::1"); 93 protected static final InetAddress TEST_ADDR_2 = 94 InetAddresses.parseNumericAddress("2001:db8::2"); 95 protected static final InetAddress TEST_ADDR_V4 = 96 InetAddresses.parseNumericAddress("192.0.2.1"); 97 protected static final InetAddress TEST_ADDR_V4_2 = 98 InetAddresses.parseNumericAddress("192.0.2.2"); 99 protected static final InetAddress TEST_DNS_ADDR = 100 InetAddresses.parseNumericAddress("2001:DB8:0:1::"); 101 protected static final InetAddress TEST_DNS_ADDR_2 = 102 InetAddresses.parseNumericAddress("2001:DB8:0:2::"); 103 protected static final LinkAddress TEST_INTERNAL_ADDR = 104 new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:1::"), 64); 105 protected static final LinkAddress TEST_INTERNAL_ADDR_2 = 106 new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:2::"), 64); 107 protected static final LinkAddress TEST_INTERNAL_ADDR_3 = 108 new LinkAddress(InetAddresses.parseNumericAddress("2001:DB8:1:3::"), 64); 109 110 protected static final int TEST_IPSEC_SPI_VALUE = 0x1234; 111 protected static final int TEST_IPSEC_SPI_RESOURCE_ID = 1; 112 protected static final int TEST_IPSEC_TRANSFORM_RESOURCE_ID = 2; 113 protected static final int TEST_IPSEC_TUNNEL_RESOURCE_ID = 3; 114 protected static final int TEST_SUB_ID = 5; 115 protected static final long ELAPSED_REAL_TIME = 123456789L; 116 protected static final String TEST_IPSEC_TUNNEL_IFACE = "IPSEC_IFACE"; 117 getTestNetworkRecord( Network network, NetworkCapabilities networkCapabilities, LinkProperties linkProperties, boolean isBlocked)118 protected static UnderlyingNetworkRecord getTestNetworkRecord( 119 Network network, 120 NetworkCapabilities networkCapabilities, 121 LinkProperties linkProperties, 122 boolean isBlocked) { 123 return new UnderlyingNetworkRecord(network, networkCapabilities, linkProperties, isBlocked); 124 } 125 126 protected static final String TEST_TCP_BUFFER_SIZES_1 = "1,2,3,4"; 127 protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 = 128 getTestNetworkRecord( 129 mock(Network.class, CALLS_REAL_METHODS), 130 new NetworkCapabilities.Builder() 131 .addTransportType(TRANSPORT_CELLULAR) 132 .setNetworkSpecifier(new TelephonyNetworkSpecifier(TEST_SUB_ID)) 133 .build(), 134 new LinkProperties(), 135 false /* blocked */); 136 137 static { 138 TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.setMtu(1500); 139 TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.setTcpBufferSizes(TEST_TCP_BUFFER_SIZES_1); 140 } 141 142 protected static final String TEST_TCP_BUFFER_SIZES_2 = "2,3,4,5"; 143 protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_2 = 144 getTestNetworkRecord( 145 mock(Network.class, CALLS_REAL_METHODS), 146 new NetworkCapabilities(), 147 new LinkProperties(), 148 false /* blocked */); 149 150 static { 151 TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.setMtu(1460); 152 TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.setTcpBufferSizes(TEST_TCP_BUFFER_SIZES_2); 153 } 154 155 protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT = 156 new TelephonySubscriptionSnapshot( 157 TEST_SUB_ID, 158 Collections.singletonMap(TEST_SUB_ID, TEST_SUB_INFO), 159 Collections.EMPTY_MAP, 160 Collections.EMPTY_MAP); 161 162 @NonNull protected final Context mContext; 163 @NonNull protected final TestLooper mTestLooper; 164 @NonNull protected final VcnNetworkProvider mVcnNetworkProvider; 165 @NonNull protected final FeatureFlags mFeatureFlags; 166 @NonNull protected final VcnContext mVcnContext; 167 @NonNull protected final VcnGatewayConnectionConfig mConfig; 168 @NonNull protected final VcnGatewayStatusCallback mGatewayStatusCallback; 169 @NonNull protected final VcnGatewayConnection.Dependencies mDeps; 170 @NonNull protected final UnderlyingNetworkController mUnderlyingNetworkController; 171 @NonNull protected final VcnWakeLock mWakeLock; 172 @NonNull protected final WakeupMessage mTeardownTimeoutAlarm; 173 @NonNull protected final WakeupMessage mDisconnectRequestAlarm; 174 @NonNull protected final WakeupMessage mRetryTimeoutAlarm; 175 @NonNull protected final WakeupMessage mSafeModeTimeoutAlarm; 176 177 @NonNull protected final IpSecService mIpSecSvc; 178 @NonNull protected final ConnectivityManager mConnMgr; 179 @NonNull protected final ConnectivityDiagnosticsManager mConnDiagMgr; 180 181 @NonNull protected final IkeSessionConnectionInfo mIkeConnectionInfo; 182 @NonNull protected final IkeSessionConfiguration mIkeSessionConfiguration; 183 184 protected VcnIkeSession mMockIkeSession; 185 protected VcnGatewayConnection mGatewayConnection; 186 VcnGatewayConnectionTestBase()187 public VcnGatewayConnectionTestBase() { 188 mContext = mock(Context.class); 189 mTestLooper = new TestLooper(); 190 mVcnNetworkProvider = mock(VcnNetworkProvider.class); 191 mFeatureFlags = mock(FeatureFlags.class); 192 mVcnContext = mock(VcnContext.class); 193 mConfig = VcnGatewayConnectionConfigTest.buildTestConfig(); 194 mGatewayStatusCallback = mock(VcnGatewayStatusCallback.class); 195 mDeps = mock(VcnGatewayConnection.Dependencies.class); 196 mUnderlyingNetworkController = mock(UnderlyingNetworkController.class); 197 mWakeLock = mock(VcnWakeLock.class); 198 mTeardownTimeoutAlarm = mock(WakeupMessage.class); 199 mDisconnectRequestAlarm = mock(WakeupMessage.class); 200 mRetryTimeoutAlarm = mock(WakeupMessage.class); 201 mSafeModeTimeoutAlarm = mock(WakeupMessage.class); 202 203 mIpSecSvc = mock(IpSecService.class); 204 setupIpSecManager(mContext, mIpSecSvc); 205 206 mConnMgr = mock(ConnectivityManager.class); 207 VcnTestUtils.setupSystemService( 208 mContext, mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); 209 210 mConnDiagMgr = mock(ConnectivityDiagnosticsManager.class); 211 VcnTestUtils.setupSystemService( 212 mContext, 213 mConnDiagMgr, 214 Context.CONNECTIVITY_DIAGNOSTICS_SERVICE, 215 ConnectivityDiagnosticsManager.class); 216 217 mIkeConnectionInfo = 218 new IkeSessionConnectionInfo(TEST_ADDR, TEST_ADDR_2, mock(Network.class)); 219 mIkeSessionConfiguration = new IkeSessionConfiguration.Builder(mIkeConnectionInfo).build(); 220 221 doReturn(mContext).when(mVcnContext).getContext(); 222 doReturn(mTestLooper.getLooper()).when(mVcnContext).getLooper(); 223 doReturn(mVcnNetworkProvider).when(mVcnContext).getVcnNetworkProvider(); 224 doReturn(mFeatureFlags).when(mVcnContext).getFeatureFlags(); 225 doReturn(true).when(mVcnContext).isFlagSafeModeTimeoutConfigEnabled(); 226 doReturn(true).when(mVcnContext).isFlagIpSecTransformStateEnabled(); 227 doReturn(true).when(mVcnContext).isFlagNetworkMetricMonitorEnabled(); 228 229 doReturn(mUnderlyingNetworkController) 230 .when(mDeps) 231 .newUnderlyingNetworkController(any(), any(), any(), any(), any()); 232 doReturn(mWakeLock) 233 .when(mDeps) 234 .newWakeLock(eq(mContext), eq(PowerManager.PARTIAL_WAKE_LOCK), any()); 235 doReturn(1) 236 .when(mDeps) 237 .getParallelTunnelCount(eq(TEST_SUBSCRIPTION_SNAPSHOT), eq(TEST_SUB_GRP)); 238 239 setUpWakeupMessage(mTeardownTimeoutAlarm, VcnGatewayConnection.TEARDOWN_TIMEOUT_ALARM); 240 setUpWakeupMessage(mDisconnectRequestAlarm, VcnGatewayConnection.DISCONNECT_REQUEST_ALARM); 241 setUpWakeupMessage(mRetryTimeoutAlarm, VcnGatewayConnection.RETRY_TIMEOUT_ALARM); 242 setUpWakeupMessage(mSafeModeTimeoutAlarm, VcnGatewayConnection.SAFEMODE_TIMEOUT_ALARM); 243 244 doReturn(ELAPSED_REAL_TIME).when(mDeps).getElapsedRealTime(); 245 } 246 setUpWakeupMessage( @onNull WakeupMessage msg, @NonNull String cmdName, VcnGatewayConnection.Dependencies deps)247 protected void setUpWakeupMessage( 248 @NonNull WakeupMessage msg, 249 @NonNull String cmdName, 250 VcnGatewayConnection.Dependencies deps) { 251 doReturn(msg).when(deps).newWakeupMessage(eq(mVcnContext), any(), eq(cmdName), any()); 252 } 253 setUpWakeupMessage(@onNull WakeupMessage msg, @NonNull String cmdName)254 private void setUpWakeupMessage(@NonNull WakeupMessage msg, @NonNull String cmdName) { 255 setUpWakeupMessage(msg, cmdName, mDeps); 256 } 257 258 @Before setUp()259 public void setUp() throws Exception { 260 IpSecTunnelInterfaceResponse resp = 261 new IpSecTunnelInterfaceResponse( 262 IpSecManager.Status.OK, 263 TEST_IPSEC_TUNNEL_RESOURCE_ID, 264 TEST_IPSEC_TUNNEL_IFACE); 265 doReturn(resp).when(mIpSecSvc).createTunnelInterface(any(), any(), any(), any(), any()); 266 267 mMockIkeSession = mock(VcnIkeSession.class); 268 doReturn(mMockIkeSession).when(mDeps).newIkeSession(any(), any(), any(), any(), any()); 269 270 mGatewayConnection = 271 new VcnGatewayConnection( 272 mVcnContext, 273 TEST_SUB_GRP, 274 TEST_SUBSCRIPTION_SNAPSHOT, 275 mConfig, 276 mGatewayStatusCallback, 277 true /* isMobileDataEnabled */, 278 mDeps); 279 } 280 makeDummyIpSecTransform()281 protected IpSecTransform makeDummyIpSecTransform() throws Exception { 282 return new IpSecTransform(mContext, new IpSecConfig()); 283 } 284 getIkeSessionCallback()285 protected IkeSessionCallback getIkeSessionCallback() { 286 ArgumentCaptor<IkeSessionCallback> captor = 287 ArgumentCaptor.forClass(IkeSessionCallback.class); 288 verify(mDeps).newIkeSession(any(), any(), any(), captor.capture(), any()); 289 return captor.getValue(); 290 } 291 getChildSessionCallback()292 protected VcnChildSessionCallback getChildSessionCallback() { 293 ArgumentCaptor<ChildSessionCallback> captor = 294 ArgumentCaptor.forClass(ChildSessionCallback.class); 295 verify(mDeps, atLeastOnce()).newIkeSession(any(), any(), any(), any(), captor.capture()); 296 return (VcnChildSessionCallback) captor.getValue(); 297 } 298 verifyWakeLockSetUp()299 protected void verifyWakeLockSetUp() { 300 verify(mDeps).newWakeLock(eq(mContext), eq(PowerManager.PARTIAL_WAKE_LOCK), any()); 301 verifyNoMoreInteractions(mWakeLock); 302 } 303 verifyWakeLockAcquired()304 protected void verifyWakeLockAcquired() { 305 verify(mWakeLock).acquire(); 306 verifyNoMoreInteractions(mWakeLock); 307 } 308 verifyWakeLockReleased()309 protected void verifyWakeLockReleased() { 310 verify(mWakeLock).release(); 311 verifyNoMoreInteractions(mWakeLock); 312 } 313 verifyWakeupMessageSetUpAndGetCallback( @onNull String tag, @NonNull WakeupMessage msg, long delayInMillis, boolean expectCanceled)314 private Runnable verifyWakeupMessageSetUpAndGetCallback( 315 @NonNull String tag, 316 @NonNull WakeupMessage msg, 317 long delayInMillis, 318 boolean expectCanceled) { 319 ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); 320 verify(mDeps).newWakeupMessage(eq(mVcnContext), any(), eq(tag), runnableCaptor.capture()); 321 322 verify(mDeps, atLeastOnce()).getElapsedRealTime(); 323 verify(msg).schedule(ELAPSED_REAL_TIME + delayInMillis); 324 verify(msg, expectCanceled ? times(1) : never()).cancel(); 325 326 return runnableCaptor.getValue(); 327 } 328 verifyTeardownTimeoutAlarmAndGetCallback(boolean expectCanceled)329 protected Runnable verifyTeardownTimeoutAlarmAndGetCallback(boolean expectCanceled) { 330 return verifyWakeupMessageSetUpAndGetCallback( 331 VcnGatewayConnection.TEARDOWN_TIMEOUT_ALARM, 332 mTeardownTimeoutAlarm, 333 TimeUnit.SECONDS.toMillis(VcnGatewayConnection.TEARDOWN_TIMEOUT_SECONDS), 334 expectCanceled); 335 } 336 verifyDisconnectRequestAlarmAndGetCallback(boolean expectCanceled)337 protected Runnable verifyDisconnectRequestAlarmAndGetCallback(boolean expectCanceled) { 338 return verifyWakeupMessageSetUpAndGetCallback( 339 VcnGatewayConnection.DISCONNECT_REQUEST_ALARM, 340 mDisconnectRequestAlarm, 341 TimeUnit.SECONDS.toMillis( 342 VcnGatewayConnection.NETWORK_LOSS_DISCONNECT_TIMEOUT_SECONDS), 343 expectCanceled); 344 } 345 verifyRetryTimeoutAlarmAndGetCallback( long delayInMillis, boolean expectCanceled)346 protected Runnable verifyRetryTimeoutAlarmAndGetCallback( 347 long delayInMillis, boolean expectCanceled) { 348 return verifyWakeupMessageSetUpAndGetCallback( 349 VcnGatewayConnection.RETRY_TIMEOUT_ALARM, 350 mRetryTimeoutAlarm, 351 delayInMillis, 352 expectCanceled); 353 } 354 verifySafeModeTimeoutAlarmAndGetCallback(boolean expectCanceled)355 protected Runnable verifySafeModeTimeoutAlarmAndGetCallback(boolean expectCanceled) { 356 return verifyWakeupMessageSetUpAndGetCallback( 357 VcnGatewayConnection.SAFEMODE_TIMEOUT_ALARM, 358 mSafeModeTimeoutAlarm, 359 TimeUnit.SECONDS.toMillis(VcnGatewayConnection.SAFEMODE_TIMEOUT_SECONDS), 360 expectCanceled); 361 } 362 verifySafeModeStateAndCallbackFired(int invocationCount, boolean isInSafeMode)363 protected void verifySafeModeStateAndCallbackFired(int invocationCount, boolean isInSafeMode) { 364 verify(mGatewayStatusCallback, times(invocationCount)).onSafeModeStatusChanged(); 365 assertEquals(isInSafeMode, mGatewayConnection.isInSafeMode()); 366 } 367 verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent( @onNull State expectedState)368 protected void verifySafeModeTimeoutNotifiesCallbackAndUnregistersNetworkAgent( 369 @NonNull State expectedState) { 370 // Set a VcnNetworkAgent, and expect it to be unregistered and cleared 371 final VcnNetworkAgent mockNetworkAgent = mock(VcnNetworkAgent.class); 372 mGatewayConnection.setNetworkAgent(mockNetworkAgent); 373 374 // SafeMode timer starts when VcnGatewayConnection exits DisconnectedState (the initial 375 // state) 376 final Runnable delayedEvent = 377 verifySafeModeTimeoutAlarmAndGetCallback(false /* expectCanceled */); 378 delayedEvent.run(); 379 mTestLooper.dispatchAll(); 380 381 assertEquals(expectedState, mGatewayConnection.getCurrentState()); 382 verifySafeModeStateAndCallbackFired(1, true); 383 384 verify(mockNetworkAgent).unregister(); 385 assertNull(mGatewayConnection.getNetworkAgent()); 386 } 387 } 388