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