1 /*
2  * Copyright 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.google.android.iwlan.epdg;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.Mockito.*;
25 import static org.mockito.Mockito.atLeastOnce;
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.Context;
31 import android.net.InetAddresses;
32 import android.net.LinkAddress;
33 import android.net.Network;
34 import android.net.ipsec.ike.ChildSessionCallback;
35 import android.net.ipsec.ike.ChildSessionParams;
36 import android.net.ipsec.ike.IkeFqdnIdentification;
37 import android.net.ipsec.ike.IkeSession;
38 import android.net.ipsec.ike.IkeSessionCallback;
39 import android.net.ipsec.ike.IkeSessionParams;
40 import android.net.ipsec.ike.SaProposal;
41 import android.net.ipsec.ike.TunnelModeChildSessionParams;
42 import android.net.ipsec.ike.exceptions.IkeException;
43 import android.net.ipsec.ike.exceptions.IkeInternalException;
44 import android.net.ipsec.ike.exceptions.IkeProtocolException;
45 import android.net.ipsec.ike.ike3gpp.Ike3gppBackoffTimer;
46 import android.net.ipsec.ike.ike3gpp.Ike3gppData;
47 import android.net.ipsec.ike.ike3gpp.Ike3gppExtension;
48 import android.os.Looper;
49 import android.os.PersistableBundle;
50 import android.telephony.CarrierConfigManager;
51 import android.telephony.SubscriptionInfo;
52 import android.telephony.SubscriptionManager;
53 import android.telephony.TelephonyManager;
54 import android.telephony.data.ApnSetting;
55 
56 import com.google.android.iwlan.IwlanError;
57 
58 import org.junit.Before;
59 import org.junit.Rule;
60 import org.junit.Test;
61 import org.junit.runner.RunWith;
62 import org.junit.runners.JUnit4;
63 import org.mockito.ArgumentCaptor;
64 import org.mockito.Mock;
65 import org.mockito.internal.util.reflection.FieldSetter;
66 import org.mockito.junit.MockitoJUnit;
67 import org.mockito.junit.MockitoRule;
68 
69 import java.io.IOException;
70 import java.net.Inet4Address;
71 import java.net.Inet6Address;
72 import java.net.InetAddress;
73 import java.util.ArrayList;
74 import java.util.List;
75 import java.util.concurrent.Executor;
76 
77 @RunWith(JUnit4.class)
78 public class EpdgTunnelManagerTest {
79     public static final int DEFAULT_SLOT_INDEX = 0;
80     public static final int DEFAULT_SUBID = 0;
81 
82     private final String TEST_IP_ADDRESS = "127.0.0.1";
83     private final String TEST_APN_NAME = "www.xyz.com";
84     private EpdgTunnelManager mEpdgTunnelManager;
85 
86     private class IwlanTunnelCallback implements EpdgTunnelManager.TunnelCallback {
onOpened(String apnName, TunnelLinkProperties linkProperties)87         public void onOpened(String apnName, TunnelLinkProperties linkProperties) {}
88 
onClosed(String apnName, IwlanError error)89         public void onClosed(String apnName, IwlanError error) {}
90     }
91 
92     @Rule public final MockitoRule mockito = MockitoJUnit.rule();
93 
94     @Mock private Context mMockContext;
95     @Mock private TunnelSetupRequest mMockTunnelSetupReq;
96     @Mock private IwlanTunnelCallback mMockIwlanTunnelCallback;
97     @Mock private IkeSession mMockIkeSession;
98     @Mock private EpdgSelector mMockEpdgSelector;
99     @Mock private Network mMockNetwork;
100     @Mock CarrierConfigManager mMockCarrierConfigManager;
101     @Mock SubscriptionManager mMockSubscriptionManager;
102     @Mock SubscriptionInfo mMockSubscriptionInfo;
103     @Mock TelephonyManager mMockTelephonyManager;
104     @Mock EpdgTunnelManager.IkeSessionCreator mMockIkeSessionCreator;
105     @Mock IkeException mMockIkeException;
106 
107     @Before
setUp()108     public void setUp() throws Exception {
109         mEpdgTunnelManager = spy(EpdgTunnelManager.getInstance(mMockContext, DEFAULT_SLOT_INDEX));
110         doReturn(Looper.getMainLooper()).when(mEpdgTunnelManager).getLooper();
111         setVariable(mEpdgTunnelManager, "mContext", mMockContext);
112         mEpdgTunnelManager.initHandler();
113         mEpdgTunnelManager.resetTunnelManagerState();
114         when(mEpdgTunnelManager.getEpdgSelector()).thenReturn(mMockEpdgSelector);
115         when(mEpdgTunnelManager.getIkeSessionCreator()).thenReturn(mMockIkeSessionCreator);
116 
117         when(mMockEpdgSelector.getValidatedServerList(
118                         anyInt(),
119                         anyInt(),
120                         anyBoolean(),
121                         anyBoolean(),
122                         eq(mMockNetwork),
123                         any(EpdgSelector.EpdgSelectorCallback.class)))
124                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
125 
126         // Fake local address
127         List<InetAddress> testLocalAddressList = new ArrayList<InetAddress>();
128         InetAddress testInetaddr = InetAddress.getByName(TEST_IP_ADDRESS);
129         testLocalAddressList.add(testInetaddr);
130 
131         doReturn(testLocalAddressList).when(mEpdgTunnelManager).getAddressForNetwork(any(), any());
132     }
133 
134     @Test
testBringUpTunnelWithInvalidProtocol()135     public void testBringUpTunnelWithInvalidProtocol() {
136         boolean ret =
137                 mEpdgTunnelManager.bringUpTunnel(
138                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_PPP),
139                         mMockIwlanTunnelCallback);
140         assertFalse(ret);
141     }
142 
143     @Test
testBringUpTunnelWithInvalidPduSessionId()144     public void testBringUpTunnelWithInvalidPduSessionId() {
145         boolean ret =
146                 mEpdgTunnelManager.bringUpTunnel(
147                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6, 16),
148                         mMockIwlanTunnelCallback);
149         assertFalse(ret);
150 
151         ret =
152                 mEpdgTunnelManager.bringUpTunnel(
153                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6, -1),
154                         mMockIwlanTunnelCallback);
155         assertFalse(ret);
156     }
157 
158     @Test
testBringUpTunnelWithValidProtocols()159     public void testBringUpTunnelWithValidProtocols() {
160         String testApnName1 = "www.xyz.com1";
161         String testApnName2 = "www.xyz.com2";
162         String testApnName3 = "www.xyz.com3";
163 
164         TunnelSetupRequest TSR_v4 =
165                 getBasicTunnelSetupRequest(testApnName1, ApnSetting.PROTOCOL_IP);
166 
167         TunnelSetupRequest TSR_v6 =
168                 getBasicTunnelSetupRequest(testApnName2, ApnSetting.PROTOCOL_IPV6);
169 
170         TunnelSetupRequest TSR_v4v6 =
171                 getBasicTunnelSetupRequest(testApnName3, ApnSetting.PROTOCOL_IPV4V6);
172 
173         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName1));
174         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName2));
175         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName3));
176 
177         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR_v4, mMockIwlanTunnelCallback);
178         assertTrue(ret);
179 
180         ret = mEpdgTunnelManager.bringUpTunnel(TSR_v6, mMockIwlanTunnelCallback);
181         assertTrue(ret);
182 
183         ret = mEpdgTunnelManager.bringUpTunnel(TSR_v4v6, mMockIwlanTunnelCallback);
184         assertTrue(ret);
185     }
186 
187     @Test
testBringUpTunnelWithNullApn()188     public void testBringUpTunnelWithNullApn() {
189 
190         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
191 
192         when(mEpdgTunnelManager.getTunnelSetupRequestApnName(TSR)).thenReturn(null);
193 
194         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
195         assertFalse(ret);
196         verify(mEpdgTunnelManager).getTunnelSetupRequestApnName(TSR);
197     }
198 
199     @Test
testBringUpTunnelWithExistApn()200     public void testBringUpTunnelWithExistApn() {
201         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
202 
203         when(mEpdgTunnelManager.isTunnelConfigContainExistApn(TEST_APN_NAME)).thenReturn(true);
204 
205         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
206         assertFalse(ret);
207         verify(mEpdgTunnelManager).isTunnelConfigContainExistApn(TEST_APN_NAME);
208     }
209 
210     @Test
testBringUPTunnelWithNoBringUpInProcess()211     public void testBringUPTunnelWithNoBringUpInProcess() {
212         String testApnName2 = "www.abc.com";
213 
214         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
215 
216         mEpdgTunnelManager.putApnNameToTunnelConfig(
217                 testApnName2, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
218         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
219 
220         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
221         assertTrue(ret);
222     }
223 
224     @Test
testBringUPTunnelSuccess()225     public void testBringUPTunnelSuccess() throws Exception {
226 
227         TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
228         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
229 
230         boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
231         assertTrue(ret);
232         verify(mMockEpdgSelector)
233                 .getValidatedServerList(
234                         anyInt(),
235                         eq(EpdgSelector.PROTO_FILTER_IPV4),
236                         eq(false),
237                         eq(false),
238                         eq(mMockNetwork),
239                         any());
240     }
241 
242     @Test
testCloseTunnelWithNoTunnelForApn()243     public void testCloseTunnelWithNoTunnelForApn() throws Exception {
244         String testApnName = "www.xyz.com";
245 
246         boolean ret = mEpdgTunnelManager.closeTunnel(testApnName, false /*forceClose*/);
247         assertTrue(ret);
248     }
249 
250     @Test
testCloseTunnelWithForceClose()251     public void testCloseTunnelWithForceClose() throws Exception {
252         String testApnName = "www.xyz.com";
253 
254         mEpdgTunnelManager.putApnNameToTunnelConfig(
255                 testApnName, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
256 
257         boolean ret = mEpdgTunnelManager.closeTunnel(testApnName, true /*forceClose*/);
258         assertTrue(ret);
259         verify(mMockIkeSession).kill();
260         verify(mEpdgTunnelManager).closePendingRequestsForApn(eq(testApnName));
261     }
262 
263     @Test
testCloseTunnelWithNonForceClose()264     public void testCloseTunnelWithNonForceClose() throws Exception {
265         String testApnName = "www.xyz.com";
266 
267         mEpdgTunnelManager.putApnNameToTunnelConfig(
268                 testApnName, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
269 
270         boolean ret = mEpdgTunnelManager.closeTunnel(testApnName, false /*forceClose*/);
271         assertTrue(ret);
272         verify(mMockIkeSession).close();
273         verify(mEpdgTunnelManager).closePendingRequestsForApn(eq(testApnName));
274     }
275 
276     @Test
testRekeyAndNattTimerFromCarrierConfig()277     public void testRekeyAndNattTimerFromCarrierConfig() throws Exception {
278         String testApnName = "www.xyz.com";
279 
280         // Test values
281         int hardTime = 50000;
282         int softTime = 20000;
283         int hardTimeChild = 10000;
284         int softTimeChild = 1000;
285         int nattTimer = 60;
286 
287         PersistableBundle bundle = new PersistableBundle();
288         bundle.putInt(CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT, hardTime);
289         bundle.putInt(CarrierConfigManager.Iwlan.KEY_IKE_REKEY_SOFT_TIMER_SEC_INT, softTime);
290         bundle.putInt(
291                 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_HARD_TIMER_SEC_INT, hardTimeChild);
292         bundle.putInt(
293                 CarrierConfigManager.Iwlan.KEY_CHILD_SA_REKEY_SOFT_TIMER_SEC_INT, softTimeChild);
294         bundle.putInt(CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT, nattTimer);
295 
296         setupMockForGetConfig(bundle);
297 
298         when(mMockEpdgSelector.getValidatedServerList(
299                         anyInt(),
300                         anyInt(),
301                         eq(false),
302                         eq(false),
303                         eq(mMockNetwork),
304                         any(EpdgSelector.EpdgSelectorCallback.class)))
305                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
306 
307         doReturn(null)
308                 .when(mMockIkeSessionCreator)
309                 .createIkeSession(
310                         eq(mMockContext),
311                         any(IkeSessionParams.class),
312                         any(ChildSessionParams.class),
313                         any(Executor.class),
314                         any(IkeSessionCallback.class),
315                         any(ChildSessionCallback.class));
316         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
317 
318         boolean ret =
319                 mEpdgTunnelManager.bringUpTunnel(
320                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
321                         mMockIwlanTunnelCallback);
322         assertTrue(ret);
323 
324         ArrayList<InetAddress> ipList = new ArrayList<>();
325         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
326         mEpdgTunnelManager.sendSelectionRequestComplete(
327                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
328 
329         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
330                 ArgumentCaptor.forClass(IkeSessionParams.class);
331         ArgumentCaptor<ChildSessionParams> childSessionParamsCaptor =
332                 ArgumentCaptor.forClass(ChildSessionParams.class);
333         verify(mMockIkeSessionCreator)
334                 .createIkeSession(
335                         eq(mMockContext),
336                         ikeSessionParamsCaptor.capture(),
337                         childSessionParamsCaptor.capture(),
338                         any(Executor.class),
339                         any(IkeSessionCallback.class),
340                         any(ChildSessionCallback.class));
341 
342         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
343         ChildSessionParams childSessionParams = childSessionParamsCaptor.getValue();
344 
345         assertEquals(ikeSessionParams.getHardLifetimeSeconds(), hardTime);
346         assertEquals(ikeSessionParams.getSoftLifetimeSeconds(), softTime);
347         assertEquals(childSessionParams.getHardLifetimeSeconds(), hardTimeChild);
348         assertEquals(childSessionParams.getSoftLifetimeSeconds(), softTimeChild);
349         assertEquals(ikeSessionParams.getNattKeepAliveDelaySeconds(), nattTimer);
350     }
351 
352     @Test
testSetRetransmissionTimeoutsFromCarrierConfig()353     public void testSetRetransmissionTimeoutsFromCarrierConfig() throws Exception {
354         String testApnName = "www.xyz.com";
355 
356         int[] testTimeouts = {1000, 1200, 1400, 1600, 2000, 4000};
357 
358         PersistableBundle bundle = new PersistableBundle();
359         bundle.putIntArray(
360                 CarrierConfigManager.Iwlan.KEY_RETRANSMIT_TIMER_MSEC_INT_ARRAY, testTimeouts);
361 
362         setupMockForGetConfig(bundle);
363 
364         when(mMockEpdgSelector.getValidatedServerList(
365                         anyInt(),
366                         anyInt(),
367                         eq(false),
368                         eq(false),
369                         eq(mMockNetwork),
370                         any(EpdgSelector.EpdgSelectorCallback.class)))
371                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
372 
373         doReturn(null)
374                 .when(mMockIkeSessionCreator)
375                 .createIkeSession(
376                         eq(mMockContext),
377                         any(IkeSessionParams.class),
378                         any(ChildSessionParams.class),
379                         any(Executor.class),
380                         any(IkeSessionCallback.class),
381                         any(ChildSessionCallback.class));
382         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
383 
384         boolean ret =
385                 mEpdgTunnelManager.bringUpTunnel(
386                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
387                         mMockIwlanTunnelCallback);
388         assertTrue(ret);
389 
390         ArrayList<InetAddress> ipList = new ArrayList<>();
391         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
392         mEpdgTunnelManager.sendSelectionRequestComplete(
393                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
394 
395         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
396                 ArgumentCaptor.forClass(IkeSessionParams.class);
397         verify(mMockIkeSessionCreator)
398                 .createIkeSession(
399                         eq(mMockContext),
400                         ikeSessionParamsCaptor.capture(),
401                         any(ChildSessionParams.class),
402                         any(Executor.class),
403                         any(IkeSessionCallback.class),
404                         any(ChildSessionCallback.class));
405 
406         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
407         assertArrayEquals(ikeSessionParams.getRetransmissionTimeoutsMillis(), testTimeouts);
408     }
409 
410     @Test
testSetDpdDelayFromCarrierConfig()411     public void testSetDpdDelayFromCarrierConfig() throws Exception {
412         String testApnName = "www.xyz.com";
413 
414         // Test values
415         int testDpdDelay = 600;
416 
417         PersistableBundle bundle = new PersistableBundle();
418         bundle.putInt(CarrierConfigManager.Iwlan.KEY_DPD_TIMER_SEC_INT, testDpdDelay);
419 
420         setupMockForGetConfig(bundle);
421         when(mMockEpdgSelector.getValidatedServerList(
422                         anyInt(),
423                         anyInt(),
424                         eq(false),
425                         eq(false),
426                         eq(mMockNetwork),
427                         any(EpdgSelector.EpdgSelectorCallback.class)))
428                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
429 
430         doReturn(null)
431                 .when(mMockIkeSessionCreator)
432                 .createIkeSession(
433                         eq(mMockContext),
434                         any(IkeSessionParams.class),
435                         any(ChildSessionParams.class),
436                         any(Executor.class),
437                         any(IkeSessionCallback.class),
438                         any(ChildSessionCallback.class));
439         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
440 
441         boolean ret =
442                 mEpdgTunnelManager.bringUpTunnel(
443                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
444                         mMockIwlanTunnelCallback);
445         assertTrue(ret);
446 
447         ArrayList<InetAddress> ipList = new ArrayList<>();
448         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
449         mEpdgTunnelManager.sendSelectionRequestComplete(
450                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
451 
452         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
453                 ArgumentCaptor.forClass(IkeSessionParams.class);
454         verify(mMockIkeSessionCreator)
455                 .createIkeSession(
456                         eq(mMockContext),
457                         ikeSessionParamsCaptor.capture(),
458                         any(ChildSessionParams.class),
459                         any(Executor.class),
460                         any(IkeSessionCallback.class),
461                         any(ChildSessionCallback.class));
462 
463         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
464         assertEquals(ikeSessionParams.getDpdDelaySeconds(), testDpdDelay);
465     }
466 
467     @Test
testGetValidEpdgAddress_DiffAddr()468     public void testGetValidEpdgAddress_DiffAddr() throws Exception {
469         String testApnName = "www.xyz.com";
470 
471         List<InetAddress> ipList1 = new ArrayList<>();
472         ipList1.add(InetAddress.getByName("1.1.1.1"));
473         mEpdgTunnelManager.validateAndSetEpdgAddress(ipList1);
474 
475         IwlanError error = new IwlanError(new IkeInternalException(new IOException()));
476 
477         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
478         setupMockForGetConfig(null);
479         when(mMockEpdgSelector.getValidatedServerList(
480                         anyInt(),
481                         anyInt(),
482                         eq(false),
483                         eq(false),
484                         eq(mMockNetwork),
485                         any(EpdgSelector.EpdgSelectorCallback.class)))
486                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
487 
488         doReturn(null)
489                 .doReturn(null)
490                 .when(mMockIkeSessionCreator)
491                 .createIkeSession(
492                         eq(mMockContext),
493                         any(IkeSessionParams.class),
494                         any(ChildSessionParams.class),
495                         any(Executor.class),
496                         any(IkeSessionCallback.class),
497                         any(ChildSessionCallback.class));
498         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
499 
500         boolean ret =
501                 mEpdgTunnelManager.bringUpTunnel(
502                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
503                         mMockIwlanTunnelCallback);
504         assertTrue(ret);
505 
506         ArrayList<InetAddress> ipList2 = new ArrayList<>();
507         ipList2.add(InetAddress.getByName("8.8.8.8"));
508         mEpdgTunnelManager.sendSelectionRequestComplete(
509                 ipList2, new IwlanError(IwlanError.NO_ERROR), 1);
510         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
511                 verifyCreateIkeSession(ipList2.get(0));
512         ikeSessionCallback.onClosedExceptionally(
513                 new IkeInternalException(new IOException("Retransmitting failure")));
514 
515         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
516         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
517     }
518 
519     @Test
testGetValidEpdgAddress_NextAddr()520     public void testGetValidEpdgAddress_NextAddr() throws Exception {
521         String testApnName = "www.xyz.com";
522 
523         List<InetAddress> ipList1 = new ArrayList<>();
524         ipList1.add(InetAddress.getByName("1.1.1.1"));
525         ipList1.add(InetAddress.getByName("8.8.8.8"));
526         mEpdgTunnelManager.validateAndSetEpdgAddress(ipList1);
527 
528         IwlanError error = new IwlanError(new IkeInternalException(new IOException()));
529 
530         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
531         setupMockForGetConfig(null);
532         when(mMockEpdgSelector.getValidatedServerList(
533                         anyInt(),
534                         anyInt(),
535                         eq(false),
536                         eq(false),
537                         eq(mMockNetwork),
538                         any(EpdgSelector.EpdgSelectorCallback.class)))
539                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
540 
541         doReturn(null)
542                 .doReturn(null)
543                 .when(mMockIkeSessionCreator)
544                 .createIkeSession(
545                         eq(mMockContext),
546                         any(IkeSessionParams.class),
547                         any(ChildSessionParams.class),
548                         any(Executor.class),
549                         any(IkeSessionCallback.class),
550                         any(ChildSessionCallback.class));
551         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
552 
553         boolean ret =
554                 mEpdgTunnelManager.bringUpTunnel(
555                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
556                         mMockIwlanTunnelCallback);
557         assertTrue(ret);
558 
559         ArrayList<InetAddress> ipList2 = new ArrayList<>();
560         ipList2.add(InetAddress.getByName("1.1.1.1"));
561         ipList2.add(InetAddress.getByName("8.8.8.8"));
562         mEpdgTunnelManager.sendSelectionRequestComplete(
563                 ipList2, new IwlanError(IwlanError.NO_ERROR), 1);
564         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
565                 verifyCreateIkeSession(ipList2.get(1));
566         ikeSessionCallback.onClosedExceptionally(
567                 new IkeInternalException(new IOException("Retransmitting failure")));
568 
569         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
570         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
571     }
572 
verifyCreateIkeSession(InetAddress ip)573     private EpdgTunnelManager.TmIkeSessionCallback verifyCreateIkeSession(InetAddress ip)
574             throws Exception {
575         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
576                 ArgumentCaptor.forClass(IkeSessionParams.class);
577         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
578                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
579         verify(mMockIkeSessionCreator, atLeastOnce())
580                 .createIkeSession(
581                         eq(mMockContext),
582                         ikeSessionParamsCaptor.capture(),
583                         any(ChildSessionParams.class),
584                         any(Executor.class),
585                         ikeSessionCallbackCaptor.capture(),
586                         any(ChildSessionCallback.class));
587         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
588         assertEquals(ikeSessionParams.getServerHostname(), ip.getHostAddress());
589         return ikeSessionCallbackCaptor.getValue();
590     }
591 
592     @Test
testIpv6PrefixMatching()593     public void testIpv6PrefixMatching() throws Exception {
594         InetAddress a1 = InetAddress.getByName("2600:381:4872:5d1e:ac45:69c7:bab2:639b");
595         LinkAddress l1 = new LinkAddress(a1, 64);
596         InetAddress src = InetAddress.getByName("2600:381:4872:5d1e:0:10:3582:a501");
597         EpdgTunnelManager.TunnelConfig tf =
598                 mEpdgTunnelManager.new TunnelConfig(null, null, src, 64);
599         assertTrue(tf.isPrefixSameAsSrcIP(l1));
600 
601         // different prefix length
602         LinkAddress l2 = new LinkAddress(a1, 63);
603         assertFalse(tf.isPrefixSameAsSrcIP(l2));
604     }
605 
606     @Test
testBackOffTimeCalculation()607     public void testBackOffTimeCalculation() throws Exception {
608         int transactionId = 1;
609 
610         // unit: 10 mins value: 2 expectedTime: 1200 (10 * 60 * 2)
611         verifyBackOffTimer("00000010", 1200, transactionId++);
612         // unit: 1 hour value: 4 expectedTime: 14400 (1 * 60 * 60 * 4)
613         verifyBackOffTimer("00100100", 14400, transactionId++);
614         // unit: 10 hours value: 3 expectedTime: (10 * 60 * 60 * 3)
615         verifyBackOffTimer("01000011", 108000, transactionId++);
616         // unit: 2 secs value: 21 expectedTime: 42 (2 * 21)
617         verifyBackOffTimer("01110101", 42, transactionId++);
618         // unit: 30 secs value: 31 expectedTime: 930 (30 * 31)
619         verifyBackOffTimer("10011111", 930, transactionId++);
620         // unit: 1 min value: 25 expectedTime: 1500 (1 * 60 * 25)
621         verifyBackOffTimer("10111001", 1500, transactionId++);
622         // unit: 1 hour value: 12 expectedTime: 43200 (1 * 60 * 60 * 12)
623         verifyBackOffTimer("11001100", 43200, transactionId++);
624         // deactivate - Should not report backoff time.
625         verifyBackOffTimer("11100100", -1, transactionId++);
626     }
627 
verifyBackOffTimer(String backoffByte, long expectedBackoffTime, int transactionId)628     private void verifyBackOffTimer(String backoffByte, long expectedBackoffTime, int transactionId)
629             throws Exception {
630         String testApnName = "www.xyz.com";
631         IwlanError error = new IwlanError(new IkeInternalException(new Exception()));
632         Ike3gppBackoffTimer mockIke3gppBackoffTimer = mock(Ike3gppBackoffTimer.class);
633         List<Ike3gppData> ike3gppInfoList = new ArrayList<>();
634         ike3gppInfoList.add(mockIke3gppBackoffTimer);
635         doReturn(Ike3gppData.DATA_TYPE_NOTIFY_BACKOFF_TIMER)
636                 .when(mockIke3gppBackoffTimer)
637                 .getDataType();
638         doReturn((byte) (int) Integer.parseInt(backoffByte, 2))
639                 .when(mockIke3gppBackoffTimer)
640                 .getBackoffTimer();
641 
642         // if back off time expected is negative normal reportIwlanError should be called.
643         if (expectedBackoffTime < 0) {
644             doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
645         } else {
646             doReturn(0L)
647                     .when(mEpdgTunnelManager)
648                     .reportIwlanError(eq(testApnName), eq(error), anyLong());
649         }
650 
651         setupMockForGetConfig(null);
652         when(mMockEpdgSelector.getValidatedServerList(
653                         anyInt(),
654                         anyInt(),
655                         eq(false),
656                         eq(false),
657                         eq(mMockNetwork),
658                         any(EpdgSelector.EpdgSelectorCallback.class)))
659                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
660         doReturn(null)
661                 .doReturn(null)
662                 .when(mMockIkeSessionCreator)
663                 .createIkeSession(
664                         eq(mMockContext),
665                         any(IkeSessionParams.class),
666                         any(ChildSessionParams.class),
667                         any(Executor.class),
668                         any(IkeSessionCallback.class),
669                         any(ChildSessionCallback.class));
670         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
671 
672         boolean ret =
673                 mEpdgTunnelManager.bringUpTunnel(
674                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
675                         mMockIwlanTunnelCallback);
676         assertTrue(ret);
677 
678         ArrayList<InetAddress> ipList = new ArrayList<>();
679         ipList.add(InetAddress.getByName("1.1.1.1"));
680         mEpdgTunnelManager.sendSelectionRequestComplete(
681                 ipList, new IwlanError(IwlanError.NO_ERROR), transactionId);
682         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
683                 ArgumentCaptor.forClass(IkeSessionParams.class);
684         ArgumentCaptor<EpdgTunnelManager.TmIkeSessionCallback> ikeSessionCallbackCaptor =
685                 ArgumentCaptor.forClass(EpdgTunnelManager.TmIkeSessionCallback.class);
686         verify(mMockIkeSessionCreator, atLeastOnce())
687                 .createIkeSession(
688                         eq(mMockContext),
689                         ikeSessionParamsCaptor.capture(),
690                         any(ChildSessionParams.class),
691                         any(Executor.class),
692                         ikeSessionCallbackCaptor.capture(),
693                         any(ChildSessionCallback.class));
694         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
695         assertEquals(ikeSessionParams.getServerHostname(), ipList.get(0).getHostAddress());
696 
697         Ike3gppExtension.Ike3gppDataListener ike3gppCallback =
698                 ikeSessionParams.getIke3gppExtension().getIke3gppDataListener();
699         ike3gppCallback.onIke3gppDataReceived(ike3gppInfoList);
700         EpdgTunnelManager.TmIkeSessionCallback ikeSessionCallback =
701                 ikeSessionCallbackCaptor.getValue();
702         ikeSessionCallback.onClosedExceptionally(new IkeInternalException(new Exception()));
703 
704         // if expected backoff time is negative - verify that backoff time is not reported.
705         if (expectedBackoffTime < 0) {
706             verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
707         } else {
708             // Else - Verify reportIwlanError with correct backoff time is being called.
709             verify(mEpdgTunnelManager, times(1))
710                     .reportIwlanError(eq(testApnName), eq(error), eq(expectedBackoffTime));
711         }
712         verify(mMockIwlanTunnelCallback, atLeastOnce()).onClosed(eq(testApnName), eq(error));
713     }
714 
getBasicTunnelSetupRequest(String apnName, int apnIpProtocol)715     private TunnelSetupRequest getBasicTunnelSetupRequest(String apnName, int apnIpProtocol) {
716         return getBasicTunnelSetupRequest(apnName, apnIpProtocol, 1);
717     }
718 
getBasicTunnelSetupRequest( String apnName, int apnIpProtocol, int pduSessionId)719     private TunnelSetupRequest getBasicTunnelSetupRequest(
720             String apnName, int apnIpProtocol, int pduSessionId) {
721         TunnelSetupRequest ret =
722                 TunnelSetupRequest.builder()
723                         .setApnName(apnName)
724                         .setNetwork(mMockNetwork)
725                         .setIsRoaming(false /*isRoaming*/)
726                         .setIsEmergency(false /*IsEmergency*/)
727                         .setRequestPcscf(false /*requestPcscf*/)
728                         .setApnIpProtocol(apnIpProtocol)
729                         .setPduSessionId(pduSessionId)
730                         .build();
731         return ret;
732     }
733 
getHandoverTunnelSetupRequest(String apnName, int apnIpProtocol)734     private TunnelSetupRequest getHandoverTunnelSetupRequest(String apnName, int apnIpProtocol) {
735         TunnelSetupRequest.Builder bld = TunnelSetupRequest.builder();
736         bld.setApnName(apnName)
737                 .setNetwork(mMockNetwork)
738                 .setIsRoaming(false /*isRoaming*/)
739                 .setIsEmergency(false /*IsEmergency*/)
740                 .setRequestPcscf(false /*requestPcscf*/)
741                 .setApnIpProtocol(apnIpProtocol)
742                 .setPduSessionId(1);
743         switch (apnIpProtocol) {
744             case ApnSetting.PROTOCOL_IP:
745                 bld.setSrcIpv4Address(InetAddresses.parseNumericAddress("10.10.10.10"));
746                 break;
747             case ApnSetting.PROTOCOL_IPV6:
748                 bld.setSrcIpv6Address(
749                         InetAddresses.parseNumericAddress(
750                                 "2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
751                 break;
752             case ApnSetting.PROTOCOL_IPV4V6:
753                 bld.setSrcIpv4Address(InetAddresses.parseNumericAddress("10.10.10.10"));
754                 bld.setSrcIpv6Address(
755                         InetAddresses.parseNumericAddress(
756                                 "2001:0db8:85a3:0000:0000:8a2e:0370:7334"));
757                 break;
758         }
759         return bld.build();
760     }
761 
setupMockForGetConfig(PersistableBundle bundle)762     private void setupMockForGetConfig(PersistableBundle bundle) {
763         if (bundle == null) {
764             bundle = new PersistableBundle();
765         }
766         bundle.putIntArray(
767                 CarrierConfigManager.Iwlan.KEY_SUPPORTED_INTEGRITY_ALGORITHMS_INT_ARRAY,
768                 new int[] {
769                     SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96,
770                     SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128,
771                     SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192,
772                     SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256,
773                 });
774         when(mMockContext.getSystemService(eq(CarrierConfigManager.class)))
775                 .thenReturn(mMockCarrierConfigManager);
776         when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
777                 .thenReturn(mMockSubscriptionManager);
778         when(mMockContext.getSystemService(eq(TelephonyManager.class)))
779                 .thenReturn(mMockTelephonyManager);
780         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX))
781                 .thenReturn(mMockSubscriptionInfo);
782         when(mMockSubscriptionInfo.getSubscriptionId()).thenReturn(DEFAULT_SUBID);
783         when(mMockSubscriptionInfo.getMncString()).thenReturn("344");
784         when(mMockTelephonyManager.createForSubscriptionId(DEFAULT_SUBID))
785                 .thenReturn(mMockTelephonyManager);
786         when(mMockCarrierConfigManager.getConfigForSubId(DEFAULT_SLOT_INDEX)).thenReturn(bundle);
787     }
788 
setVariable(Object target, String variableName, Object value)789     private void setVariable(Object target, String variableName, Object value) throws Exception {
790         FieldSetter.setField(target, target.getClass().getDeclaredField(variableName), value);
791     }
792 
793     @Test
testHandleOnClosedWithEpdgAddressSelected_True()794     public void testHandleOnClosedWithEpdgAddressSelected_True() throws Exception {
795         String testApnName = "www.xyz.com";
796         IwlanError error = new IwlanError(IwlanError.NO_ERROR);
797 
798         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
799         mEpdgTunnelManager.putApnNameToTunnelConfig(
800                 testApnName, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
801 
802         mEpdgTunnelManager.setIsEpdgAddressSelected(true);
803 
804         mEpdgTunnelManager.getTmIkeSessionCallback(testApnName).onClosed();
805 
806         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
807         verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
808         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
809     }
810 
811     @Test
testHandleOnClosedWithEpdgAddressSelected_False()812     public void testHandleOnClosedWithEpdgAddressSelected_False() throws Exception {
813         String testApnName = "www.xyz.com";
814         IwlanError error = new IwlanError(IwlanError.NO_ERROR);
815 
816         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
817 
818         PersistableBundle bundle = new PersistableBundle();
819         setupMockForGetConfig(bundle);
820         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
821 
822         boolean ret =
823                 mEpdgTunnelManager.bringUpTunnel(
824                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
825                         mMockIwlanTunnelCallback);
826         assertTrue(ret);
827 
828         ArrayList<InetAddress> ipList = new ArrayList<>();
829         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
830         mEpdgTunnelManager.sendSelectionRequestComplete(
831                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
832 
833         mEpdgTunnelManager.setIsEpdgAddressSelected(false);
834 
835         mEpdgTunnelManager.getTmIkeSessionCallback(testApnName).onClosed();
836 
837         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
838         verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
839         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
840     }
841 
842     @Test
testHandleOnClosedExceptionallyWithEpdgAddressSelected_True()843     public void testHandleOnClosedExceptionallyWithEpdgAddressSelected_True() throws Exception {
844         String testApnName = "www.xyz.com";
845         IwlanError error = new IwlanError(mMockIkeException);
846 
847         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
848 
849         mEpdgTunnelManager.putApnNameToTunnelConfig(
850                 testApnName, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
851 
852         mEpdgTunnelManager.setIsEpdgAddressSelected(true);
853 
854         mEpdgTunnelManager
855                 .getTmIkeSessionCallback(testApnName)
856                 .onClosedExceptionally(mMockIkeException);
857 
858         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
859         verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
860         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
861     }
862 
863     @Test
testHandleOnClosedExceptionallyWithEpdgAddressSelected_False()864     public void testHandleOnClosedExceptionallyWithEpdgAddressSelected_False() throws Exception {
865         String testApnName = "www.xyz.com";
866         IwlanError error = new IwlanError(mMockIkeException);
867 
868         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
869 
870         PersistableBundle bundle = new PersistableBundle();
871         setupMockForGetConfig(bundle);
872         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
873 
874         boolean ret =
875                 mEpdgTunnelManager.bringUpTunnel(
876                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
877                         mMockIwlanTunnelCallback);
878         assertTrue(ret);
879 
880         ArrayList<InetAddress> ipList = new ArrayList<>();
881         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
882         mEpdgTunnelManager.sendSelectionRequestComplete(
883                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
884 
885         mEpdgTunnelManager.setIsEpdgAddressSelected(false);
886 
887         mEpdgTunnelManager
888                 .getTmIkeSessionCallback(testApnName)
889                 .onClosedExceptionally(mMockIkeException);
890 
891         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), any(IwlanError.class));
892         verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
893         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
894     }
895 
896     @Test
testSetIkeTrafficSelectorsIPv4()897     public void testSetIkeTrafficSelectorsIPv4() throws Exception {
898         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IP, false);
899     }
900 
901     @Test
testSetIkeTrafficSelectorsIPv6()902     public void testSetIkeTrafficSelectorsIPv6() throws Exception {
903         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV6, false);
904     }
905 
906     @Test
testSetIkeTrafficSelectorsIPv4v6()907     public void testSetIkeTrafficSelectorsIPv4v6() throws Exception {
908         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV4V6, false);
909     }
910 
911     @Test
testSetIkeTrafficSelectorsIPv4_handover()912     public void testSetIkeTrafficSelectorsIPv4_handover() throws Exception {
913         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IP, true);
914     }
915 
916     @Test
testSetIkeTrafficSelectorsIPv6_handover()917     public void testSetIkeTrafficSelectorsIPv6_handover() throws Exception {
918         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV6, true);
919     }
920 
921     @Test
testSetIkeTrafficSelectorsIPv4v6_handover()922     public void testSetIkeTrafficSelectorsIPv4v6_handover() throws Exception {
923         testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IPV4V6, true);
924     }
925 
testSetIkeTrafficSelectors(int apnProtocol, boolean handover)926     private void testSetIkeTrafficSelectors(int apnProtocol, boolean handover) throws Exception {
927         String testApnName = "www.xyz.com";
928 
929         PersistableBundle bundle = new PersistableBundle();
930         setupMockForGetConfig(bundle);
931 
932         when(mMockEpdgSelector.getValidatedServerList(
933                         anyInt(),
934                         anyInt(),
935                         eq(false),
936                         eq(false),
937                         eq(mMockNetwork),
938                         any(EpdgSelector.EpdgSelectorCallback.class)))
939                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
940 
941         doReturn(null)
942                 .when(mMockIkeSessionCreator)
943                 .createIkeSession(
944                         eq(mMockContext),
945                         any(IkeSessionParams.class),
946                         any(ChildSessionParams.class),
947                         any(Executor.class),
948                         any(IkeSessionCallback.class),
949                         any(ChildSessionCallback.class));
950         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
951 
952         boolean ret;
953 
954         if (handover) {
955             ret =
956                     mEpdgTunnelManager.bringUpTunnel(
957                             getHandoverTunnelSetupRequest(TEST_APN_NAME, apnProtocol),
958                             mMockIwlanTunnelCallback);
959         } else {
960             ret =
961                     mEpdgTunnelManager.bringUpTunnel(
962                             getBasicTunnelSetupRequest(TEST_APN_NAME, apnProtocol),
963                             mMockIwlanTunnelCallback);
964         }
965 
966         assertTrue(ret);
967 
968         ArrayList<InetAddress> ipList = new ArrayList<>();
969         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
970         mEpdgTunnelManager.sendSelectionRequestComplete(
971                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
972 
973         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
974                 ArgumentCaptor.forClass(IkeSessionParams.class);
975         ArgumentCaptor<ChildSessionParams> childSessionParamsCaptor =
976                 ArgumentCaptor.forClass(ChildSessionParams.class);
977         verify(mMockIkeSessionCreator)
978                 .createIkeSession(
979                         eq(mMockContext),
980                         ikeSessionParamsCaptor.capture(),
981                         childSessionParamsCaptor.capture(),
982                         any(Executor.class),
983                         any(IkeSessionCallback.class),
984                         any(ChildSessionCallback.class));
985 
986         ChildSessionParams childSessionParams = childSessionParamsCaptor.getValue();
987 
988         switch (apnProtocol) {
989             case ApnSetting.PROTOCOL_IPV4V6:
990                 assertEquals(childSessionParams.getInboundTrafficSelectors().size(), 2);
991                 assertEquals(childSessionParams.getOutboundTrafficSelectors().size(), 2);
992                 assertTrue(
993                         childSessionParams.getInboundTrafficSelectors().get(0).endingAddress
994                                 != childSessionParams
995                                         .getInboundTrafficSelectors()
996                                         .get(1)
997                                         .endingAddress);
998                 assertTrue(
999                         childSessionParams.getInboundTrafficSelectors().get(0).startingAddress
1000                                 != childSessionParams
1001                                         .getInboundTrafficSelectors()
1002                                         .get(1)
1003                                         .startingAddress);
1004                 break;
1005             case ApnSetting.PROTOCOL_IPV6:
1006                 assertEquals(childSessionParams.getInboundTrafficSelectors().size(), 1);
1007                 assertEquals(childSessionParams.getOutboundTrafficSelectors().size(), 1);
1008                 assertEquals(
1009                         childSessionParams.getOutboundTrafficSelectors().get(0),
1010                         childSessionParams.getInboundTrafficSelectors().get(0));
1011                 assertEquals(
1012                         childSessionParams.getInboundTrafficSelectors().get(0).endingAddress,
1013                         InetAddresses.parseNumericAddress(
1014                                 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
1015                 assertEquals(
1016                         childSessionParams.getInboundTrafficSelectors().get(0).startingAddress,
1017                         InetAddresses.parseNumericAddress("::"));
1018                 break;
1019             case ApnSetting.PROTOCOL_IP:
1020                 assertEquals(childSessionParams.getInboundTrafficSelectors().size(), 1);
1021                 assertEquals(childSessionParams.getOutboundTrafficSelectors().size(), 1);
1022                 assertEquals(
1023                         childSessionParams.getOutboundTrafficSelectors().get(0),
1024                         childSessionParams.getInboundTrafficSelectors().get(0));
1025                 assertEquals(
1026                         childSessionParams.getInboundTrafficSelectors().get(0).endingAddress,
1027                         InetAddresses.parseNumericAddress("255.255.255.255"));
1028                 assertEquals(
1029                         childSessionParams.getInboundTrafficSelectors().get(0).startingAddress,
1030                         InetAddresses.parseNumericAddress("0.0.0.0"));
1031                 break;
1032         }
1033     }
1034 
1035     @Test
testN1modeCapabilityInclusion()1036     public void testN1modeCapabilityInclusion() throws Exception {
1037         {
1038             testN1modeCapability(8);
1039         }
1040     }
1041 
1042     @Test
testN1modeCapabilityNonInclusion()1043     public void testN1modeCapabilityNonInclusion() throws Exception {
1044         {
1045             testN1modeCapability(0);
1046         }
1047     }
1048 
1049     @Test
testReportIwlanErrorIkeProtocolException()1050     public void testReportIwlanErrorIkeProtocolException() throws Exception {
1051         String testApnName = "www.xyz.com";
1052 
1053         IkeProtocolException mockException = mock(IkeProtocolException.class);
1054         doReturn(IkeProtocolException.ERROR_TYPE_INVALID_IKE_SPI)
1055                 .when(mockException)
1056                 .getErrorType();
1057         doReturn(new byte[0]).when(mockException).getErrorData();
1058         IwlanError error = new IwlanError(mockException);
1059 
1060         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1061 
1062         mEpdgTunnelManager.putApnNameToTunnelConfig(
1063                 testApnName, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
1064 
1065         mEpdgTunnelManager.setIsEpdgAddressSelected(true);
1066 
1067         mEpdgTunnelManager
1068                 .getTmIkeSessionCallback(testApnName)
1069                 .onClosedExceptionally(mockException);
1070 
1071         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
1072         verify(mEpdgTunnelManager, times(2)).resetTunnelManagerState();
1073         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
1074     }
1075 
1076     @Test
testReportIwlanErrorServerSelectionFailed()1077     public void testReportIwlanErrorServerSelectionFailed() throws Exception {
1078         String testApnName = "www.xyz.com";
1079         IwlanError error = new IwlanError(IwlanError.EPDG_SELECTOR_SERVER_SELECTION_FAILED);
1080 
1081         doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
1082         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
1083 
1084         PersistableBundle bundle = new PersistableBundle();
1085         setupMockForGetConfig(bundle);
1086 
1087         boolean ret =
1088                 mEpdgTunnelManager.bringUpTunnel(
1089                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1090                         mMockIwlanTunnelCallback);
1091         assertTrue(ret);
1092 
1093         mEpdgTunnelManager.sendSelectionRequestComplete(null, error, 1);
1094         mEpdgTunnelManager.setIsEpdgAddressSelected(false);
1095 
1096         verify(mEpdgTunnelManager, times(1)).reportIwlanError(eq(testApnName), eq(error));
1097     }
1098 
1099     @Test
testCanBringUpTunnel()1100     public void testCanBringUpTunnel() throws Exception {
1101         String testApnName = "www.xyz.com";
1102         IwlanError error = new IwlanError(mMockIkeException);
1103 
1104         doReturn(false).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
1105         doReturn(error).when(mEpdgTunnelManager).getLastError(eq(testApnName));
1106 
1107         PersistableBundle bundle = new PersistableBundle();
1108         setupMockForGetConfig(bundle);
1109 
1110         boolean ret =
1111                 mEpdgTunnelManager.bringUpTunnel(
1112                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1113                         mMockIwlanTunnelCallback);
1114         assertTrue(ret);
1115         verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
1116     }
1117 
testN1modeCapability(int pduSessionId)1118     private void testN1modeCapability(int pduSessionId) throws Exception {
1119         String testApnName = "www.xyz.com";
1120         int PDU_SESSION_ID = pduSessionId;
1121         byte PDU_SESSION_ID_BYTE = (byte) PDU_SESSION_ID;
1122 
1123         PersistableBundle bundle = new PersistableBundle();
1124         setupMockForGetConfig(bundle);
1125 
1126         when(mMockEpdgSelector.getValidatedServerList(
1127                         anyInt(),
1128                         anyInt(),
1129                         eq(false),
1130                         eq(false),
1131                         eq(mMockNetwork),
1132                         any(EpdgSelector.EpdgSelectorCallback.class)))
1133                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
1134 
1135         doReturn(null)
1136                 .when(mMockIkeSessionCreator)
1137                 .createIkeSession(
1138                         eq(mMockContext),
1139                         any(IkeSessionParams.class),
1140                         any(ChildSessionParams.class),
1141                         any(Executor.class),
1142                         any(IkeSessionCallback.class),
1143                         any(ChildSessionCallback.class));
1144         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
1145 
1146         boolean ret;
1147 
1148         ret =
1149                 mEpdgTunnelManager.bringUpTunnel(
1150                         getBasicTunnelSetupRequest(
1151                                 TEST_APN_NAME, ApnSetting.PROTOCOL_IPV6, PDU_SESSION_ID),
1152                         mMockIwlanTunnelCallback);
1153 
1154         assertTrue(ret);
1155 
1156         ArrayList<InetAddress> ipList = new ArrayList<>();
1157         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
1158         mEpdgTunnelManager.sendSelectionRequestComplete(
1159                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
1160 
1161         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1162                 ArgumentCaptor.forClass(IkeSessionParams.class);
1163         ArgumentCaptor<ChildSessionParams> childSessionParamsCaptor =
1164                 ArgumentCaptor.forClass(ChildSessionParams.class);
1165         verify(mMockIkeSessionCreator)
1166                 .createIkeSession(
1167                         eq(mMockContext),
1168                         ikeSessionParamsCaptor.capture(),
1169                         childSessionParamsCaptor.capture(),
1170                         any(Executor.class),
1171                         any(IkeSessionCallback.class),
1172                         any(ChildSessionCallback.class));
1173 
1174         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1175 
1176         if (pduSessionId == 0) {
1177             assertNull(ikeSessionParams.getIke3gppExtension());
1178         } else {
1179             byte pduSessionIdByte =
1180                     ikeSessionParams.getIke3gppExtension().getIke3gppParams().getPduSessionId();
1181             assertEquals(pduSessionIdByte, PDU_SESSION_ID_BYTE);
1182         }
1183     }
1184 
1185     @Test
testInvalidNattTimerFromCarrierConfig()1186     public void testInvalidNattTimerFromCarrierConfig() throws Exception {
1187         String testApnName = "www.xyz.com";
1188 
1189         int nattTimer = 4500; // valid range for natt timer is 0-3600
1190         int ikeDefaultNattTimerValue = 20; // default value for natt timer is 20 secs
1191 
1192         PersistableBundle bundle = new PersistableBundle();
1193         bundle.putInt(CarrierConfigManager.Iwlan.KEY_NATT_KEEP_ALIVE_TIMER_SEC_INT, nattTimer);
1194 
1195         setupMockForGetConfig(bundle);
1196         when(mMockEpdgSelector.getValidatedServerList(
1197                         anyInt(),
1198                         anyInt(),
1199                         eq(false),
1200                         eq(false),
1201                         eq(mMockNetwork),
1202                         any(EpdgSelector.EpdgSelectorCallback.class)))
1203                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
1204 
1205         doReturn(null)
1206                 .when(mMockIkeSessionCreator)
1207                 .createIkeSession(
1208                         eq(mMockContext),
1209                         any(IkeSessionParams.class),
1210                         any(ChildSessionParams.class),
1211                         any(Executor.class),
1212                         any(IkeSessionCallback.class),
1213                         any(ChildSessionCallback.class));
1214         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
1215 
1216         boolean ret =
1217                 mEpdgTunnelManager.bringUpTunnel(
1218                         getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
1219                         mMockIwlanTunnelCallback);
1220         assertTrue(ret);
1221 
1222         ArrayList<InetAddress> ipList = new ArrayList<>();
1223         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
1224         mEpdgTunnelManager.sendSelectionRequestComplete(
1225                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
1226 
1227         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1228                 ArgumentCaptor.forClass(IkeSessionParams.class);
1229 
1230         verify(mMockIkeSessionCreator)
1231                 .createIkeSession(
1232                         eq(mMockContext),
1233                         ikeSessionParamsCaptor.capture(),
1234                         any(ChildSessionParams.class),
1235                         any(Executor.class),
1236                         any(IkeSessionCallback.class),
1237                         any(ChildSessionCallback.class));
1238 
1239         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1240         assertEquals(ikeSessionParams.getNattKeepAliveDelaySeconds(), ikeDefaultNattTimerValue);
1241     }
1242 
1243     @Test
testTunnelSetupRequestParams()1244     public void testTunnelSetupRequestParams() throws Exception {
1245         String testApnName = "www.xyz.com";
1246         Inet6Address testAddressV6 = Inet6Address.getByAddress("25.25.25.25", new byte[16], 0);
1247         Inet4Address testAddressV4 = (Inet4Address) Inet4Address.getByName("30.30.30.30");
1248         int pduSessionId = 5;
1249         boolean isRoaming = false;
1250         boolean isEmergency = true;
1251         boolean requestPcscf = true;
1252         int ipv6AddressLen = 64;
1253 
1254         TunnelSetupRequest tsr =
1255                 TunnelSetupRequest.builder()
1256                         .setApnName(testApnName)
1257                         .setNetwork(mMockNetwork)
1258                         .setApnIpProtocol(ApnSetting.PROTOCOL_IPV4V6)
1259                         .setSrcIpv6Address(testAddressV6)
1260                         .setSrcIpv6AddressPrefixLength(ipv6AddressLen)
1261                         .setSrcIpv4Address(testAddressV4)
1262                         .setPduSessionId(pduSessionId)
1263                         .setIsRoaming(isRoaming)
1264                         .setIsEmergency(isEmergency)
1265                         .setRequestPcscf(requestPcscf)
1266                         .build();
1267 
1268         setupMockForGetConfig(null);
1269         when(mMockEpdgSelector.getValidatedServerList(
1270                         anyInt(),
1271                         anyInt(),
1272                         eq(isRoaming),
1273                         eq(isEmergency),
1274                         eq(mMockNetwork),
1275                         any(EpdgSelector.EpdgSelectorCallback.class)))
1276                 .thenReturn(new IwlanError(IwlanError.NO_ERROR));
1277 
1278         doReturn(null)
1279                 .when(mMockIkeSessionCreator)
1280                 .createIkeSession(
1281                         eq(mMockContext),
1282                         any(IkeSessionParams.class),
1283                         any(ChildSessionParams.class),
1284                         any(Executor.class),
1285                         any(IkeSessionCallback.class),
1286                         any(ChildSessionCallback.class));
1287         doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
1288 
1289         boolean ret = mEpdgTunnelManager.bringUpTunnel(tsr, mMockIwlanTunnelCallback);
1290         assertTrue(ret);
1291 
1292         // verify isRoaming, isEmergency and Network variables.
1293         verify(mMockEpdgSelector)
1294                 .getValidatedServerList(
1295                         anyInt(),
1296                         anyInt(), // only Ipv6 address is added
1297                         eq(isRoaming),
1298                         eq(isEmergency),
1299                         eq(mMockNetwork),
1300                         any(EpdgSelector.EpdgSelectorCallback.class));
1301 
1302         ArrayList<InetAddress> ipList = new ArrayList<>();
1303         ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
1304         mEpdgTunnelManager.sendSelectionRequestComplete(
1305                 ipList, new IwlanError(IwlanError.NO_ERROR), 1);
1306 
1307         ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
1308                 ArgumentCaptor.forClass(IkeSessionParams.class);
1309         ArgumentCaptor<TunnelModeChildSessionParams> childSessionParamsCaptor =
1310                 ArgumentCaptor.forClass(TunnelModeChildSessionParams.class);
1311 
1312         verify(mMockIkeSessionCreator)
1313                 .createIkeSession(
1314                         eq(mMockContext),
1315                         ikeSessionParamsCaptor.capture(),
1316                         childSessionParamsCaptor.capture(),
1317                         any(Executor.class),
1318                         any(IkeSessionCallback.class),
1319                         any(ChildSessionCallback.class));
1320 
1321         IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
1322         TunnelModeChildSessionParams childSessionParams = childSessionParamsCaptor.getValue();
1323 
1324         // apnName verification. By default remote identification is type fqdn
1325         IkeFqdnIdentification ikeId =
1326                 (IkeFqdnIdentification) ikeSessionParams.getRemoteIdentification();
1327         assertEquals(ikeId.fqdn, testApnName);
1328 
1329         // verify Network
1330         assertEquals(ikeSessionParams.getNetwork(), mMockNetwork);
1331 
1332         // verify requestPcscf (true) with Apn protocol IPV6
1333         // it should add the pcscf config requests of type ConfigRequestIpv6PcscfServer and
1334         // ConfigRequestIpv4PcscfServer
1335         assertTrue(
1336                 ikeSessionParams.getConfigurationRequests().stream()
1337                         .anyMatch(c -> c instanceof IkeSessionParams.ConfigRequestIpv6PcscfServer));
1338         assertTrue(
1339                 ikeSessionParams.getConfigurationRequests().stream()
1340                         .anyMatch(c -> c instanceof IkeSessionParams.ConfigRequestIpv4PcscfServer));
1341 
1342         // verify pduSessionID
1343         assertEquals(
1344                 ikeSessionParams.getIke3gppExtension().getIke3gppParams().getPduSessionId(),
1345                 pduSessionId);
1346 
1347         // verify src ipv6  and src ipv4 address
1348         List<TunnelModeChildSessionParams.TunnelModeChildConfigRequest> configRequests =
1349                 childSessionParams.getConfigurationRequests();
1350         boolean ipv6ConfigRequestPresent = false;
1351         boolean ipv4ConfigRequestPresent = true;
1352         for (TunnelModeChildSessionParams.TunnelModeChildConfigRequest configRequest :
1353                 configRequests) {
1354             if (configRequest instanceof TunnelModeChildSessionParams.ConfigRequestIpv6Address) {
1355                 ipv6ConfigRequestPresent = true;
1356                 assertEquals(
1357                         ((TunnelModeChildSessionParams.ConfigRequestIpv6Address) configRequest)
1358                                 .getAddress(),
1359                         testAddressV6);
1360                 assertEquals(
1361                         ((TunnelModeChildSessionParams.ConfigRequestIpv6Address) configRequest)
1362                                 .getPrefixLength(),
1363                         ipv6AddressLen);
1364             }
1365             if (configRequest instanceof TunnelModeChildSessionParams.ConfigRequestIpv4Address) {
1366                 ipv4ConfigRequestPresent = true;
1367                 assertEquals(
1368                         ((TunnelModeChildSessionParams.ConfigRequestIpv4Address) configRequest)
1369                                 .getAddress(),
1370                         testAddressV4);
1371             }
1372         }
1373         assertTrue(ipv6ConfigRequestPresent);
1374         assertTrue(ipv4ConfigRequestPresent);
1375     }
1376 }
1377