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