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