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.LinkProperties; 20 import android.net.RouteInfo; 21 import android.system.OsConstants; 22 import android.test.suitebuilder.annotation.SmallTest; 23 import junit.framework.TestCase; 24 25 import java.net.InetAddress; 26 import java.util.ArrayList; 27 28 public class LinkPropertiesTest extends TestCase { 29 private static InetAddress ADDRV4 = NetworkUtils.numericToInetAddress("75.208.6.1"); 30 private static InetAddress ADDRV6 = NetworkUtils.numericToInetAddress( 31 "2001:0db8:85a3:0000:0000:8a2e:0370:7334"); 32 private static InetAddress DNS1 = NetworkUtils.numericToInetAddress("75.208.7.1"); 33 private static InetAddress DNS2 = NetworkUtils.numericToInetAddress("69.78.7.1"); 34 private static InetAddress DNS6 = NetworkUtils.numericToInetAddress("2001:4860:4860::8888"); 35 private static InetAddress GATEWAY1 = NetworkUtils.numericToInetAddress("75.208.8.1"); 36 private static InetAddress GATEWAY2 = NetworkUtils.numericToInetAddress("69.78.8.1"); 37 private static InetAddress GATEWAY6 = NetworkUtils.numericToInetAddress("fe80::6:0000:613"); 38 private static String NAME = "qmi0"; 39 private static int MTU = 1500; 40 41 private static LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32); 42 private static LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128); 43 private static LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64"); 44 45 public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) { 46 // Check implementation of equals(), element by element. 47 assertTrue(source.isIdenticalInterfaceName(target)); 48 assertTrue(target.isIdenticalInterfaceName(source)); 49 50 assertTrue(source.isIdenticalAddresses(target)); 51 assertTrue(target.isIdenticalAddresses(source)); 52 53 assertTrue(source.isIdenticalDnses(target)); 54 assertTrue(target.isIdenticalDnses(source)); 55 56 assertTrue(source.isIdenticalRoutes(target)); 57 assertTrue(target.isIdenticalRoutes(source)); 58 59 assertTrue(source.isIdenticalHttpProxy(target)); 60 assertTrue(target.isIdenticalHttpProxy(source)); 61 62 assertTrue(source.isIdenticalStackedLinks(target)); 63 assertTrue(target.isIdenticalStackedLinks(source)); 64 65 assertTrue(source.isIdenticalMtu(target)); 66 assertTrue(target.isIdenticalMtu(source)); 67 68 // Check result of equals(). 69 assertTrue(source.equals(target)); 70 assertTrue(target.equals(source)); 71 72 // Check hashCode. 73 assertEquals(source.hashCode(), target.hashCode()); 74 } 75 76 @SmallTest 77 public void testEqualsNull() { 78 LinkProperties source = new LinkProperties(); 79 LinkProperties target = new LinkProperties(); 80 81 assertFalse(source == target); 82 assertLinkPropertiesEqual(source, target); 83 } 84 85 @SmallTest 86 public void testEqualsSameOrder() { 87 try { 88 LinkProperties source = new LinkProperties(); 89 source.setInterfaceName(NAME); 90 // set 2 link addresses 91 source.addLinkAddress(LINKADDRV4); 92 source.addLinkAddress(LINKADDRV6); 93 // set 2 dnses 94 source.addDnsServer(DNS1); 95 source.addDnsServer(DNS2); 96 // set 2 gateways 97 source.addRoute(new RouteInfo(GATEWAY1)); 98 source.addRoute(new RouteInfo(GATEWAY2)); 99 source.setMtu(MTU); 100 101 LinkProperties target = new LinkProperties(); 102 103 // All fields are same 104 target.setInterfaceName(NAME); 105 target.addLinkAddress(LINKADDRV4); 106 target.addLinkAddress(LINKADDRV6); 107 target.addDnsServer(DNS1); 108 target.addDnsServer(DNS2); 109 target.addRoute(new RouteInfo(GATEWAY1)); 110 target.addRoute(new RouteInfo(GATEWAY2)); 111 target.setMtu(MTU); 112 113 assertLinkPropertiesEqual(source, target); 114 115 target.clear(); 116 // change Interface Name 117 target.setInterfaceName("qmi1"); 118 target.addLinkAddress(LINKADDRV4); 119 target.addLinkAddress(LINKADDRV6); 120 target.addDnsServer(DNS1); 121 target.addDnsServer(DNS2); 122 target.addRoute(new RouteInfo(GATEWAY1)); 123 target.addRoute(new RouteInfo(GATEWAY2)); 124 target.setMtu(MTU); 125 assertFalse(source.equals(target)); 126 127 target.clear(); 128 target.setInterfaceName(NAME); 129 // change link addresses 130 target.addLinkAddress(new LinkAddress( 131 NetworkUtils.numericToInetAddress("75.208.6.2"), 32)); 132 target.addLinkAddress(LINKADDRV6); 133 target.addDnsServer(DNS1); 134 target.addDnsServer(DNS2); 135 target.addRoute(new RouteInfo(GATEWAY1)); 136 target.addRoute(new RouteInfo(GATEWAY2)); 137 target.setMtu(MTU); 138 assertFalse(source.equals(target)); 139 140 target.clear(); 141 target.setInterfaceName(NAME); 142 target.addLinkAddress(LINKADDRV4); 143 target.addLinkAddress(LINKADDRV6); 144 // change dnses 145 target.addDnsServer(NetworkUtils.numericToInetAddress("75.208.7.2")); 146 target.addDnsServer(DNS2); 147 target.addRoute(new RouteInfo(GATEWAY1)); 148 target.addRoute(new RouteInfo(GATEWAY2)); 149 target.setMtu(MTU); 150 assertFalse(source.equals(target)); 151 152 target.clear(); 153 target.setInterfaceName(NAME); 154 target.addLinkAddress(LINKADDRV4); 155 target.addLinkAddress(LINKADDRV6); 156 target.addDnsServer(DNS1); 157 target.addDnsServer(DNS2); 158 // change gateway 159 target.addRoute(new RouteInfo(NetworkUtils.numericToInetAddress("75.208.8.2"))); 160 target.addRoute(new RouteInfo(GATEWAY2)); 161 target.setMtu(MTU); 162 assertFalse(source.equals(target)); 163 164 target.clear(); 165 target.setInterfaceName(NAME); 166 target.addLinkAddress(LINKADDRV4); 167 target.addLinkAddress(LINKADDRV6); 168 target.addDnsServer(DNS1); 169 target.addDnsServer(DNS2); 170 target.addRoute(new RouteInfo(GATEWAY1)); 171 target.addRoute(new RouteInfo(GATEWAY2)); 172 // change mtu 173 target.setMtu(1440); 174 assertFalse(source.equals(target)); 175 176 } catch (Exception e) { 177 throw new RuntimeException(e.toString()); 178 //fail(); 179 } 180 } 181 182 @SmallTest 183 public void testEqualsDifferentOrder() { 184 try { 185 LinkProperties source = new LinkProperties(); 186 source.setInterfaceName(NAME); 187 // set 2 link addresses 188 source.addLinkAddress(LINKADDRV4); 189 source.addLinkAddress(LINKADDRV6); 190 // set 2 dnses 191 source.addDnsServer(DNS1); 192 source.addDnsServer(DNS2); 193 // set 2 gateways 194 source.addRoute(new RouteInfo(GATEWAY1)); 195 source.addRoute(new RouteInfo(GATEWAY2)); 196 source.setMtu(MTU); 197 198 LinkProperties target = new LinkProperties(); 199 // Exchange order 200 target.setInterfaceName(NAME); 201 target.addLinkAddress(LINKADDRV6); 202 target.addLinkAddress(LINKADDRV4); 203 target.addDnsServer(DNS2); 204 target.addDnsServer(DNS1); 205 target.addRoute(new RouteInfo(GATEWAY2)); 206 target.addRoute(new RouteInfo(GATEWAY1)); 207 target.setMtu(MTU); 208 209 assertLinkPropertiesEqual(source, target); 210 } catch (Exception e) { 211 fail(); 212 } 213 } 214 215 @SmallTest 216 public void testEqualsDuplicated() { 217 try { 218 LinkProperties source = new LinkProperties(); 219 // set 3 link addresses, eg, [A, A, B] 220 source.addLinkAddress(LINKADDRV4); 221 source.addLinkAddress(LINKADDRV4); 222 source.addLinkAddress(LINKADDRV6); 223 224 LinkProperties target = new LinkProperties(); 225 // set 3 link addresses, eg, [A, B, B] 226 target.addLinkAddress(LINKADDRV4); 227 target.addLinkAddress(LINKADDRV6); 228 target.addLinkAddress(LINKADDRV6); 229 230 assertLinkPropertiesEqual(source, target); 231 } catch (Exception e) { 232 fail(); 233 } 234 } 235 236 private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) { 237 for (RouteInfo r : lp.getRoutes()) { 238 assertEquals(iface, r.getInterface()); 239 } 240 } 241 242 @SmallTest 243 public void testRouteInterfaces() { 244 LinkAddress prefix = new LinkAddress( 245 NetworkUtils.numericToInetAddress("2001:db8::"), 32); 246 InetAddress address = ADDRV6; 247 248 // Add a route with no interface to a LinkProperties with no interface. No errors. 249 LinkProperties lp = new LinkProperties(); 250 RouteInfo r = new RouteInfo(prefix, address, null); 251 assertTrue(lp.addRoute(r)); 252 assertEquals(1, lp.getRoutes().size()); 253 assertAllRoutesHaveInterface(null, lp); 254 255 // Adding the same route twice has no effect. 256 assertFalse(lp.addRoute(r)); 257 assertEquals(1, lp.getRoutes().size()); 258 259 // Add a route with an interface. Expect an exception. 260 r = new RouteInfo(prefix, address, "wlan0"); 261 try { 262 lp.addRoute(r); 263 fail("Adding wlan0 route to LP with no interface, expect exception"); 264 } catch (IllegalArgumentException expected) {} 265 266 // Change the interface name. All the routes should change their interface name too. 267 lp.setInterfaceName("rmnet0"); 268 assertAllRoutesHaveInterface("rmnet0", lp); 269 270 // Now add a route with the wrong interface. This causes an exception too. 271 try { 272 lp.addRoute(r); 273 fail("Adding wlan0 route to rmnet0 LP, expect exception"); 274 } catch (IllegalArgumentException expected) {} 275 276 // If the interface name matches, the route is added. 277 r = new RouteInfo(prefix, null, "wlan0"); 278 lp.setInterfaceName("wlan0"); 279 lp.addRoute(r); 280 assertEquals(2, lp.getRoutes().size()); 281 assertAllRoutesHaveInterface("wlan0", lp); 282 283 // Routes with null interfaces are converted to wlan0. 284 r = RouteInfo.makeHostRoute(ADDRV6, null); 285 lp.addRoute(r); 286 assertEquals(3, lp.getRoutes().size()); 287 assertAllRoutesHaveInterface("wlan0", lp); 288 289 // Check comparisons work. 290 LinkProperties lp2 = new LinkProperties(lp); 291 assertAllRoutesHaveInterface("wlan0", lp); 292 assertEquals(0, lp.compareAllRoutes(lp2).added.size()); 293 assertEquals(0, lp.compareAllRoutes(lp2).removed.size()); 294 295 lp2.setInterfaceName("p2p0"); 296 assertAllRoutesHaveInterface("p2p0", lp2); 297 assertEquals(3, lp.compareAllRoutes(lp2).added.size()); 298 assertEquals(3, lp.compareAllRoutes(lp2).removed.size()); 299 } 300 301 @SmallTest 302 public void testStackedInterfaces() { 303 LinkProperties rmnet0 = new LinkProperties(); 304 rmnet0.setInterfaceName("rmnet0"); 305 rmnet0.addLinkAddress(LINKADDRV6); 306 307 LinkProperties clat4 = new LinkProperties(); 308 clat4.setInterfaceName("clat4"); 309 clat4.addLinkAddress(LINKADDRV4); 310 311 assertEquals(0, rmnet0.getStackedLinks().size()); 312 assertEquals(1, rmnet0.getAddresses().size()); 313 assertEquals(1, rmnet0.getLinkAddresses().size()); 314 assertEquals(1, rmnet0.getAllAddresses().size()); 315 assertEquals(1, rmnet0.getAllLinkAddresses().size()); 316 317 rmnet0.addStackedLink(clat4); 318 assertEquals(1, rmnet0.getStackedLinks().size()); 319 assertEquals(1, rmnet0.getAddresses().size()); 320 assertEquals(1, rmnet0.getLinkAddresses().size()); 321 assertEquals(2, rmnet0.getAllAddresses().size()); 322 assertEquals(2, rmnet0.getAllLinkAddresses().size()); 323 324 rmnet0.addStackedLink(clat4); 325 assertEquals(1, rmnet0.getStackedLinks().size()); 326 assertEquals(1, rmnet0.getAddresses().size()); 327 assertEquals(1, rmnet0.getLinkAddresses().size()); 328 assertEquals(2, rmnet0.getAllAddresses().size()); 329 assertEquals(2, rmnet0.getAllLinkAddresses().size()); 330 331 assertEquals(0, clat4.getStackedLinks().size()); 332 333 // Modify an item in the returned collection to see what happens. 334 for (LinkProperties link : rmnet0.getStackedLinks()) { 335 if (link.getInterfaceName().equals("clat4")) { 336 link.setInterfaceName("newname"); 337 } 338 } 339 for (LinkProperties link : rmnet0.getStackedLinks()) { 340 assertFalse("newname".equals(link.getInterfaceName())); 341 } 342 343 assertTrue(rmnet0.removeStackedLink("clat4")); 344 assertEquals(0, rmnet0.getStackedLinks().size()); 345 assertEquals(1, rmnet0.getAddresses().size()); 346 assertEquals(1, rmnet0.getLinkAddresses().size()); 347 assertEquals(1, rmnet0.getAllAddresses().size()); 348 assertEquals(1, rmnet0.getAllLinkAddresses().size()); 349 350 assertFalse(rmnet0.removeStackedLink("clat4")); 351 } 352 353 private LinkAddress getFirstLinkAddress(LinkProperties lp) { 354 return lp.getLinkAddresses().iterator().next(); 355 } 356 357 @SmallTest 358 public void testAddressMethods() { 359 LinkProperties lp = new LinkProperties(); 360 361 // No addresses. 362 assertFalse(lp.hasIPv4Address()); 363 assertFalse(lp.hasGlobalIPv6Address()); 364 365 // Addresses on stacked links don't count. 366 LinkProperties stacked = new LinkProperties(); 367 stacked.setInterfaceName("stacked"); 368 lp.addStackedLink(stacked); 369 stacked.addLinkAddress(LINKADDRV4); 370 stacked.addLinkAddress(LINKADDRV6); 371 assertTrue(stacked.hasIPv4Address()); 372 assertTrue(stacked.hasGlobalIPv6Address()); 373 assertFalse(lp.hasIPv4Address()); 374 assertFalse(lp.hasGlobalIPv6Address()); 375 lp.removeStackedLink("stacked"); 376 assertFalse(lp.hasIPv4Address()); 377 assertFalse(lp.hasGlobalIPv6Address()); 378 379 // Addresses on the base link. 380 // Check the return values of hasIPvXAddress and ensure the add/remove methods return true 381 // iff something changes. 382 assertEquals(0, lp.getLinkAddresses().size()); 383 assertTrue(lp.addLinkAddress(LINKADDRV6)); 384 assertEquals(1, lp.getLinkAddresses().size()); 385 assertFalse(lp.hasIPv4Address()); 386 assertTrue(lp.hasGlobalIPv6Address()); 387 388 assertTrue(lp.removeLinkAddress(LINKADDRV6)); 389 assertEquals(0, lp.getLinkAddresses().size()); 390 391 assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL)); 392 assertEquals(1, lp.getLinkAddresses().size()); 393 assertFalse(lp.hasGlobalIPv6Address()); 394 395 assertTrue(lp.addLinkAddress(LINKADDRV4)); 396 assertEquals(2, lp.getLinkAddresses().size()); 397 assertTrue(lp.hasIPv4Address()); 398 assertFalse(lp.hasGlobalIPv6Address()); 399 400 assertTrue(lp.addLinkAddress(LINKADDRV6)); 401 assertEquals(3, lp.getLinkAddresses().size()); 402 assertTrue(lp.hasIPv4Address()); 403 assertTrue(lp.hasGlobalIPv6Address()); 404 405 assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL)); 406 assertEquals(2, lp.getLinkAddresses().size()); 407 assertTrue(lp.hasIPv4Address()); 408 assertTrue(lp.hasGlobalIPv6Address()); 409 410 // Adding an address twice has no effect. 411 // Removing an address that's not present has no effect. 412 assertFalse(lp.addLinkAddress(LINKADDRV4)); 413 assertEquals(2, lp.getLinkAddresses().size()); 414 assertTrue(lp.hasIPv4Address()); 415 assertTrue(lp.removeLinkAddress(LINKADDRV4)); 416 assertEquals(1, lp.getLinkAddresses().size()); 417 assertFalse(lp.hasIPv4Address()); 418 assertFalse(lp.removeLinkAddress(LINKADDRV4)); 419 assertEquals(1, lp.getLinkAddresses().size()); 420 421 // Adding an address that's already present but with different properties causes the 422 // existing address to be updated and returns true. 423 // Start with only LINKADDRV6. 424 assertEquals(1, lp.getLinkAddresses().size()); 425 assertEquals(LINKADDRV6, getFirstLinkAddress(lp)); 426 427 // Create a LinkAddress object for the same address, but with different flags. 428 LinkAddress deprecated = new LinkAddress(ADDRV6, 128, 429 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE); 430 assertTrue(deprecated.isSameAddressAs(LINKADDRV6)); 431 assertFalse(deprecated.equals(LINKADDRV6)); 432 433 // Check that adding it updates the existing address instead of adding a new one. 434 assertTrue(lp.addLinkAddress(deprecated)); 435 assertEquals(1, lp.getLinkAddresses().size()); 436 assertEquals(deprecated, getFirstLinkAddress(lp)); 437 assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp))); 438 439 // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties. 440 assertTrue(lp.removeLinkAddress(LINKADDRV6)); 441 assertEquals(0, lp.getLinkAddresses().size()); 442 } 443 444 @SmallTest 445 public void testSetLinkAddresses() { 446 LinkProperties lp = new LinkProperties(); 447 lp.addLinkAddress(LINKADDRV4); 448 lp.addLinkAddress(LINKADDRV6); 449 450 LinkProperties lp2 = new LinkProperties(); 451 lp2.addLinkAddress(LINKADDRV6); 452 453 assertFalse(lp.equals(lp2)); 454 455 lp2.setLinkAddresses(lp.getLinkAddresses()); 456 assertTrue(lp.equals(lp)); 457 } 458 459 @SmallTest 460 public void testIsProvisioned() { 461 LinkProperties lp4 = new LinkProperties(); 462 assertFalse("v4only:empty", lp4.isProvisioned()); 463 lp4.addLinkAddress(LINKADDRV4); 464 assertFalse("v4only:addr-only", lp4.isProvisioned()); 465 lp4.addDnsServer(DNS1); 466 assertFalse("v4only:addr+dns", lp4.isProvisioned()); 467 lp4.addRoute(new RouteInfo(GATEWAY1)); 468 assertTrue("v4only:addr+dns+route", lp4.isProvisioned()); 469 470 LinkProperties lp6 = new LinkProperties(); 471 assertFalse("v6only:empty", lp6.isProvisioned()); 472 lp6.addLinkAddress(LINKADDRV6LINKLOCAL); 473 assertFalse("v6only:fe80-only", lp6.isProvisioned()); 474 lp6.addDnsServer(DNS6); 475 assertFalse("v6only:fe80+dns", lp6.isProvisioned()); 476 lp6.addRoute(new RouteInfo(GATEWAY6)); 477 assertFalse("v6only:fe80+dns+route", lp6.isProvisioned()); 478 lp6.addLinkAddress(LINKADDRV6); 479 assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned()); 480 lp6.removeLinkAddress(LINKADDRV6LINKLOCAL); 481 assertTrue("v6only:global+dns+route", lp6.isProvisioned()); 482 483 LinkProperties lp46 = new LinkProperties(); 484 lp46.addLinkAddress(LINKADDRV4); 485 lp46.addLinkAddress(LINKADDRV6); 486 lp46.addDnsServer(DNS1); 487 lp46.addDnsServer(DNS6); 488 assertFalse("dualstack:missing-routes", lp46.isProvisioned()); 489 lp46.addRoute(new RouteInfo(GATEWAY1)); 490 assertTrue("dualstack:v4-provisioned", lp46.isProvisioned()); 491 lp6.addRoute(new RouteInfo(GATEWAY6)); 492 assertTrue("dualstack:both-provisioned", lp46.isProvisioned()); 493 494 // A link with an IPv6 address and default route, but IPv4 DNS server. 495 LinkProperties mixed = new LinkProperties(); 496 mixed.addLinkAddress(LINKADDRV6); 497 mixed.addDnsServer(DNS1); 498 mixed.addRoute(new RouteInfo(GATEWAY6)); 499 assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned()); 500 } 501 } 502