1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.vcn;
18 
19 import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE;
20 
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotEquals;
24 import static org.junit.Assert.assertNotSame;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27 
28 import android.net.NetworkCapabilities;
29 import android.net.ipsec.ike.IkeSessionParams;
30 import android.net.ipsec.ike.IkeTunnelConnectionParams;
31 import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest;
32 import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest;
33 
34 import androidx.test.filters.SmallTest;
35 import androidx.test.runner.AndroidJUnit4;
36 
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 import java.util.Arrays;
41 import java.util.concurrent.TimeUnit;
42 
43 @RunWith(AndroidJUnit4.class)
44 @SmallTest
45 public class VcnGatewayConnectionConfigTest {
46     // Public for use in VcnGatewayConnectionTest
47     public static final int[] EXPOSED_CAPS =
48             new int[] {
49                 NetworkCapabilities.NET_CAPABILITY_INTERNET, NetworkCapabilities.NET_CAPABILITY_MMS
50             };
51     public static final int[] UNDERLYING_CAPS = new int[] {NetworkCapabilities.NET_CAPABILITY_DUN};
52 
53     static {
54         Arrays.sort(EXPOSED_CAPS);
55         Arrays.sort(UNDERLYING_CAPS);
56     }
57 
58     public static final long[] RETRY_INTERVALS_MS =
59             new long[] {
60                 TimeUnit.SECONDS.toMillis(5),
61                 TimeUnit.SECONDS.toMillis(30),
62                 TimeUnit.MINUTES.toMillis(1),
63                 TimeUnit.MINUTES.toMillis(5),
64                 TimeUnit.MINUTES.toMillis(15),
65                 TimeUnit.MINUTES.toMillis(30)
66             };
67     public static final int MAX_MTU = 1360;
68 
69     public static final IkeTunnelConnectionParams TUNNEL_CONNECTION_PARAMS =
70             TunnelConnectionParamsUtilsTest.buildTestParams();
71 
72     public static final String GATEWAY_CONNECTION_NAME_PREFIX = "gatewayConnectionName-";
73     private static int sGatewayConnectionConfigCount = 0;
74 
buildTestConfig( String gatewayConnectionName, IkeTunnelConnectionParams tunnelConnectionParams)75     private static VcnGatewayConnectionConfig buildTestConfig(
76             String gatewayConnectionName, IkeTunnelConnectionParams tunnelConnectionParams) {
77         return buildTestConfigWithExposedCaps(
78                 new VcnGatewayConnectionConfig.Builder(
79                         gatewayConnectionName, tunnelConnectionParams),
80                 EXPOSED_CAPS);
81     }
82 
83     // Public for use in VcnGatewayConnectionTest
buildTestConfig()84     public static VcnGatewayConnectionConfig buildTestConfig() {
85         return buildTestConfigWithExposedCaps(EXPOSED_CAPS);
86     }
87 
newBuilder()88     private static VcnGatewayConnectionConfig.Builder newBuilder() {
89         // Append a unique identifier to the name prefix to guarantee that all created
90         // VcnGatewayConnectionConfigs have a unique name (required by VcnConfig).
91         return new VcnGatewayConnectionConfig.Builder(
92                 GATEWAY_CONNECTION_NAME_PREFIX + sGatewayConnectionConfigCount++,
93                 TUNNEL_CONNECTION_PARAMS);
94     }
95 
buildTestConfigWithExposedCaps( VcnGatewayConnectionConfig.Builder builder, int... exposedCaps)96     private static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(
97             VcnGatewayConnectionConfig.Builder builder, int... exposedCaps) {
98         builder.setRetryIntervalsMillis(RETRY_INTERVALS_MS).setMaxMtu(MAX_MTU);
99 
100         for (int caps : exposedCaps) {
101             builder.addExposedCapability(caps);
102         }
103 
104         return builder.build();
105     }
106 
107     // Public for use in VcnGatewayConnectionTest
buildTestConfigWithExposedCaps(int... exposedCaps)108     public static VcnGatewayConnectionConfig buildTestConfigWithExposedCaps(int... exposedCaps) {
109         return buildTestConfigWithExposedCaps(newBuilder(), exposedCaps);
110     }
111 
112     @Test
testBuilderRequiresNonNullGatewayConnectionName()113     public void testBuilderRequiresNonNullGatewayConnectionName() {
114         try {
115             new VcnGatewayConnectionConfig.Builder(
116                             null /* gatewayConnectionName */, TUNNEL_CONNECTION_PARAMS)
117                     .build();
118 
119             fail("Expected exception due to invalid gateway connection name");
120         } catch (NullPointerException e) {
121         }
122     }
123 
124     @Test
testBuilderRequiresNonNullTunnelConnectionParams()125     public void testBuilderRequiresNonNullTunnelConnectionParams() {
126         try {
127             new VcnGatewayConnectionConfig.Builder(
128                             GATEWAY_CONNECTION_NAME_PREFIX, null /* tunnelConnectionParams */)
129                     .build();
130 
131             fail("Expected exception due to the absence of tunnel connection parameters");
132         } catch (NullPointerException e) {
133         }
134     }
135 
136     @Test
testBuilderRequiresMobikeEnabled()137     public void testBuilderRequiresMobikeEnabled() {
138         try {
139             final IkeSessionParams ikeParams =
140                     IkeSessionParamsUtilsTest.createBuilderMinimum()
141                             .removeIkeOption(IKE_OPTION_MOBIKE)
142                             .build();
143             final IkeTunnelConnectionParams tunnelParams =
144                     TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams);
145             new VcnGatewayConnectionConfig.Builder(GATEWAY_CONNECTION_NAME_PREFIX, tunnelParams);
146             fail("Expected exception due to MOBIKE not enabled");
147         } catch (IllegalArgumentException e) {
148         }
149     }
150 
151     @Test
testBuilderRequiresNonEmptyExposedCaps()152     public void testBuilderRequiresNonEmptyExposedCaps() {
153         try {
154             newBuilder().build();
155 
156             fail("Expected exception due to invalid exposed capabilities");
157         } catch (IllegalArgumentException e) {
158         }
159     }
160 
161     @Test
testBuilderRequiresNonNullRetryInterval()162     public void testBuilderRequiresNonNullRetryInterval() {
163         try {
164             newBuilder().setRetryIntervalsMillis(null);
165             fail("Expected exception due to invalid retryIntervalMs");
166         } catch (IllegalArgumentException e) {
167         }
168     }
169 
170     @Test
testBuilderRequiresNonEmptyRetryInterval()171     public void testBuilderRequiresNonEmptyRetryInterval() {
172         try {
173             newBuilder().setRetryIntervalsMillis(new long[0]);
174             fail("Expected exception due to invalid retryIntervalMs");
175         } catch (IllegalArgumentException e) {
176         }
177     }
178 
179     @Test
testBuilderRequiresValidMtu()180     public void testBuilderRequiresValidMtu() {
181         try {
182             newBuilder().setMaxMtu(VcnGatewayConnectionConfig.MIN_MTU_V6 - 1);
183             fail("Expected exception due to invalid mtu");
184         } catch (IllegalArgumentException e) {
185         }
186     }
187 
188     @Test
testBuilderAndGetters()189     public void testBuilderAndGetters() {
190         final VcnGatewayConnectionConfig config = buildTestConfig();
191 
192         assertTrue(config.getGatewayConnectionName().startsWith(GATEWAY_CONNECTION_NAME_PREFIX));
193 
194         int[] exposedCaps = config.getExposedCapabilities();
195         Arrays.sort(exposedCaps);
196         assertArrayEquals(EXPOSED_CAPS, exposedCaps);
197 
198         assertEquals(TUNNEL_CONNECTION_PARAMS, config.getTunnelConnectionParams());
199 
200         assertArrayEquals(RETRY_INTERVALS_MS, config.getRetryIntervalsMillis());
201         assertEquals(MAX_MTU, config.getMaxMtu());
202     }
203 
204     @Test
testPersistableBundle()205     public void testPersistableBundle() {
206         final VcnGatewayConnectionConfig config = buildTestConfig();
207 
208         assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle()));
209     }
210 
buildTunnelConnectionParams(String ikePsk)211     private static IkeTunnelConnectionParams buildTunnelConnectionParams(String ikePsk) {
212         final IkeSessionParams ikeParams =
213                 IkeSessionParamsUtilsTest.createBuilderMinimum()
214                         .setAuthPsk(ikePsk.getBytes())
215                         .build();
216         return TunnelConnectionParamsUtilsTest.buildTestParams(ikeParams);
217     }
218 
219     @Test
testTunnelConnectionParamsEquals()220     public void testTunnelConnectionParamsEquals() throws Exception {
221         final String connectionName = "testTunnelConnectionParamsEquals.connectionName";
222         final String psk = "testTunnelConnectionParamsEquals.psk";
223 
224         final IkeTunnelConnectionParams tunnelParams = buildTunnelConnectionParams(psk);
225         final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams);
226 
227         final IkeTunnelConnectionParams anotherTunnelParams = buildTunnelConnectionParams(psk);
228         final VcnGatewayConnectionConfig anotherConfig =
229                 buildTestConfig(connectionName, anotherTunnelParams);
230 
231         assertNotSame(tunnelParams, anotherTunnelParams);
232         assertEquals(tunnelParams, anotherTunnelParams);
233         assertEquals(config, anotherConfig);
234     }
235 
236     @Test
testTunnelConnectionParamsNotEquals()237     public void testTunnelConnectionParamsNotEquals() throws Exception {
238         final String connectionName = "testTunnelConnectionParamsNotEquals.connectionName";
239 
240         final IkeTunnelConnectionParams tunnelParams =
241                 buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskA");
242         final VcnGatewayConnectionConfig config = buildTestConfig(connectionName, tunnelParams);
243 
244         final IkeTunnelConnectionParams anotherTunnelParams =
245                 buildTunnelConnectionParams("testTunnelConnectionParamsNotEquals.pskB");
246         final VcnGatewayConnectionConfig anotherConfig =
247                 buildTestConfig(connectionName, anotherTunnelParams);
248 
249         assertNotEquals(tunnelParams, anotherTunnelParams);
250         assertNotEquals(config, anotherConfig);
251     }
252 }
253