Home | History | Annotate | Download | only in net
      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