blob: 550953d0612df9b435c79f144528e1afdafac308 [file] [log] [blame]
Remi NGUYEN VAN31022d62021-05-11 13:37:06 +00001/*
2 * Copyright (C) 2010 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
17package android.net;
18
19import static android.net.RouteInfo.RTN_THROW;
20import static android.net.RouteInfo.RTN_UNICAST;
21import static android.net.RouteInfo.RTN_UNREACHABLE;
22
23import static com.android.testutils.ParcelUtils.assertParcelSane;
24import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
25import static com.android.testutils.ParcelUtils.parcelingRoundTrip;
26
27import static org.junit.Assert.assertEquals;
28import static org.junit.Assert.assertFalse;
29import static org.junit.Assert.assertNotEquals;
30import static org.junit.Assert.assertNull;
31import static org.junit.Assert.assertTrue;
32import static org.junit.Assert.fail;
33
34import android.net.LinkProperties.ProvisioningChange;
35import android.os.Build;
36import android.system.OsConstants;
37import android.util.ArraySet;
38
39import androidx.core.os.BuildCompat;
40import androidx.test.filters.SmallTest;
41import androidx.test.runner.AndroidJUnit4;
42
43import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
44import com.android.testutils.DevSdkIgnoreRule;
45import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
46import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
47
48import org.junit.Rule;
49import org.junit.Test;
50import org.junit.runner.RunWith;
51
52import java.net.Inet4Address;
53import java.net.Inet6Address;
54import java.net.InetAddress;
55import java.util.Arrays;
56import java.util.Collection;
57import java.util.Collections;
58import java.util.List;
59import java.util.Set;
60
61@RunWith(AndroidJUnit4.class)
62@SmallTest
63public class LinkPropertiesTest {
64 @Rule
65 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
66
67 private static final InetAddress ADDRV4 = address("75.208.6.1");
68 private static final InetAddress ADDRV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
69 private static final InetAddress DNS1 = address("75.208.7.1");
70 private static final InetAddress DNS2 = address("69.78.7.1");
71 private static final InetAddress DNS6 = address("2001:4860:4860::8888");
72 private static final InetAddress PRIVDNS1 = address("1.1.1.1");
73 private static final InetAddress PRIVDNS2 = address("1.0.0.1");
74 private static final InetAddress PRIVDNS6 = address("2606:4700:4700::1111");
75 private static final InetAddress PCSCFV4 = address("10.77.25.37");
76 private static final InetAddress PCSCFV6 = address("2001:0db8:85a3:0000:0000:8a2e:0370:1");
77 private static final InetAddress GATEWAY1 = address("75.208.8.1");
78 private static final InetAddress GATEWAY2 = address("69.78.8.1");
79 private static final InetAddress GATEWAY61 = address("fe80::6:0000:613");
80 private static final InetAddress GATEWAY62 = address("fe80::6:22%lo");
81 private static final InetAddress TESTIPV4ADDR = address("192.168.47.42");
82 private static final InetAddress TESTIPV6ADDR = address("fe80::7:33%43");
83 private static final Inet4Address DHCPSERVER = (Inet4Address) address("192.0.2.1");
84 private static final String NAME = "qmi0";
85 private static final String DOMAINS = "google.com";
86 private static final String PRIV_DNS_SERVER_NAME = "private.dns.com";
87 private static final String TCP_BUFFER_SIZES = "524288,1048576,2097152,262144,524288,1048576";
88 private static final int MTU = 1500;
89 private static final LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
90 private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
91 private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
92 private static final Uri CAPPORT_API_URL = Uri.parse("https://test.example.com/capportapi");
93
94 // CaptivePortalData cannot be in a constant as it does not exist on Q.
95 // The test runner also crashes when scanning for tests if it is a return type.
96 private static Object getCaptivePortalData() {
97 return new CaptivePortalData.Builder()
98 .setVenueInfoUrl(Uri.parse("https://test.example.com/venue")).build();
99 }
100
101 private static InetAddress address(String addrString) {
102 return InetAddresses.parseNumericAddress(addrString);
103 }
104
105 private static boolean isAtLeastR() {
106 // BuildCompat.isAtLeastR is documented to return false on release SDKs (including R)
107 return Build.VERSION.SDK_INT > Build.VERSION_CODES.Q || BuildCompat.isAtLeastR();
108 }
109
110 private void checkEmpty(final LinkProperties lp) {
111 assertEquals(0, lp.getAllInterfaceNames().size());
112 assertEquals(0, lp.getAllAddresses().size());
113 assertEquals(0, lp.getDnsServers().size());
114 assertEquals(0, lp.getValidatedPrivateDnsServers().size());
115 assertEquals(0, lp.getPcscfServers().size());
116 assertEquals(0, lp.getAllRoutes().size());
117 assertEquals(0, lp.getAllLinkAddresses().size());
118 assertEquals(0, lp.getStackedLinks().size());
119 assertEquals(0, lp.getMtu());
120 assertNull(lp.getPrivateDnsServerName());
121 assertNull(lp.getDomains());
122 assertNull(lp.getHttpProxy());
123 assertNull(lp.getTcpBufferSizes());
124 assertNull(lp.getNat64Prefix());
125 assertFalse(lp.isProvisioned());
126 assertFalse(lp.isIpv4Provisioned());
127 assertFalse(lp.isIpv6Provisioned());
128 assertFalse(lp.isPrivateDnsActive());
129
130 if (isAtLeastR()) {
131 assertNull(lp.getDhcpServerAddress());
132 assertFalse(lp.isWakeOnLanSupported());
133 assertNull(lp.getCaptivePortalApiUrl());
134 assertNull(lp.getCaptivePortalData());
135 }
136 }
137
138 private LinkProperties makeTestObject() {
139 final LinkProperties lp = new LinkProperties();
140 lp.setInterfaceName(NAME);
141 lp.addLinkAddress(LINKADDRV4);
142 lp.addLinkAddress(LINKADDRV6);
143 lp.addDnsServer(DNS1);
144 lp.addDnsServer(DNS2);
145 lp.addValidatedPrivateDnsServer(PRIVDNS1);
146 lp.addValidatedPrivateDnsServer(PRIVDNS2);
147 lp.setUsePrivateDns(true);
148 lp.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME);
149 lp.addPcscfServer(PCSCFV6);
150 lp.setDomains(DOMAINS);
151 lp.addRoute(new RouteInfo(GATEWAY1));
152 lp.addRoute(new RouteInfo(GATEWAY2));
153 lp.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888));
154 lp.setMtu(MTU);
155 lp.setTcpBufferSizes(TCP_BUFFER_SIZES);
156 lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96"));
157 if (isAtLeastR()) {
158 lp.setDhcpServerAddress(DHCPSERVER);
159 lp.setWakeOnLanSupported(true);
160 lp.setCaptivePortalApiUrl(CAPPORT_API_URL);
161 lp.setCaptivePortalData((CaptivePortalData) getCaptivePortalData());
162 }
163 return lp;
164 }
165
166 public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
167 // Check implementation of equals(), element by element.
168 assertTrue(source.isIdenticalInterfaceName(target));
169 assertTrue(target.isIdenticalInterfaceName(source));
170
171 assertTrue(source.isIdenticalAddresses(target));
172 assertTrue(target.isIdenticalAddresses(source));
173
174 assertTrue(source.isIdenticalDnses(target));
175 assertTrue(target.isIdenticalDnses(source));
176
177 assertTrue(source.isIdenticalPrivateDns(target));
178 assertTrue(target.isIdenticalPrivateDns(source));
179
180 assertTrue(source.isIdenticalValidatedPrivateDnses(target));
181 assertTrue(target.isIdenticalValidatedPrivateDnses(source));
182
183 assertTrue(source.isIdenticalPcscfs(target));
184 assertTrue(target.isIdenticalPcscfs(source));
185
186 assertTrue(source.isIdenticalRoutes(target));
187 assertTrue(target.isIdenticalRoutes(source));
188
189 assertTrue(source.isIdenticalHttpProxy(target));
190 assertTrue(target.isIdenticalHttpProxy(source));
191
192 assertTrue(source.isIdenticalStackedLinks(target));
193 assertTrue(target.isIdenticalStackedLinks(source));
194
195 assertTrue(source.isIdenticalMtu(target));
196 assertTrue(target.isIdenticalMtu(source));
197
198 assertTrue(source.isIdenticalTcpBufferSizes(target));
199 assertTrue(target.isIdenticalTcpBufferSizes(source));
200
201 if (isAtLeastR()) {
202 assertTrue(source.isIdenticalDhcpServerAddress(target));
203 assertTrue(source.isIdenticalDhcpServerAddress(source));
204
205 assertTrue(source.isIdenticalWakeOnLan(target));
206 assertTrue(target.isIdenticalWakeOnLan(source));
207
208 assertTrue(source.isIdenticalCaptivePortalApiUrl(target));
209 assertTrue(target.isIdenticalCaptivePortalApiUrl(source));
210
211 assertTrue(source.isIdenticalCaptivePortalData(target));
212 assertTrue(target.isIdenticalCaptivePortalData(source));
213 }
214
215 // Check result of equals().
216 assertTrue(source.equals(target));
217 assertTrue(target.equals(source));
218
219 // Check hashCode.
220 assertEquals(source.hashCode(), target.hashCode());
221 }
222
223 @Test
224 public void testEqualsNull() {
225 LinkProperties source = new LinkProperties();
226 LinkProperties target = new LinkProperties();
227
228 assertFalse(source == target);
229 assertLinkPropertiesEqual(source, target);
230 }
231
232 @Test
233 public void testEqualsSameOrder() throws Exception {
234 LinkProperties source = new LinkProperties();
235 source.setInterfaceName(NAME);
236 // set 2 link addresses
237 source.addLinkAddress(LINKADDRV4);
238 source.addLinkAddress(LINKADDRV6);
239 // set 2 dnses
240 source.addDnsServer(DNS1);
241 source.addDnsServer(DNS2);
242 // set 1 pcscf
243 source.addPcscfServer(PCSCFV6);
244 // set 2 gateways
245 source.addRoute(new RouteInfo(GATEWAY1));
246 source.addRoute(new RouteInfo(GATEWAY2));
247 source.setMtu(MTU);
248
249 LinkProperties target = new LinkProperties();
250
251 // All fields are same
252 target.setInterfaceName(NAME);
253 target.addLinkAddress(LINKADDRV4);
254 target.addLinkAddress(LINKADDRV6);
255 target.addDnsServer(DNS1);
256 target.addDnsServer(DNS2);
257 target.addPcscfServer(PCSCFV6);
258 target.addRoute(new RouteInfo(GATEWAY1));
259 target.addRoute(new RouteInfo(GATEWAY2));
260 target.setMtu(MTU);
261
262 assertLinkPropertiesEqual(source, target);
263
264 target.clear();
265 // change Interface Name
266 target.setInterfaceName("qmi1");
267 target.addLinkAddress(LINKADDRV4);
268 target.addLinkAddress(LINKADDRV6);
269 target.addDnsServer(DNS1);
270 target.addDnsServer(DNS2);
271 target.addPcscfServer(PCSCFV6);
272 target.addRoute(new RouteInfo(GATEWAY1));
273 target.addRoute(new RouteInfo(GATEWAY2));
274 target.setMtu(MTU);
275 assertFalse(source.equals(target));
276
277 target.clear();
278 target.setInterfaceName(NAME);
279 // change link addresses
280 target.addLinkAddress(new LinkAddress(address("75.208.6.2"), 32));
281 target.addLinkAddress(LINKADDRV6);
282 target.addDnsServer(DNS1);
283 target.addDnsServer(DNS2);
284 target.addPcscfServer(PCSCFV6);
285 target.addRoute(new RouteInfo(GATEWAY1));
286 target.addRoute(new RouteInfo(GATEWAY2));
287 target.setMtu(MTU);
288 assertFalse(source.equals(target));
289
290 target.clear();
291 target.setInterfaceName(NAME);
292 target.addLinkAddress(LINKADDRV4);
293 target.addLinkAddress(LINKADDRV6);
294 // change dnses
295 target.addDnsServer(address("75.208.7.2"));
296 target.addDnsServer(DNS2);
297 target.addPcscfServer(PCSCFV6);
298 target.addRoute(new RouteInfo(GATEWAY1));
299 target.addRoute(new RouteInfo(GATEWAY2));
300 target.setMtu(MTU);
301 assertFalse(source.equals(target));
302
303 target.clear();
304 target.setInterfaceName(NAME);
305 target.addLinkAddress(LINKADDRV4);
306 target.addLinkAddress(LINKADDRV6);
307 target.addDnsServer(address("75.208.7.2"));
308 target.addDnsServer(DNS2);
309 // change pcscf
310 target.addPcscfServer(address("2001::1"));
311 target.addRoute(new RouteInfo(GATEWAY1));
312 target.addRoute(new RouteInfo(GATEWAY2));
313 target.setMtu(MTU);
314 assertFalse(source.equals(target));
315
316 target.clear();
317 target.setInterfaceName(NAME);
318 target.addLinkAddress(LINKADDRV4);
319 target.addLinkAddress(LINKADDRV6);
320 target.addDnsServer(DNS1);
321 target.addDnsServer(DNS2);
322 // change gateway
323 target.addRoute(new RouteInfo(address("75.208.8.2")));
324 target.setMtu(MTU);
325 target.addRoute(new RouteInfo(GATEWAY2));
326 assertFalse(source.equals(target));
327
328 target.clear();
329 target.setInterfaceName(NAME);
330 target.addLinkAddress(LINKADDRV4);
331 target.addLinkAddress(LINKADDRV6);
332 target.addDnsServer(DNS1);
333 target.addDnsServer(DNS2);
334 target.addRoute(new RouteInfo(GATEWAY1));
335 target.addRoute(new RouteInfo(GATEWAY2));
336 // change mtu
337 target.setMtu(1440);
338 assertFalse(source.equals(target));
339 }
340
341 @Test
342 public void testEqualsDifferentOrder() throws Exception {
343 LinkProperties source = new LinkProperties();
344 source.setInterfaceName(NAME);
345 // set 2 link addresses
346 source.addLinkAddress(LINKADDRV4);
347 source.addLinkAddress(LINKADDRV6);
348 // set 2 dnses
349 source.addDnsServer(DNS1);
350 source.addDnsServer(DNS2);
351 // set 2 gateways
352 source.addRoute(new RouteInfo(LINKADDRV4, GATEWAY1));
353 source.addRoute(new RouteInfo(GATEWAY2));
354 source.setMtu(MTU);
355
356 LinkProperties target = new LinkProperties();
357 // Exchange order
358 target.setInterfaceName(NAME);
359 target.addLinkAddress(LINKADDRV6);
360 target.addLinkAddress(LINKADDRV4);
361 target.addDnsServer(DNS2);
362 target.addDnsServer(DNS1);
363 target.addRoute(new RouteInfo(GATEWAY2));
364 target.addRoute(new RouteInfo(LINKADDRV4, GATEWAY1));
365 target.setMtu(MTU);
366
367 assertLinkPropertiesEqual(source, target);
368 }
369
370 @Test
371 public void testEqualsDuplicated() throws Exception {
372 LinkProperties source = new LinkProperties();
373 // set 3 link addresses, eg, [A, A, B]
374 source.addLinkAddress(LINKADDRV4);
375 source.addLinkAddress(LINKADDRV4);
376 source.addLinkAddress(LINKADDRV6);
377
378 LinkProperties target = new LinkProperties();
379 // set 3 link addresses, eg, [A, B, B]
380 target.addLinkAddress(LINKADDRV4);
381 target.addLinkAddress(LINKADDRV6);
382 target.addLinkAddress(LINKADDRV6);
383
384 assertLinkPropertiesEqual(source, target);
385 }
386
387 private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
388 for (RouteInfo r : lp.getRoutes()) {
389 assertEquals(iface, r.getInterface());
390 }
391 }
392
393 private void assertAllRoutesNotHaveInterface(String iface, LinkProperties lp) {
394 for (RouteInfo r : lp.getRoutes()) {
395 assertNotEquals(iface, r.getInterface());
396 }
397 }
398
399 @Test
400 public void testRouteInterfaces() {
401 LinkAddress prefix1 = new LinkAddress(address("2001:db8:1::"), 48);
402 LinkAddress prefix2 = new LinkAddress(address("2001:db8:2::"), 48);
403 InetAddress address = ADDRV6;
404
405 // Add a route with no interface to a LinkProperties with no interface. No errors.
406 LinkProperties lp = new LinkProperties();
407 RouteInfo r = new RouteInfo(prefix1, address, null);
408 assertTrue(lp.addRoute(r));
409 assertEquals(1, lp.getRoutes().size());
410 assertAllRoutesHaveInterface(null, lp);
411
412 // Adding the same route twice has no effect.
413 assertFalse(lp.addRoute(r));
414 assertEquals(1, lp.getRoutes().size());
415
416 // Add a route with an interface. Expect an exception.
417 r = new RouteInfo(prefix2, address, "wlan0");
418 try {
419 lp.addRoute(r);
420 fail("Adding wlan0 route to LP with no interface, expect exception");
421 } catch (IllegalArgumentException expected) {}
422
423 // Change the interface name. All the routes should change their interface name too.
424 lp.setInterfaceName("rmnet0");
425 assertAllRoutesHaveInterface("rmnet0", lp);
426 assertAllRoutesNotHaveInterface(null, lp);
427 assertAllRoutesNotHaveInterface("wlan0", lp);
428
429 // Now add a route with the wrong interface. This causes an exception too.
430 try {
431 lp.addRoute(r);
432 fail("Adding wlan0 route to rmnet0 LP, expect exception");
433 } catch (IllegalArgumentException expected) {}
434
435 // If the interface name matches, the route is added.
436 r = new RouteInfo(prefix2, null, "wlan0");
437 lp.setInterfaceName("wlan0");
438 lp.addRoute(r);
439 assertEquals(2, lp.getRoutes().size());
440 assertAllRoutesHaveInterface("wlan0", lp);
441 assertAllRoutesNotHaveInterface("rmnet0", lp);
442
443 // Routes with null interfaces are converted to wlan0.
444 r = RouteInfo.makeHostRoute(ADDRV6, null);
445 lp.addRoute(r);
446 assertEquals(3, lp.getRoutes().size());
447 assertAllRoutesHaveInterface("wlan0", lp);
448
449 // Check routes are updated correctly when calling setInterfaceName.
450 LinkProperties lp2 = new LinkProperties(lp);
451 assertAllRoutesHaveInterface("wlan0", lp2);
452 final CompareResult<RouteInfo> cr1 =
453 new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes());
454 assertEquals(0, cr1.added.size());
455 assertEquals(0, cr1.removed.size());
456
457 lp2.setInterfaceName("p2p0");
458 assertAllRoutesHaveInterface("p2p0", lp2);
459 assertAllRoutesNotHaveInterface("wlan0", lp2);
460 final CompareResult<RouteInfo> cr2 =
461 new CompareResult<>(lp.getAllRoutes(), lp2.getAllRoutes());
462 assertEquals(3, cr2.added.size());
463 assertEquals(3, cr2.removed.size());
464
465 // Remove route with incorrect interface, no route removed.
466 lp.removeRoute(new RouteInfo(prefix2, null, null));
467 assertEquals(3, lp.getRoutes().size());
468
469 // Check remove works when interface is correct.
470 lp.removeRoute(new RouteInfo(prefix2, null, "wlan0"));
471 assertEquals(2, lp.getRoutes().size());
472 assertAllRoutesHaveInterface("wlan0", lp);
473 assertAllRoutesNotHaveInterface("p2p0", lp);
474 }
475
476 @Test
477 public void testStackedInterfaces() {
478 LinkProperties rmnet0 = new LinkProperties();
479 rmnet0.setInterfaceName("rmnet0");
480 rmnet0.addLinkAddress(LINKADDRV6);
481
482 LinkProperties clat4 = new LinkProperties();
483 clat4.setInterfaceName("clat4");
484 clat4.addLinkAddress(LINKADDRV4);
485
486 assertEquals(0, rmnet0.getStackedLinks().size());
487 assertEquals(1, rmnet0.getAddresses().size());
488 assertEquals(1, rmnet0.getLinkAddresses().size());
489 assertEquals(1, rmnet0.getAllAddresses().size());
490 assertEquals(1, rmnet0.getAllLinkAddresses().size());
491 assertEquals(1, rmnet0.getAllInterfaceNames().size());
492 assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
493
494 rmnet0.addStackedLink(clat4);
495 assertEquals(1, rmnet0.getStackedLinks().size());
496 assertEquals(1, rmnet0.getAddresses().size());
497 assertEquals(1, rmnet0.getLinkAddresses().size());
498 assertEquals(2, rmnet0.getAllAddresses().size());
499 assertEquals(2, rmnet0.getAllLinkAddresses().size());
500 assertEquals(2, rmnet0.getAllInterfaceNames().size());
501 assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
502 assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1));
503
504 rmnet0.addStackedLink(clat4);
505 assertEquals(1, rmnet0.getStackedLinks().size());
506 assertEquals(1, rmnet0.getAddresses().size());
507 assertEquals(1, rmnet0.getLinkAddresses().size());
508 assertEquals(2, rmnet0.getAllAddresses().size());
509 assertEquals(2, rmnet0.getAllLinkAddresses().size());
510 assertEquals(2, rmnet0.getAllInterfaceNames().size());
511 assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
512 assertEquals("clat4", rmnet0.getAllInterfaceNames().get(1));
513
514 assertEquals(0, clat4.getStackedLinks().size());
515
516 // Modify an item in the returned collection to see what happens.
517 for (LinkProperties link : rmnet0.getStackedLinks()) {
518 if (link.getInterfaceName().equals("clat4")) {
519 link.setInterfaceName("newname");
520 }
521 }
522 for (LinkProperties link : rmnet0.getStackedLinks()) {
523 assertFalse("newname".equals(link.getInterfaceName()));
524 }
525
526 assertTrue(rmnet0.removeStackedLink("clat4"));
527 assertEquals(0, rmnet0.getStackedLinks().size());
528 assertEquals(1, rmnet0.getAddresses().size());
529 assertEquals(1, rmnet0.getLinkAddresses().size());
530 assertEquals(1, rmnet0.getAllAddresses().size());
531 assertEquals(1, rmnet0.getAllLinkAddresses().size());
532 assertEquals(1, rmnet0.getAllInterfaceNames().size());
533 assertEquals("rmnet0", rmnet0.getAllInterfaceNames().get(0));
534
535 assertFalse(rmnet0.removeStackedLink("clat4"));
536 }
537
538 private LinkAddress getFirstLinkAddress(LinkProperties lp) {
539 return lp.getLinkAddresses().iterator().next();
540 }
541
542 @Test
543 public void testAddressMethods() {
544 LinkProperties lp = new LinkProperties();
545
546 // No addresses.
547 assertFalse(lp.hasIpv4Address());
548 assertFalse(lp.hasGlobalIpv6Address());
549
550 // Addresses on stacked links don't count.
551 LinkProperties stacked = new LinkProperties();
552 stacked.setInterfaceName("stacked");
553 lp.addStackedLink(stacked);
554 stacked.addLinkAddress(LINKADDRV4);
555 stacked.addLinkAddress(LINKADDRV6);
556 assertTrue(stacked.hasIpv4Address());
557 assertTrue(stacked.hasGlobalIpv6Address());
558 assertFalse(lp.hasIpv4Address());
559 assertFalse(lp.hasGlobalIpv6Address());
560 lp.removeStackedLink("stacked");
561 assertFalse(lp.hasIpv4Address());
562 assertFalse(lp.hasGlobalIpv6Address());
563
564 // Addresses on the base link.
565 // Check the return values of hasIpvXAddress and ensure the add/remove methods return true
566 // iff something changes.
567 assertEquals(0, lp.getLinkAddresses().size());
568 assertTrue(lp.addLinkAddress(LINKADDRV6));
569 assertEquals(1, lp.getLinkAddresses().size());
570 assertFalse(lp.hasIpv4Address());
571 assertTrue(lp.hasGlobalIpv6Address());
572
573 assertTrue(lp.removeLinkAddress(LINKADDRV6));
574 assertEquals(0, lp.getLinkAddresses().size());
575
576 assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
577 assertEquals(1, lp.getLinkAddresses().size());
578 assertFalse(lp.hasGlobalIpv6Address());
579
580 assertTrue(lp.addLinkAddress(LINKADDRV4));
581 assertEquals(2, lp.getLinkAddresses().size());
582 assertTrue(lp.hasIpv4Address());
583 assertFalse(lp.hasGlobalIpv6Address());
584
585 assertTrue(lp.addLinkAddress(LINKADDRV6));
586 assertEquals(3, lp.getLinkAddresses().size());
587 assertTrue(lp.hasIpv4Address());
588 assertTrue(lp.hasGlobalIpv6Address());
589
590 assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
591 assertEquals(2, lp.getLinkAddresses().size());
592 assertTrue(lp.hasIpv4Address());
593 assertTrue(lp.hasGlobalIpv6Address());
594
595 // Adding an address twice has no effect.
596 // Removing an address that's not present has no effect.
597 assertFalse(lp.addLinkAddress(LINKADDRV4));
598 assertEquals(2, lp.getLinkAddresses().size());
599 assertTrue(lp.hasIpv4Address());
600 assertTrue(lp.removeLinkAddress(LINKADDRV4));
601 assertEquals(1, lp.getLinkAddresses().size());
602 assertFalse(lp.hasIpv4Address());
603 assertFalse(lp.removeLinkAddress(LINKADDRV4));
604 assertEquals(1, lp.getLinkAddresses().size());
605
606 // Adding an address that's already present but with different properties causes the
607 // existing address to be updated and returns true.
608 // Start with only LINKADDRV6.
609 assertEquals(1, lp.getLinkAddresses().size());
610 assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
611
612 // Create a LinkAddress object for the same address, but with different flags.
613 LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
614 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
615 assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
616 assertFalse(deprecated.equals(LINKADDRV6));
617
618 // Check that adding it updates the existing address instead of adding a new one.
619 assertTrue(lp.addLinkAddress(deprecated));
620 assertEquals(1, lp.getLinkAddresses().size());
621 assertEquals(deprecated, getFirstLinkAddress(lp));
622 assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
623
624 // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
625 assertTrue(lp.removeLinkAddress(LINKADDRV6));
626 assertEquals(0, lp.getLinkAddresses().size());
627 }
628
629 @Test
630 public void testLinkAddresses() {
631 final LinkProperties lp = new LinkProperties();
632 lp.addLinkAddress(LINKADDRV4);
633 lp.addLinkAddress(LINKADDRV6);
634
635 final LinkProperties lp2 = new LinkProperties();
636 lp2.addLinkAddress(LINKADDRV6);
637
638 final LinkProperties lp3 = new LinkProperties();
639 final List<LinkAddress> linkAddresses = Arrays.asList(LINKADDRV4);
640 lp3.setLinkAddresses(linkAddresses);
641
642 assertFalse(lp.equals(lp2));
643 assertFalse(lp2.equals(lp3));
644
645 lp.removeLinkAddress(LINKADDRV4);
646 assertTrue(lp.equals(lp2));
647
648 lp2.setLinkAddresses(lp3.getLinkAddresses());
649 assertTrue(lp2.equals(lp3));
650 }
651
652 @Test
653 public void testNat64Prefix() throws Exception {
654 LinkProperties lp = new LinkProperties();
655 lp.addLinkAddress(LINKADDRV4);
656 lp.addLinkAddress(LINKADDRV6);
657
658 assertNull(lp.getNat64Prefix());
659
660 IpPrefix p = new IpPrefix("64:ff9b::/96");
661 lp.setNat64Prefix(p);
662 assertEquals(p, lp.getNat64Prefix());
663
664 p = new IpPrefix("2001:db8:a:b:1:2:3::/96");
665 lp.setNat64Prefix(p);
666 assertEquals(p, lp.getNat64Prefix());
667
668 p = new IpPrefix("2001:db8:a:b:1:2::/80");
669 try {
670 lp.setNat64Prefix(p);
671 } catch (IllegalArgumentException expected) {
672 }
673
674 p = new IpPrefix("64:ff9b::/64");
675 try {
676 lp.setNat64Prefix(p);
677 } catch (IllegalArgumentException expected) {
678 }
679
680 assertEquals(new IpPrefix("2001:db8:a:b:1:2:3::/96"), lp.getNat64Prefix());
681
682 lp.setNat64Prefix(null);
683 assertNull(lp.getNat64Prefix());
684 }
685
686 @Test
687 public void testIsProvisioned() {
688 LinkProperties lp4 = new LinkProperties();
689 assertFalse("v4only:empty", lp4.isProvisioned());
690 lp4.addLinkAddress(LINKADDRV4);
691 assertFalse("v4only:addr-only", lp4.isProvisioned());
692 lp4.addDnsServer(DNS1);
693 assertFalse("v4only:addr+dns", lp4.isProvisioned());
694 lp4.addRoute(new RouteInfo(GATEWAY1));
695 assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
696 assertTrue("v4only:addr+dns+route", lp4.isIpv4Provisioned());
697 assertFalse("v4only:addr+dns+route", lp4.isIpv6Provisioned());
698
699 LinkProperties lp6 = new LinkProperties();
700 assertFalse("v6only:empty", lp6.isProvisioned());
701 lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
702 assertFalse("v6only:fe80-only", lp6.isProvisioned());
703 lp6.addDnsServer(DNS6);
704 assertFalse("v6only:fe80+dns", lp6.isProvisioned());
705 lp6.addRoute(new RouteInfo(GATEWAY61));
706 assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
707 lp6.addLinkAddress(LINKADDRV6);
708 assertTrue("v6only:fe80+global+dns+route", lp6.isIpv6Provisioned());
709 assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
710 lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
711 assertFalse("v6only:global+dns+route", lp6.isIpv4Provisioned());
712 assertTrue("v6only:global+dns+route", lp6.isIpv6Provisioned());
713 assertTrue("v6only:global+dns+route", lp6.isProvisioned());
714
715 LinkProperties lp46 = new LinkProperties();
716 lp46.addLinkAddress(LINKADDRV4);
717 lp46.addLinkAddress(LINKADDRV6);
718 lp46.addDnsServer(DNS1);
719 lp46.addDnsServer(DNS6);
720 assertFalse("dualstack:missing-routes", lp46.isProvisioned());
721 lp46.addRoute(new RouteInfo(GATEWAY1));
722 assertTrue("dualstack:v4-provisioned", lp46.isIpv4Provisioned());
723 assertFalse("dualstack:v4-provisioned", lp46.isIpv6Provisioned());
724 assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
725 lp46.addRoute(new RouteInfo(GATEWAY61));
726 assertTrue("dualstack:both-provisioned", lp46.isIpv4Provisioned());
727 assertTrue("dualstack:both-provisioned", lp46.isIpv6Provisioned());
728 assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
729
730 // A link with an IPv6 address and default route, but IPv4 DNS server.
731 LinkProperties mixed = new LinkProperties();
732 mixed.addLinkAddress(LINKADDRV6);
733 mixed.addDnsServer(DNS1);
734 mixed.addRoute(new RouteInfo(GATEWAY61));
735 assertFalse("mixed:addr6+route6+dns4", mixed.isIpv4Provisioned());
736 assertFalse("mixed:addr6+route6+dns4", mixed.isIpv6Provisioned());
737 assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
738 }
739
740 @Test
741 public void testCompareProvisioning() {
742 LinkProperties v4lp = new LinkProperties();
743 v4lp.addLinkAddress(LINKADDRV4);
744 v4lp.addRoute(new RouteInfo(GATEWAY1));
745 v4lp.addDnsServer(DNS1);
746 assertTrue(v4lp.isProvisioned());
747
748 LinkProperties v4r = new LinkProperties(v4lp);
749 v4r.removeDnsServer(DNS1);
750 assertFalse(v4r.isProvisioned());
751
752 assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
753 LinkProperties.compareProvisioning(v4r, v4r));
754 assertEquals(ProvisioningChange.LOST_PROVISIONING,
755 LinkProperties.compareProvisioning(v4lp, v4r));
756 assertEquals(ProvisioningChange.GAINED_PROVISIONING,
757 LinkProperties.compareProvisioning(v4r, v4lp));
758 assertEquals(ProvisioningChange.STILL_PROVISIONED,
759 LinkProperties.compareProvisioning(v4lp, v4lp));
760
761 // Check that losing IPv4 provisioning on a dualstack network is
762 // seen as a total loss of provisioning.
763 LinkProperties v6lp = new LinkProperties();
764 v6lp.addLinkAddress(LINKADDRV6);
765 v6lp.addRoute(new RouteInfo(GATEWAY61));
766 v6lp.addDnsServer(DNS6);
767 assertFalse(v6lp.isIpv4Provisioned());
768 assertTrue(v6lp.isIpv6Provisioned());
769 assertTrue(v6lp.isProvisioned());
770
771 LinkProperties v46lp = new LinkProperties(v6lp);
772 v46lp.addLinkAddress(LINKADDRV4);
773 v46lp.addRoute(new RouteInfo(GATEWAY1));
774 v46lp.addDnsServer(DNS1);
775 assertTrue(v46lp.isIpv4Provisioned());
776 assertTrue(v46lp.isIpv6Provisioned());
777 assertTrue(v46lp.isProvisioned());
778
779 assertEquals(ProvisioningChange.STILL_PROVISIONED,
780 LinkProperties.compareProvisioning(v4lp, v46lp));
781 assertEquals(ProvisioningChange.STILL_PROVISIONED,
782 LinkProperties.compareProvisioning(v6lp, v46lp));
783 assertEquals(ProvisioningChange.LOST_PROVISIONING,
784 LinkProperties.compareProvisioning(v46lp, v6lp));
785 assertEquals(ProvisioningChange.LOST_PROVISIONING,
786 LinkProperties.compareProvisioning(v46lp, v4lp));
787
788 // Check that losing and gaining a secondary router does not change
789 // the provisioning status.
790 LinkProperties v6lp2 = new LinkProperties(v6lp);
791 v6lp2.addRoute(new RouteInfo(GATEWAY62));
792 assertTrue(v6lp2.isProvisioned());
793
794 assertEquals(ProvisioningChange.STILL_PROVISIONED,
795 LinkProperties.compareProvisioning(v6lp2, v6lp));
796 assertEquals(ProvisioningChange.STILL_PROVISIONED,
797 LinkProperties.compareProvisioning(v6lp, v6lp2));
798 }
799
800 @Test
801 public void testIsReachable() {
802 final LinkProperties v4lp = new LinkProperties();
803 assertFalse(v4lp.isReachable(DNS1));
804 assertFalse(v4lp.isReachable(DNS2));
805
806 // Add an on-link route, making the on-link DNS server reachable,
807 // but there is still no IPv4 address.
808 assertTrue(v4lp.addRoute(new RouteInfo(new IpPrefix(address("75.208.0.0"), 16))));
809 assertFalse(v4lp.isReachable(DNS1));
810 assertFalse(v4lp.isReachable(DNS2));
811
812 // Adding an IPv4 address (right now, any IPv4 address) means we use
813 // the routes to compute likely reachability.
814 assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
815 assertTrue(v4lp.isReachable(DNS1));
816 assertFalse(v4lp.isReachable(DNS2));
817
818 // Adding a default route makes the off-link DNS server reachable.
819 assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
820 assertTrue(v4lp.isReachable(DNS1));
821 assertTrue(v4lp.isReachable(DNS2));
822
823 final LinkProperties v6lp = new LinkProperties();
824 final InetAddress kLinkLocalDns = address("fe80::6:1");
825 final InetAddress kLinkLocalDnsWithScope = address("fe80::6:2%43");
826 final InetAddress kOnLinkDns = address("2001:db8:85a3::53");
827 assertFalse(v6lp.isReachable(kLinkLocalDns));
828 assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
829 assertFalse(v6lp.isReachable(kOnLinkDns));
830 assertFalse(v6lp.isReachable(DNS6));
831
832 // Add a link-local route, making the link-local DNS servers reachable. Because
833 // we assume the presence of an IPv6 link-local address, link-local DNS servers
834 // are considered reachable, but only those with a non-zero scope identifier.
835 assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("fe80::"), 64))));
836 assertFalse(v6lp.isReachable(kLinkLocalDns));
837 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
838 assertFalse(v6lp.isReachable(kOnLinkDns));
839 assertFalse(v6lp.isReachable(DNS6));
840
841 // Add a link-local address--nothing changes.
842 assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
843 assertFalse(v6lp.isReachable(kLinkLocalDns));
844 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
845 assertFalse(v6lp.isReachable(kOnLinkDns));
846 assertFalse(v6lp.isReachable(DNS6));
847
848 // Add a global route on link, but no global address yet. DNS servers reachable
849 // via a route that doesn't require a gateway: give them the benefit of the
850 // doubt and hope the link-local source address suffices for communication.
851 assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(address("2001:db8:85a3::"), 64))));
852 assertFalse(v6lp.isReachable(kLinkLocalDns));
853 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
854 assertTrue(v6lp.isReachable(kOnLinkDns));
855 assertFalse(v6lp.isReachable(DNS6));
856
857 // Add a global address; the on-link global address DNS server is (still)
858 // presumed reachable.
859 assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
860 assertFalse(v6lp.isReachable(kLinkLocalDns));
861 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
862 assertTrue(v6lp.isReachable(kOnLinkDns));
863 assertFalse(v6lp.isReachable(DNS6));
864
865 // Adding a default route makes the off-link DNS server reachable.
866 assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
867 assertFalse(v6lp.isReachable(kLinkLocalDns));
868 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
869 assertTrue(v6lp.isReachable(kOnLinkDns));
870 assertTrue(v6lp.isReachable(DNS6));
871
872 // Check isReachable on stacked links. This requires that the source IP address be assigned
873 // on the interface returned by the route lookup.
874 LinkProperties stacked = new LinkProperties();
875
876 // Can't add a stacked link without an interface name.
877 stacked.setInterfaceName("v4-test0");
878 v6lp.addStackedLink(stacked);
879
880 InetAddress stackedAddress = address("192.0.0.4");
881 LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
882 assertFalse(v6lp.isReachable(stackedAddress));
883 stacked.addLinkAddress(stackedLinkAddress);
884 assertFalse(v6lp.isReachable(stackedAddress));
885 stacked.addRoute(new RouteInfo(stackedLinkAddress));
886 assertTrue(stacked.isReachable(stackedAddress));
887 assertTrue(v6lp.isReachable(stackedAddress));
888
889 assertFalse(v6lp.isReachable(DNS1));
890 stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
891 assertTrue(v6lp.isReachable(DNS1));
892 }
893
894 @Test
895 public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
896 // IPv4 case: no route added initially
897 LinkProperties rmnet0 = new LinkProperties();
898 rmnet0.setInterfaceName("rmnet0");
899 rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8"));
900 RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
901 rmnet0.getInterfaceName());
902
903 // Since no routes is added explicitly, getAllRoutes() should return empty.
904 assertTrue(rmnet0.getAllRoutes().isEmpty());
905 rmnet0.ensureDirectlyConnectedRoutes();
906 // ensureDirectlyConnectedRoutes() should have added the missing local route.
907 assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes());
908
909 // IPv4 case: both direct and default routes added initially
910 LinkProperties rmnet1 = new LinkProperties();
911 rmnet1.setInterfaceName("rmnet1");
912 rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
913 RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, address("10.0.0.1"),
914 rmnet1.getInterfaceName());
915 RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
916 rmnet1.getInterfaceName());
917 rmnet1.addRoute(defaultRoute1);
918 rmnet1.addRoute(directRoute1);
919
920 // Check added routes
921 assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
922 // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected
923 // route is already part of the configuration.
924 rmnet1.ensureDirectlyConnectedRoutes();
925 assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
926
927 // IPv6 case: only default routes added initially
928 LinkProperties rmnet2 = new LinkProperties();
929 rmnet2.setInterfaceName("rmnet2");
930 rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
931 rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
932 RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, address("2001:db8::1"),
933 rmnet2.getInterfaceName());
934 RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
935 rmnet2.getInterfaceName());
936 RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null,
937 rmnet2.getInterfaceName());
938 rmnet2.addRoute(defaultRoute2);
939
940 assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes());
941 rmnet2.ensureDirectlyConnectedRoutes();
942 assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2),
943 rmnet2.getAllRoutes());
944
945 // Corner case: no interface name
946 LinkProperties rmnet3 = new LinkProperties();
947 rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24"));
948 RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null,
949 rmnet3.getInterfaceName());
950
951 assertTrue(rmnet3.getAllRoutes().isEmpty());
952 rmnet3.ensureDirectlyConnectedRoutes();
953 assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes());
954 }
955
956 private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
957 Set<RouteInfo> expectedSet = new ArraySet<>(expected);
958 Set<RouteInfo> actualSet = new ArraySet<>(actual);
959 // Duplicated entries in actual routes are considered failures
960 assertEquals(actual.size(), actualSet.size());
961
962 assertEquals(expectedSet, actualSet);
963 }
964
965 private static LinkProperties makeLinkPropertiesForParceling() {
966 LinkProperties source = new LinkProperties();
967 source.setInterfaceName(NAME);
968
969 source.addLinkAddress(LINKADDRV4);
970 source.addLinkAddress(LINKADDRV6);
971
972 source.addDnsServer(DNS1);
973 source.addDnsServer(DNS2);
974 source.addDnsServer(GATEWAY62);
975
976 source.addPcscfServer(TESTIPV4ADDR);
977 source.addPcscfServer(TESTIPV6ADDR);
978
979 source.setUsePrivateDns(true);
980 source.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME);
981
982 source.setDomains(DOMAINS);
983
984 source.addRoute(new RouteInfo(GATEWAY1));
985 source.addRoute(new RouteInfo(GATEWAY2));
986
987 source.addValidatedPrivateDnsServer(DNS6);
988 source.addValidatedPrivateDnsServer(GATEWAY61);
989 source.addValidatedPrivateDnsServer(TESTIPV6ADDR);
990
991 source.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888));
992
993 source.setMtu(MTU);
994
995 source.setTcpBufferSizes(TCP_BUFFER_SIZES);
996
997 source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
998
999 final LinkProperties stacked = new LinkProperties();
1000 stacked.setInterfaceName("test-stacked");
1001 source.addStackedLink(stacked);
1002
1003 return source;
1004 }
1005
1006 @Test @IgnoreAfter(Build.VERSION_CODES.Q)
1007 public void testLinkPropertiesParcelable_Q() throws Exception {
1008 final LinkProperties source = makeLinkPropertiesForParceling();
1009 assertParcelSane(source, 14 /* fieldCount */);
1010 }
1011
1012 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1013 public void testLinkPropertiesParcelable() throws Exception {
1014 final LinkProperties source = makeLinkPropertiesForParceling();
1015
1016 source.setWakeOnLanSupported(true);
1017 source.setCaptivePortalApiUrl(CAPPORT_API_URL);
1018 source.setCaptivePortalData((CaptivePortalData) getCaptivePortalData());
1019 source.setDhcpServerAddress((Inet4Address) GATEWAY1);
1020 assertParcelSane(new LinkProperties(source, true /* parcelSensitiveFields */),
1021 18 /* fieldCount */);
1022
1023 // Verify that without using a sensitiveFieldsParcelingCopy, sensitive fields are cleared.
1024 final LinkProperties sanitized = new LinkProperties(source);
1025 sanitized.setCaptivePortalApiUrl(null);
1026 sanitized.setCaptivePortalData(null);
1027 assertEquals(sanitized, parcelingRoundTrip(source));
1028 }
1029
1030 // Parceling of the scope was broken until Q-QPR2
1031 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1032 public void testLinkLocalDnsServerParceling() throws Exception {
1033 final String strAddress = "fe80::1%lo";
1034 final LinkProperties lp = new LinkProperties();
1035 lp.addDnsServer(address(strAddress));
1036 final LinkProperties unparceled = parcelingRoundTrip(lp);
1037 // Inet6Address#equals does not test for the scope id
1038 assertEquals(strAddress, unparceled.getDnsServers().get(0).getHostAddress());
1039 }
1040
1041 @Test
1042 public void testParcelUninitialized() throws Exception {
1043 LinkProperties empty = new LinkProperties();
1044 assertParcelingIsLossless(empty);
1045 }
1046
1047 @Test
1048 public void testConstructor() {
1049 LinkProperties lp = new LinkProperties();
1050 checkEmpty(lp);
1051 assertLinkPropertiesEqual(lp, new LinkProperties(lp));
1052 assertLinkPropertiesEqual(lp, new LinkProperties());
1053
1054 lp = makeTestObject();
1055 assertLinkPropertiesEqual(lp, new LinkProperties(lp));
1056 }
1057
1058 @Test
1059 public void testDnsServers() {
1060 final LinkProperties lp = new LinkProperties();
1061 final List<InetAddress> dnsServers = Arrays.asList(DNS1, DNS2);
1062 lp.setDnsServers(dnsServers);
1063 assertEquals(2, lp.getDnsServers().size());
1064 assertEquals(DNS1, lp.getDnsServers().get(0));
1065 assertEquals(DNS2, lp.getDnsServers().get(1));
1066
1067 lp.removeDnsServer(DNS1);
1068 assertEquals(1, lp.getDnsServers().size());
1069 assertEquals(DNS2, lp.getDnsServers().get(0));
1070
1071 lp.addDnsServer(DNS6);
1072 assertEquals(2, lp.getDnsServers().size());
1073 assertEquals(DNS2, lp.getDnsServers().get(0));
1074 assertEquals(DNS6, lp.getDnsServers().get(1));
1075 }
1076
1077 @Test
1078 public void testValidatedPrivateDnsServers() {
1079 final LinkProperties lp = new LinkProperties();
1080 final List<InetAddress> privDnsServers = Arrays.asList(PRIVDNS1, PRIVDNS2);
1081 lp.setValidatedPrivateDnsServers(privDnsServers);
1082 assertEquals(2, lp.getValidatedPrivateDnsServers().size());
1083 assertEquals(PRIVDNS1, lp.getValidatedPrivateDnsServers().get(0));
1084 assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(1));
1085
1086 lp.removeValidatedPrivateDnsServer(PRIVDNS1);
1087 assertEquals(1, lp.getValidatedPrivateDnsServers().size());
1088 assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(0));
1089
1090 lp.addValidatedPrivateDnsServer(PRIVDNS6);
1091 assertEquals(2, lp.getValidatedPrivateDnsServers().size());
1092 assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(0));
1093 assertEquals(PRIVDNS6, lp.getValidatedPrivateDnsServers().get(1));
1094 }
1095
1096 @Test
1097 public void testPcscfServers() {
1098 final LinkProperties lp = new LinkProperties();
1099 final List<InetAddress> pcscfServers = Arrays.asList(PCSCFV4);
1100 lp.setPcscfServers(pcscfServers);
1101 assertEquals(1, lp.getPcscfServers().size());
1102 assertEquals(PCSCFV4, lp.getPcscfServers().get(0));
1103
1104 lp.removePcscfServer(PCSCFV4);
1105 assertEquals(0, lp.getPcscfServers().size());
1106
1107 lp.addPcscfServer(PCSCFV6);
1108 assertEquals(1, lp.getPcscfServers().size());
1109 assertEquals(PCSCFV6, lp.getPcscfServers().get(0));
1110 }
1111
1112 @Test
1113 public void testTcpBufferSizes() {
1114 final LinkProperties lp = makeTestObject();
1115 assertEquals(TCP_BUFFER_SIZES, lp.getTcpBufferSizes());
1116
1117 lp.setTcpBufferSizes(null);
1118 assertNull(lp.getTcpBufferSizes());
1119 }
1120
1121 @Test
1122 public void testHasIpv6DefaultRoute() {
1123 final LinkProperties lp = makeTestObject();
1124 assertFalse(lp.hasIPv6DefaultRoute());
1125
1126 lp.addRoute(new RouteInfo(GATEWAY61));
1127 assertTrue(lp.hasIPv6DefaultRoute());
1128 }
1129
1130 @Test
1131 public void testHttpProxy() {
1132 final LinkProperties lp = makeTestObject();
1133 assertTrue(lp.getHttpProxy().equals(ProxyInfo.buildDirectProxy("test", 8888)));
1134 }
1135
1136 @Test
1137 public void testPrivateDnsServerName() {
1138 final LinkProperties lp = makeTestObject();
1139 assertEquals(PRIV_DNS_SERVER_NAME, lp.getPrivateDnsServerName());
1140
1141 lp.setPrivateDnsServerName(null);
1142 assertNull(lp.getPrivateDnsServerName());
1143 }
1144
1145 @Test
1146 public void testUsePrivateDns() {
1147 final LinkProperties lp = makeTestObject();
1148 assertTrue(lp.isPrivateDnsActive());
1149
1150 lp.clear();
1151 assertFalse(lp.isPrivateDnsActive());
1152 }
1153
1154 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1155 public void testDhcpServerAddress() {
1156 final LinkProperties lp = makeTestObject();
1157 assertEquals(DHCPSERVER, lp.getDhcpServerAddress());
1158
1159 lp.clear();
1160 assertNull(lp.getDhcpServerAddress());
1161 }
1162
1163 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1164 public void testWakeOnLanSupported() {
1165 final LinkProperties lp = makeTestObject();
1166 assertTrue(lp.isWakeOnLanSupported());
1167
1168 lp.clear();
1169 assertFalse(lp.isWakeOnLanSupported());
1170 }
1171
1172 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1173 public void testCaptivePortalApiUrl() {
1174 final LinkProperties lp = makeTestObject();
1175 assertEquals(CAPPORT_API_URL, lp.getCaptivePortalApiUrl());
1176
1177 lp.clear();
1178 assertNull(lp.getCaptivePortalApiUrl());
1179 }
1180
1181 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1182 public void testCaptivePortalData() {
1183 final LinkProperties lp = makeTestObject();
1184 assertEquals(getCaptivePortalData(), lp.getCaptivePortalData());
1185
1186 lp.clear();
1187 assertNull(lp.getCaptivePortalData());
1188 }
1189
1190 private LinkProperties makeIpv4LinkProperties() {
1191 final LinkProperties linkProperties = new LinkProperties();
1192 linkProperties.setInterfaceName(NAME);
1193 linkProperties.addLinkAddress(LINKADDRV4);
1194 linkProperties.addDnsServer(DNS1);
1195 linkProperties.addRoute(new RouteInfo(GATEWAY1));
1196 linkProperties.addRoute(new RouteInfo(GATEWAY2));
1197 return linkProperties;
1198 }
1199
1200 private LinkProperties makeIpv6LinkProperties() {
1201 final LinkProperties linkProperties = new LinkProperties();
1202 linkProperties.setInterfaceName(NAME);
1203 linkProperties.addLinkAddress(LINKADDRV6);
1204 linkProperties.addDnsServer(DNS6);
1205 linkProperties.addRoute(new RouteInfo(GATEWAY61));
1206 linkProperties.addRoute(new RouteInfo(GATEWAY62));
1207 return linkProperties;
1208 }
1209
1210 @Test
1211 public void testHasIpv4DefaultRoute() {
1212 final LinkProperties Ipv4 = makeIpv4LinkProperties();
1213 assertTrue(Ipv4.hasIpv4DefaultRoute());
1214 final LinkProperties Ipv6 = makeIpv6LinkProperties();
1215 assertFalse(Ipv6.hasIpv4DefaultRoute());
1216 }
1217
1218 @Test
1219 public void testHasIpv4DnsServer() {
1220 final LinkProperties Ipv4 = makeIpv4LinkProperties();
1221 assertTrue(Ipv4.hasIpv4DnsServer());
1222 final LinkProperties Ipv6 = makeIpv6LinkProperties();
1223 assertFalse(Ipv6.hasIpv4DnsServer());
1224 }
1225
1226 @Test
1227 public void testHasIpv6DnsServer() {
1228 final LinkProperties Ipv4 = makeIpv4LinkProperties();
1229 assertFalse(Ipv4.hasIpv6DnsServer());
1230 final LinkProperties Ipv6 = makeIpv6LinkProperties();
1231 assertTrue(Ipv6.hasIpv6DnsServer());
1232 }
1233
1234 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1235 public void testHasIpv4UnreachableDefaultRoute() {
1236 final LinkProperties lp = makeTestObject();
1237 assertFalse(lp.hasIpv4UnreachableDefaultRoute());
1238 assertFalse(lp.hasIpv6UnreachableDefaultRoute());
1239
1240 lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
1241 assertTrue(lp.hasIpv4UnreachableDefaultRoute());
1242 assertFalse(lp.hasIpv6UnreachableDefaultRoute());
1243 }
1244
1245 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1246 public void testHasIpv6UnreachableDefaultRoute() {
1247 final LinkProperties lp = makeTestObject();
1248 assertFalse(lp.hasIpv6UnreachableDefaultRoute());
1249 assertFalse(lp.hasIpv4UnreachableDefaultRoute());
1250
1251 lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
1252 assertTrue(lp.hasIpv6UnreachableDefaultRoute());
1253 assertFalse(lp.hasIpv4UnreachableDefaultRoute());
1254 }
1255
1256 @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
1257 public void testRouteAddWithSameKey() throws Exception {
1258 LinkProperties lp = new LinkProperties();
1259 lp.setInterfaceName("wlan0");
1260 final IpPrefix v6 = new IpPrefix("64:ff9b::/96");
1261 lp.addRoute(new RouteInfo(v6, address("fe80::1"), "wlan0", RTN_UNICAST, 1280));
1262 assertEquals(1, lp.getRoutes().size());
1263 lp.addRoute(new RouteInfo(v6, address("fe80::1"), "wlan0", RTN_UNICAST, 1500));
1264 assertEquals(1, lp.getRoutes().size());
1265 final IpPrefix v4 = new IpPrefix("192.0.2.128/25");
1266 lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_UNICAST, 1460));
1267 assertEquals(2, lp.getRoutes().size());
1268 lp.addRoute(new RouteInfo(v4, address("192.0.2.1"), "wlan0", RTN_THROW, 1460));
1269 assertEquals(2, lp.getRoutes().size());
1270 }
1271}