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