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 android.net.IpPrefix; 20 import android.net.LinkAddress; 21 import android.net.LinkProperties; 22 import android.net.LinkProperties.ProvisioningChange; 23 import android.net.RouteInfo; 24 import android.system.OsConstants; 25 import android.test.suitebuilder.annotation.SmallTest; 26 import junit.framework.TestCase; 27 28 import java.net.InetAddress; 29 import java.util.ArrayList; 30 31 32 public class LinkPropertiesTest extends TestCase { 33 private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1"); 34 private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress( 35 "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); 36 private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1"); 37 private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1"); 38 private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888"); 39 private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1"); 40 private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1"); 41 private static InetAddress GATEWAY61 = NetworkUtils.numericToInetAddress("fe80::6:0000:613"); 42 private static InetAddress GATEWAY62 = NetworkUtils.numericToInetAddress("fe80::6:2222"); 43 private static String NAME = "qmi0"; 44 private static int MTU = 1500; 45 46 private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32); 47 private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128); 48 private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64"); 49 50 public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) { 51 // Check implementation of equals(), element by element. 52 assertTrue(source.isIdenticalInterfaceName(target)); 53 assertTrue(target.isIdenticalInterfaceName(source)); 54 55 assertTrue(source.isIdenticalAddresses(target)); 56 assertTrue(target.isIdenticalAddresses(source)); 57 58 assertTrue(source.isIdenticalDnses(target)); 59 assertTrue(target.isIdenticalDnses(source)); 60 61 assertTrue(source.isIdenticalRoutes(target)); 62 assertTrue(target.isIdenticalRoutes(source)); 63 64 assertTrue(source.isIdenticalHttpProxy(target)); 65 assertTrue(target.isIdenticalHttpProxy(source)); 66 67 assertTrue(source.isIdenticalStackedLinks(target)); 68 assertTrue(target.isIdenticalStackedLinks(source)); 69 70 assertTrue(source.isIdenticalMtu(target)); 71 assertTrue(target.isIdenticalMtu(source)); 72 73 // Check result of equals(). 74 assertTrue(source.equals(target)); 75 assertTrue(target.equals(source)); 76 77 // Check hashCode. 78 assertEquals(source.hashCode(), target.hashCode()); 79 } 80 81 @SmallTest 82 public void testEqualsNull() { 83 LinkProperties source = new LinkProperties(); 84 LinkProperties target = new LinkProperties(); 85 86 assertFalse(source == target); 87 assertLinkPropertiesEqual(source, target); 88 } 89 90 @SmallTest 91 public void testEqualsSameOrder() { 92 try { 93 LinkProperties source = new LinkProperties(); 94 source.setInterfaceName(NAME); 95 // set 2 link addresses 96 source.addLinkAddress(LINKADDRV4); 97 source.addLinkAddress(LINKADDRV6); 98 // set 2 dnses 99 source.addDnsServer(DNS1); 100 source.addDnsServer(DNS2); 101 // set 2 gateways 102 source.addRoute(new RouteInfo(GATEWAY1)); 103 source.addRoute(new RouteInfo(GATEWAY2)); 104 source.setMtu(MTU); 105 106 LinkProperties target = new LinkProperties(); 107 108 // All fields are same 109 target.setInterfaceName(NAME); 110 target.addLinkAddress(LINKADDRV4); 111 target.addLinkAddress(LINKADDRV6); 112 target.addDnsServer(DNS1); 113 target.addDnsServer(DNS2); 114 target.addRoute(new RouteInfo(GATEWAY1)); 115 target.addRoute(new RouteInfo(GATEWAY2)); 116 target.setMtu(MTU); 117 118 assertLinkPropertiesEqual(source, target); 119 120 target.clear(); 121 // change Interface Name 122 target.setInterfaceName("qmi1"); 123 target.addLinkAddress(LINKADDRV4); 124 target.addLinkAddress(LINKADDRV6); 125 target.addDnsServer(DNS1); 126 target.addDnsServer(DNS2); 127 target.addRoute(new RouteInfo(GATEWAY1)); 128 target.addRoute(new RouteInfo(GATEWAY2)); 129 target.setMtu(MTU); 130 assertFalse(source.equals(target)); 131 132 target.clear(); 133 target.setInterfaceName(NAME); 134 // change link addresses 135 target.addLinkAddress(new LinkAddress( 136 NetworkUtils.numericToInetAddress("75.208.6.2"), 32)); 137 target.addLinkAddress(LINKADDRV6); 138 target.addDnsServer(DNS1); 139 target.addDnsServer(DNS2); 140 target.addRoute(new RouteInfo(GATEWAY1)); 141 target.addRoute(new RouteInfo(GATEWAY2)); 142 target.setMtu(MTU); 143 assertFalse(source.equals(target)); 144 145 target.clear(); 146 target.setInterfaceName(NAME); 147 target.addLinkAddress(LINKADDRV4); 148 target.addLinkAddress(LINKADDRV6); 149 // change dnses 150 target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2")); 151 target.addDnsServer(DNS2); 152 target.addRoute(new RouteInfo(GATEWAY1)); 153 target.addRoute(new RouteInfo(GATEWAY2)); 154 target.setMtu(MTU); 155 assertFalse(source.equals(target)); 156 157 target.clear(); 158 target.setInterfaceName(NAME); 159 target.addLinkAddress(LINKADDRV4); 160 target.addLinkAddress(LINKADDRV6); 161 target.addDnsServer(DNS1); 162 target.addDnsServer(DNS2); 163 // change gateway 164 target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2"))); 165 target.addRoute(new RouteInfo(GATEWAY2)); 166 target.setMtu(MTU); 167 assertFalse(source.equals(target)); 168 169 target.clear(); 170 target.setInterfaceName(NAME); 171 target.addLinkAddress(LINKADDRV4); 172 target.addLinkAddress(LINKADDRV6); 173 target.addDnsServer(DNS1); 174 target.addDnsServer(DNS2); 175 target.addRoute(new RouteInfo(GATEWAY1)); 176 target.addRoute(new RouteInfo(GATEWAY2)); 177 // change mtu 178 target.setMtu(1440); 179 assertFalse(source.equals(target)); 180 181 } catch (Exception e) { 182 throw new RuntimeException(e.toString()); 183 //fail(); 184 } 185 } 186 187 @SmallTest 188 public void testEqualsDifferentOrder() { 189 try { 190 LinkProperties source = new LinkProperties(); 191 source.setInterfaceName(NAME); 192 // set 2 link addresses 193 source.addLinkAddress(LINKADDRV4); 194 source.addLinkAddress(LINKADDRV6); 195 // set 2 dnses 196 source.addDnsServer(DNS1); 197 source.addDnsServer(DNS2); 198 // set 2 gateways 199 source.addRoute(new RouteInfo(GATEWAY1)); 200 source.addRoute(new RouteInfo(GATEWAY2)); 201 source.setMtu(MTU); 202 203 LinkProperties target = new LinkProperties(); 204 // Exchange order 205 target.setInterfaceName(NAME); 206 target.addLinkAddress(LINKADDRV6); 207 target.addLinkAddress(LINKADDRV4); 208 target.addDnsServer(DNS2); 209 target.addDnsServer(DNS1); 210 target.addRoute(new RouteInfo(GATEWAY2)); 211 target.addRoute(new RouteInfo(GATEWAY1)); 212 target.setMtu(MTU); 213 214 assertLinkPropertiesEqual(source, target); 215 } catch (Exception e) { 216 fail(); 217 } 218 } 219 220 @SmallTest 221 public void testEqualsDuplicated() { 222 try { 223 LinkProperties source = new LinkProperties(); 224 // set 3 link addresses, eg, [A, A, B] 225 source.addLinkAddress(LINKADDRV4); 226 source.addLinkAddress(LINKADDRV4); 227 source.addLinkAddress(LINKADDRV6); 228 229 LinkProperties target = new LinkProperties(); 230 // set 3 link addresses, eg, [A, B, B] 231 target.addLinkAddress(LINKADDRV4); 232 target.addLinkAddress(LINKADDRV6); 233 target.addLinkAddress(LINKADDRV6); 234 235 assertLinkPropertiesEqual(source, target); 236 } catch (Exception e) { 237 fail(); 238 } 239 } 240 241 private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) { 242 for (RouteInfo r : lp.getRoutes()) { 243 assertEquals(iface, r.getInterface()); 244 } 245 } 246 247 @SmallTest 248 public void testRouteInterfaces() { 249 LinkAddress prefix = new LinkAddress( 250 NetworkUtils.numericToInetAddress("2001:db8::"), 32); 251 InetAddress address = ADDRV6; 252 253 // Add a route with no interface to a LinkProperties with no interface. No errors. 254 LinkProperties lp = new LinkProperties(); 255 RouteInfo r = new RouteInfo(prefix, address, null); 256 assertTrue(lp.addRoute(r)); 257 assertEquals(1, lp.getRoutes().size()); 258 assertAllRoutesHaveInterface(null, lp); 259 260 // Adding the same route twice has no effect. 261 assertFalse(lp.addRoute(r)); 262 assertEquals(1, lp.getRoutes().size()); 263 264 // Add a route with an interface. Expect an exception. 265 r = new RouteInfo(prefix, address, "wlan0"); 266 try { 267 lp.addRoute(r); 268 fail("Adding wlan0 route to LP with no interface, expect exception"); 269 } catch (IllegalArgumentException expected) {} 270 271 // Change the interface name. All the routes should change their interface name too. 272 lp.setInterfaceName("rmnet0"); 273 assertAllRoutesHaveInterface("rmnet0", lp); 274 275 // Now add a route with the wrong interface. This causes an exception too. 276 try { 277 lp.addRoute(r); 278 fail("Adding wlan0 route to rmnet0 LP, expect exception"); 279 } catch (IllegalArgumentException expected) {} 280 281 // If the interface name matches, the route is added. 282 r = new RouteInfo(prefix, null, "wlan0"); 283 lp.setInterfaceName("wlan0"); 284 lp.addRoute(r); 285 assertEquals(2, lp.getRoutes().size()); 286 assertAllRoutesHaveInterface("wlan0", lp); 287 288 // Routes with null interfaces are converted to wlan0. 289 r = RouteInfo.makeHostRoute(ADDRV6, null); 290 lp.addRoute(r); 291 assertEquals(3, lp.getRoutes().size()); 292 assertAllRoutesHaveInterface("wlan0", lp); 293 294 // Check comparisons work. 295 LinkProperties lp2 = new LinkProperties(lp); 296 assertAllRoutesHaveInterface("wlan0", lp); 297 assertEquals(0, lp.compareAllRoutes(lp2).added.size()); 298 assertEquals(0, lp.compareAllRoutes(lp2).removed.size()); 299 300 lp2.setInterfaceName("p2p0"); 301 assertAllRoutesHaveInterface("p2p0", lp2); 302 assertEquals(3, lp.compareAllRoutes(lp2).added.size()); 303 assertEquals(3, lp.compareAllRoutes(lp2).removed.size()); 304 } 305 306 @SmallTest 307 public void testStackedInterfaces() { 308 LinkProperties rmnet0 = new LinkProperties(); 309 rmnet0.setInterfaceName("rmnet0"); 310 rmnet0.addLinkAddress(LINKADDRV6); 311 312 LinkProperties clat4 = new LinkProperties(); 313 clat4.setInterfaceName("clat4"); 314 clat4.addLinkAddress(LINKADDRV4); 315 316 assertEquals(0, rmnet0.getStackedLinks().size()); 317 assertEquals(1, rmnet0.getAddresses().size()); 318 assertEquals(1, rmnet0.getLinkAddresses().size()); 319 assertEquals(1, rmnet0.getAllAddresses().size()); 320 assertEquals(1, rmnet0.getAllLinkAddresses().size()); 321 322 rmnet0.addStackedLink(clat4); 323 assertEquals(1, rmnet0.getStackedLinks().size()); 324 assertEquals(1, rmnet0.getAddresses().size()); 325 assertEquals(1, rmnet0.getLinkAddresses().size()); 326 assertEquals(2, rmnet0.getAllAddresses().size()); 327 assertEquals(2, rmnet0.getAllLinkAddresses().size()); 328 329 rmnet0.addStackedLink(clat4); 330 assertEquals(1, rmnet0.getStackedLinks().size()); 331 assertEquals(1, rmnet0.getAddresses().size()); 332 assertEquals(1, rmnet0.getLinkAddresses().size()); 333 assertEquals(2, rmnet0.getAllAddresses().size()); 334 assertEquals(2, rmnet0.getAllLinkAddresses().size()); 335 336 assertEquals(0, clat4.getStackedLinks().size()); 337 338 // Modify an item in the returned collection to see what happens. 339 for (LinkProperties link : rmnet0.getStackedLinks()) { 340 if (link.getInterfaceName().equals("clat4")) { 341 link.setInterfaceName("newname"); 342 } 343 } 344 for (LinkProperties link : rmnet0.getStackedLinks()) { 345 assertFalse("newname".equals(link.getInterfaceName())); 346 } 347 348 assertTrue(rmnet0.removeStackedLink("clat4")); 349 assertEquals(0, rmnet0.getStackedLinks().size()); 350 assertEquals(1, rmnet0.getAddresses().size()); 351 assertEquals(1, rmnet0.getLinkAddresses().size()); 352 assertEquals(1, rmnet0.getAllAddresses().size()); 353 assertEquals(1, rmnet0.getAllLinkAddresses().size()); 354 355 assertFalse(rmnet0.removeStackedLink("clat4")); 356 } 357 358 private LinkAddress getFirstLinkAddress(LinkProperties lp) { 359 return lp.getLinkAddresses().iterator().next(); 360 } 361 362 @SmallTest 363 public void testAddressMethods() { 364 LinkProperties lp = new LinkProperties(); 365 366 // No addresses. 367 assertFalse(lp.hasIPv4Address()); 368 assertFalse(lp.hasGlobalIPv6Address()); 369 370 // Addresses on stacked links don't count. 371 LinkProperties stacked = new LinkProperties(); 372 stacked.setInterfaceName("stacked"); 373 lp.addStackedLink(stacked); 374 stacked.addLinkAddress(LINKADDRV4); 375 stacked.addLinkAddress(LINKADDRV6); 376 assertTrue(stacked.hasIPv4Address()); 377 assertTrue(stacked.hasGlobalIPv6Address()); 378 assertFalse(lp.hasIPv4Address()); 379 assertFalse(lp.hasGlobalIPv6Address()); 380 lp.removeStackedLink("stacked"); 381 assertFalse(lp.hasIPv4Address()); 382 assertFalse(lp.hasGlobalIPv6Address()); 383 384 // Addresses on the base link. 385 // Check the return values of hasIPvXAddress and ensure the add/remove methods return true 386 // iff something changes. 387 assertEquals(0, lp.getLinkAddresses().size()); 388 assertTrue(lp.addLinkAddress(LINKADDRV6)); 389 assertEquals(1, lp.getLinkAddresses().size()); 390 assertFalse(lp.hasIPv4Address()); 391 assertTrue(lp.hasGlobalIPv6Address()); 392 393 assertTrue(lp.removeLinkAddress(LINKADDRV6)); 394 assertEquals(0, lp.getLinkAddresses().size()); 395 396 assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL)); 397 assertEquals(1, lp.getLinkAddresses().size()); 398 assertFalse(lp.hasGlobalIPv6Address()); 399 400 assertTrue(lp.addLinkAddress(LINKADDRV4)); 401 assertEquals(2, lp.getLinkAddresses().size()); 402 assertTrue(lp.hasIPv4Address()); 403 assertFalse(lp.hasGlobalIPv6Address()); 404 405 assertTrue(lp.addLinkAddress(LINKADDRV6)); 406 assertEquals(3, lp.getLinkAddresses().size()); 407 assertTrue(lp.hasIPv4Address()); 408 assertTrue(lp.hasGlobalIPv6Address()); 409 410 assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL)); 411 assertEquals(2, lp.getLinkAddresses().size()); 412 assertTrue(lp.hasIPv4Address()); 413 assertTrue(lp.hasGlobalIPv6Address()); 414 415 // Adding an address twice has no effect. 416 // Removing an address that's not present has no effect. 417 assertFalse(lp.addLinkAddress(LINKADDRV4)); 418 assertEquals(2, lp.getLinkAddresses().size()); 419 assertTrue(lp.hasIPv4Address()); 420 assertTrue(lp.removeLinkAddress(LINKADDRV4)); 421 assertEquals(1, lp.getLinkAddresses().size()); 422 assertFalse(lp.hasIPv4Address()); 423 assertFalse(lp.removeLinkAddress(LINKADDRV4)); 424 assertEquals(1, lp.getLinkAddresses().size()); 425 426 // Adding an address that's already present but with different properties causes the 427 // existing address to be updated and returns true. 428 // Start with only LINKADDRV6. 429 assertEquals(1, lp.getLinkAddresses().size()); 430 assertEquals(LINKADDRV6, getFirstLinkAddress(lp)); 431 432 // Create a LinkAddress object for the same address, but with different flags. 433 LinkAddress deprecated = new LinkAddress(ADDRV6, 128, 434 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE); 435 assertTrue(deprecated.isSameAddressAs(LINKADDRV6)); 436 assertFalse(deprecated.equals(LINKADDRV6)); 437 438 // Check that adding it updates the existing address instead of adding a new one. 439 assertTrue(lp.addLinkAddress(deprecated)); 440 assertEquals(1, lp.getLinkAddresses().size()); 441 assertEquals(deprecated, getFirstLinkAddress(lp)); 442 assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp))); 443 444 // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties. 445 assertTrue(lp.removeLinkAddress(LINKADDRV6)); 446 assertEquals(0, lp.getLinkAddresses().size()); 447 } 448 449 @SmallTest 450 public void testSetLinkAddresses() { 451 LinkProperties lp = new LinkProperties(); 452 lp.addLinkAddress(LINKADDRV4); 453 lp.addLinkAddress(LINKADDRV6); 454 455 LinkProperties lp2 = new LinkProperties(); 456 lp2.addLinkAddress(LINKADDRV6); 457 458 assertFalse(lp.equals(lp2)); 459 460 lp2.setLinkAddresses(lp.getLinkAddresses()); 461 assertTrue(lp.equals(lp)); 462 } 463 464 @SmallTest 465 public void testIsProvisioned() { 466 LinkProperties lp4 = new LinkProperties(); 467 assertFalse("v4only:empty", lp4.isProvisioned()); 468 lp4.addLinkAddress(LINKADDRV4); 469 assertFalse("v4only:addr-only", lp4.isProvisioned()); 470 lp4.addDnsServer(DNS1); 471 assertFalse("v4only:addr+dns", lp4.isProvisioned()); 472 lp4.addRoute(new RouteInfo(GATEWAY1)); 473 assertTrue("v4only:addr+dns+route", lp4.isProvisioned()); 474 assertTrue("v4only:addr+dns+route", lp4.isIPv4Provisioned()); 475 assertFalse("v4only:addr+dns+route", lp4.isIPv6Provisioned()); 476 477 LinkProperties lp6 = new LinkProperties(); 478 assertFalse("v6only:empty", lp6.isProvisioned()); 479 lp6.addLinkAddress(LINKADDRV6LINKLOCAL); 480 assertFalse("v6only:fe80-only", lp6.isProvisioned()); 481 lp6.addDnsServer(DNS6); 482 assertFalse("v6only:fe80+dns", lp6.isProvisioned()); 483 lp6.addRoute(new RouteInfo(GATEWAY61)); 484 assertFalse("v6only:fe80+dns+route", lp6.isProvisioned()); 485 lp6.addLinkAddress(LINKADDRV6); 486 assertTrue("v6only:fe80+global+dns+route", lp6.isIPv6Provisioned()); 487 assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned()); 488 lp6.removeLinkAddress(LINKADDRV6LINKLOCAL); 489 assertFalse("v6only:global+dns+route", lp6.isIPv4Provisioned()); 490 assertTrue("v6only:global+dns+route", lp6.isIPv6Provisioned()); 491 assertTrue("v6only:global+dns+route", lp6.isProvisioned()); 492 493 LinkProperties lp46 = new LinkProperties(); 494 lp46.addLinkAddress(LINKADDRV4); 495 lp46.addLinkAddress(LINKADDRV6); 496 lp46.addDnsServer(DNS1); 497 lp46.addDnsServer(DNS6); 498 assertFalse("dualstack:missing-routes", lp46.isProvisioned()); 499 lp46.addRoute(new RouteInfo(GATEWAY1)); 500 assertTrue("dualstack:v4-provisioned", lp46.isIPv4Provisioned()); 501 assertFalse("dualstack:v4-provisioned", lp46.isIPv6Provisioned()); 502 assertTrue("dualstack:v4-provisioned", lp46.isProvisioned()); 503 lp46.addRoute(new RouteInfo(GATEWAY61)); 504 assertTrue("dualstack:both-provisioned", lp46.isIPv4Provisioned()); 505 assertTrue("dualstack:both-provisioned", lp46.isIPv6Provisioned()); 506 assertTrue("dualstack:both-provisioned", lp46.isProvisioned()); 507 508 // A link with an IPv6 address and default route, but IPv4 DNS server. 509 LinkProperties mixed = new LinkProperties(); 510 mixed.addLinkAddress(LINKADDRV6); 511 mixed.addDnsServer(DNS1); 512 mixed.addRoute(new RouteInfo(GATEWAY61)); 513 assertFalse("mixed:addr6+route6+dns4", mixed.isIPv4Provisioned()); 514 assertFalse("mixed:addr6+route6+dns4", mixed.isIPv6Provisioned()); 515 assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned()); 516 } 517 518 @SmallTest 519 public void testCompareProvisioning() { 520 LinkProperties v4lp = new LinkProperties(); 521 v4lp.addLinkAddress(LINKADDRV4); 522 v4lp.addRoute(new RouteInfo(GATEWAY1)); 523 v4lp.addDnsServer(DNS1); 524 assertTrue(v4lp.isProvisioned()); 525 526 LinkProperties v4r = new LinkProperties(v4lp); 527 v4r.removeDnsServer(DNS1); 528 assertFalse(v4r.isProvisioned()); 529 530 assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED, 531 LinkProperties.compareProvisioning(v4r, v4r)); 532 assertEquals(ProvisioningChange.LOST_PROVISIONING, 533 LinkProperties.compareProvisioning(v4lp, v4r)); 534 assertEquals(ProvisioningChange.GAINED_PROVISIONING, 535 LinkProperties.compareProvisioning(v4r, v4lp)); 536 assertEquals(ProvisioningChange.STILL_PROVISIONED, 537 LinkProperties.compareProvisioning(v4lp, v4lp)); 538 539 // Check that losing IPv4 provisioning on a dualstack network is 540 // seen as a total loss of provisioning. 541 LinkProperties v6lp = new LinkProperties(); 542 v6lp.addLinkAddress(LINKADDRV6); 543 v6lp.addRoute(new RouteInfo(GATEWAY61)); 544 v6lp.addDnsServer(DNS6); 545 assertFalse(v6lp.isIPv4Provisioned()); 546 assertTrue(v6lp.isIPv6Provisioned()); 547 assertTrue(v6lp.isProvisioned()); 548 549 LinkProperties v46lp = new LinkProperties(v6lp); 550 v46lp.addLinkAddress(LINKADDRV4); 551 v46lp.addRoute(new RouteInfo(GATEWAY1)); 552 v46lp.addDnsServer(DNS1); 553 assertTrue(v46lp.isIPv4Provisioned()); 554 assertTrue(v46lp.isIPv6Provisioned()); 555 assertTrue(v46lp.isProvisioned()); 556 557 assertEquals(ProvisioningChange.STILL_PROVISIONED, 558 LinkProperties.compareProvisioning(v6lp, v46lp)); 559 assertEquals(ProvisioningChange.LOST_PROVISIONING, 560 LinkProperties.compareProvisioning(v46lp, v6lp)); 561 562 // Check that losing and gaining a secondary router does not change 563 // the provisioning status. 564 LinkProperties v6lp2 = new LinkProperties(v6lp); 565 v6lp2.addRoute(new RouteInfo(GATEWAY62)); 566 assertTrue(v6lp2.isProvisioned()); 567 568 assertEquals(ProvisioningChange.STILL_PROVISIONED, 569 LinkProperties.compareProvisioning(v6lp2, v6lp)); 570 assertEquals(ProvisioningChange.STILL_PROVISIONED, 571 LinkProperties.compareProvisioning(v6lp, v6lp2)); 572 } 573 574 @SmallTest 575 public void testIsReachable() { 576 final LinkProperties v4lp = new LinkProperties(); 577 assertFalse(v4lp.isReachable(DNS1)); 578 assertFalse(v4lp.isReachable(DNS2)); 579 580 // Add an on-link route, making the on-link DNS server reachable, 581 // but there is still no IPv4 address. 582 assertTrue(v4lp.addRoute(new RouteInfo( 583 new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16)))); 584 assertFalse(v4lp.isReachable(DNS1)); 585 assertFalse(v4lp.isReachable(DNS2)); 586 587 // Adding an IPv4 address (right now, any IPv4 address) means we use 588 // the routes to compute likely reachability. 589 assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16))); 590 assertTrue(v4lp.isReachable(DNS1)); 591 assertFalse(v4lp.isReachable(DNS2)); 592 593 // Adding a default route makes the off-link DNS server reachable. 594 assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1))); 595 assertTrue(v4lp.isReachable(DNS1)); 596 assertTrue(v4lp.isReachable(DNS2)); 597 598 final LinkProperties v6lp = new LinkProperties(); 599 final InetAddress kLinkLocalDns = NetworkUtils.numericToInetAddress("fe80::6:1"); 600 final InetAddress kLinkLocalDnsWithScope = NetworkUtils.numericToInetAddress("fe80::6:2%43"); 601 final InetAddress kOnLinkDns = NetworkUtils.numericToInetAddress("2001:db8:85a3::53"); 602 assertFalse(v6lp.isReachable(kLinkLocalDns)); 603 assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope)); 604 assertFalse(v6lp.isReachable(kOnLinkDns)); 605 assertFalse(v6lp.isReachable(DNS6)); 606 607 // Add a link-local route, making the link-local DNS servers reachable. Because 608 // we assume the presence of an IPv6 link-local address, link-local DNS servers 609 // are considered reachable, but only those with a non-zero scope identifier. 610 assertTrue(v6lp.addRoute(new RouteInfo( 611 new IpPrefix(NetworkUtils.numericToInetAddress("fe80::"), 64)))); 612 assertFalse(v6lp.isReachable(kLinkLocalDns)); 613 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); 614 assertFalse(v6lp.isReachable(kOnLinkDns)); 615 assertFalse(v6lp.isReachable(DNS6)); 616 617 // Add a link-local address--nothing changes. 618 assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL)); 619 assertFalse(v6lp.isReachable(kLinkLocalDns)); 620 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); 621 assertFalse(v6lp.isReachable(kOnLinkDns)); 622 assertFalse(v6lp.isReachable(DNS6)); 623 624 // Add a global route on link, but no global address yet. DNS servers reachable 625 // via a route that doesn't require a gateway: give them the benefit of the 626 // doubt and hope the link-local source address suffices for communication. 627 assertTrue(v6lp.addRoute(new RouteInfo( 628 new IpPrefix(NetworkUtils.numericToInetAddress("2001:db8:85a3::"), 64)))); 629 assertFalse(v6lp.isReachable(kLinkLocalDns)); 630 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); 631 assertTrue(v6lp.isReachable(kOnLinkDns)); 632 assertFalse(v6lp.isReachable(DNS6)); 633 634 // Add a global address; the on-link global address DNS server is (still) 635 // presumed reachable. 636 assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64))); 637 assertFalse(v6lp.isReachable(kLinkLocalDns)); 638 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); 639 assertTrue(v6lp.isReachable(kOnLinkDns)); 640 assertFalse(v6lp.isReachable(DNS6)); 641 642 // Adding a default route makes the off-link DNS server reachable. 643 assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62))); 644 assertFalse(v6lp.isReachable(kLinkLocalDns)); 645 assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope)); 646 assertTrue(v6lp.isReachable(kOnLinkDns)); 647 assertTrue(v6lp.isReachable(DNS6)); 648 } 649 } 650