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