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 org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotEquals;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25 
26 import android.net.LinkProperties.CompareResult;
27 import android.net.LinkProperties.ProvisioningChange;
28 import android.system.OsConstants;
29 import android.util.ArraySet;
30 
31 import androidx.test.filters.SmallTest;
32 import androidx.test.runner.AndroidJUnit4;
33 
34 import com.android.internal.util.TestUtils;
35 
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 import java.net.InetAddress;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.Collections;
44 import java.util.List;
45 import java.util.Set;
46 
47 @RunWith(AndroidJUnit4.class)
48 @SmallTest
49 public class LinkPropertiesTest {
50     private static final InetAddress ADDRV4 = InetAddresses.parseNumericAddress("75.208.6.1");
51     private static final InetAddress ADDRV6 = InetAddresses.parseNumericAddress(
52             "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
53     private static final InetAddress DNS1 = InetAddresses.parseNumericAddress("75.208.7.1");
54     private static final InetAddress DNS2 = InetAddresses.parseNumericAddress("69.78.7.1");
55     private static final InetAddress DNS6 = InetAddresses.parseNumericAddress(
56             "2001:4860:4860::8888");
57     private static final InetAddress PRIVDNS1 = InetAddresses.parseNumericAddress("1.1.1.1");
58     private static final InetAddress PRIVDNS2 = InetAddresses.parseNumericAddress("1.0.0.1");
59     private static final InetAddress PRIVDNS6 = InetAddresses.parseNumericAddress(
60             "2606:4700:4700::1111");
61     private static final InetAddress PCSCFV4 = InetAddresses.parseNumericAddress("10.77.25.37");
62     private static final InetAddress PCSCFV6 = InetAddresses.parseNumericAddress(
63             "2001:0db8:85a3:0000:0000:8a2e:0370:1");
64     private static final InetAddress GATEWAY1 = InetAddresses.parseNumericAddress("75.208.8.1");
65     private static final InetAddress GATEWAY2 = InetAddresses.parseNumericAddress("69.78.8.1");
66     private static final InetAddress GATEWAY61 = InetAddresses.parseNumericAddress(
67             "fe80::6:0000:613");
68     private static final InetAddress GATEWAY62 = InetAddresses.parseNumericAddress("fe80::6:2222");
69     private static final String NAME = "qmi0";
70     private static final String DOMAINS = "google.com";
71     private static final String PRIV_DNS_SERVER_NAME = "private.dns.com";
72     private static final String TCP_BUFFER_SIZES = "524288,1048576,2097152,262144,524288,1048576";
73     private static final int MTU = 1500;
74     private static final LinkAddress LINKADDRV4 = new LinkAddress(ADDRV4, 32);
75     private static final LinkAddress LINKADDRV6 = new LinkAddress(ADDRV6, 128);
76     private static final LinkAddress LINKADDRV6LINKLOCAL = new LinkAddress("fe80::1/64");
77 
78     // TODO: replace all calls to NetworkUtils.numericToInetAddress with calls to this method.
Address(String addrString)79     private InetAddress Address(String addrString) {
80         return InetAddresses.parseNumericAddress(addrString);
81     }
82 
checkEmpty(final LinkProperties lp)83     private void checkEmpty(final LinkProperties lp) {
84         assertEquals(0, lp.getAllInterfaceNames().size());
85         assertEquals(0, lp.getAllAddresses().size());
86         assertEquals(0, lp.getDnsServers().size());
87         assertEquals(0, lp.getValidatedPrivateDnsServers().size());
88         assertEquals(0, lp.getPcscfServers().size());
89         assertEquals(0, lp.getAllRoutes().size());
90         assertEquals(0, lp.getAllLinkAddresses().size());
91         assertEquals(0, lp.getStackedLinks().size());
92         assertEquals(0, lp.getMtu());
93         assertNull(lp.getPrivateDnsServerName());
94         assertNull(lp.getDomains());
95         assertNull(lp.getHttpProxy());
96         assertNull(lp.getTcpBufferSizes());
97         assertNull(lp.getNat64Prefix());
98         assertFalse(lp.isProvisioned());
99         assertFalse(lp.isIpv4Provisioned());
100         assertFalse(lp.isIpv6Provisioned());
101         assertFalse(lp.isPrivateDnsActive());
102     }
103 
makeTestObject()104     private LinkProperties makeTestObject() {
105         final LinkProperties lp = new LinkProperties();
106         lp.setInterfaceName(NAME);
107         lp.addLinkAddress(LINKADDRV4);
108         lp.addLinkAddress(LINKADDRV6);
109         lp.addDnsServer(DNS1);
110         lp.addDnsServer(DNS2);
111         lp.addValidatedPrivateDnsServer(PRIVDNS1);
112         lp.addValidatedPrivateDnsServer(PRIVDNS2);
113         lp.setUsePrivateDns(true);
114         lp.setPrivateDnsServerName(PRIV_DNS_SERVER_NAME);
115         lp.addPcscfServer(PCSCFV6);
116         lp.setDomains(DOMAINS);
117         lp.addRoute(new RouteInfo(GATEWAY1));
118         lp.addRoute(new RouteInfo(GATEWAY2));
119         lp.setHttpProxy(ProxyInfo.buildDirectProxy("test", 8888));
120         lp.setMtu(MTU);
121         lp.setTcpBufferSizes(TCP_BUFFER_SIZES);
122         lp.setNat64Prefix(new IpPrefix("2001:db8:0:64::/96"));
123         return lp;
124     }
125 
assertLinkPropertiesEqual(LinkProperties source, LinkProperties target)126     public void assertLinkPropertiesEqual(LinkProperties source, LinkProperties target) {
127         // Check implementation of equals(), element by element.
128         assertTrue(source.isIdenticalInterfaceName(target));
129         assertTrue(target.isIdenticalInterfaceName(source));
130 
131         assertTrue(source.isIdenticalAddresses(target));
132         assertTrue(target.isIdenticalAddresses(source));
133 
134         assertTrue(source.isIdenticalDnses(target));
135         assertTrue(target.isIdenticalDnses(source));
136 
137         assertTrue(source.isIdenticalPrivateDns(target));
138         assertTrue(target.isIdenticalPrivateDns(source));
139 
140         assertTrue(source.isIdenticalValidatedPrivateDnses(target));
141         assertTrue(target.isIdenticalValidatedPrivateDnses(source));
142 
143         assertTrue(source.isIdenticalPcscfs(target));
144         assertTrue(target.isIdenticalPcscfs(source));
145 
146         assertTrue(source.isIdenticalRoutes(target));
147         assertTrue(target.isIdenticalRoutes(source));
148 
149         assertTrue(source.isIdenticalHttpProxy(target));
150         assertTrue(target.isIdenticalHttpProxy(source));
151 
152         assertTrue(source.isIdenticalStackedLinks(target));
153         assertTrue(target.isIdenticalStackedLinks(source));
154 
155         assertTrue(source.isIdenticalMtu(target));
156         assertTrue(target.isIdenticalMtu(source));
157 
158         assertTrue(source.isIdenticalTcpBufferSizes(target));
159         assertTrue(target.isIdenticalTcpBufferSizes(source));
160 
161         // Check result of equals().
162         assertTrue(source.equals(target));
163         assertTrue(target.equals(source));
164 
165         // Check hashCode.
166         assertEquals(source.hashCode(), target.hashCode());
167     }
168 
169     @Test
testEqualsNull()170     public void testEqualsNull() {
171         LinkProperties source = new LinkProperties();
172         LinkProperties target = new LinkProperties();
173 
174         assertFalse(source == target);
175         assertLinkPropertiesEqual(source, target);
176     }
177 
178     @Test
testEqualsSameOrder()179     public void testEqualsSameOrder() throws Exception {
180         LinkProperties source = new LinkProperties();
181         source.setInterfaceName(NAME);
182         // set 2 link addresses
183         source.addLinkAddress(LINKADDRV4);
184         source.addLinkAddress(LINKADDRV6);
185         // set 2 dnses
186         source.addDnsServer(DNS1);
187         source.addDnsServer(DNS2);
188         // set 1 pcscf
189         source.addPcscfServer(PCSCFV6);
190         // set 2 gateways
191         source.addRoute(new RouteInfo(GATEWAY1));
192         source.addRoute(new RouteInfo(GATEWAY2));
193         source.setMtu(MTU);
194 
195         LinkProperties target = new LinkProperties();
196 
197         // All fields are same
198         target.setInterfaceName(NAME);
199         target.addLinkAddress(LINKADDRV4);
200         target.addLinkAddress(LINKADDRV6);
201         target.addDnsServer(DNS1);
202         target.addDnsServer(DNS2);
203         target.addPcscfServer(PCSCFV6);
204         target.addRoute(new RouteInfo(GATEWAY1));
205         target.addRoute(new RouteInfo(GATEWAY2));
206         target.setMtu(MTU);
207 
208         assertLinkPropertiesEqual(source, target);
209 
210         target.clear();
211         // change Interface Name
212         target.setInterfaceName("qmi1");
213         target.addLinkAddress(LINKADDRV4);
214         target.addLinkAddress(LINKADDRV6);
215         target.addDnsServer(DNS1);
216         target.addDnsServer(DNS2);
217         target.addPcscfServer(PCSCFV6);
218         target.addRoute(new RouteInfo(GATEWAY1));
219         target.addRoute(new RouteInfo(GATEWAY2));
220         target.setMtu(MTU);
221         assertFalse(source.equals(target));
222 
223         target.clear();
224         target.setInterfaceName(NAME);
225         // change link addresses
226         target.addLinkAddress(new LinkAddress(Address("75.208.6.2"), 32));
227         target.addLinkAddress(LINKADDRV6);
228         target.addDnsServer(DNS1);
229         target.addDnsServer(DNS2);
230         target.addPcscfServer(PCSCFV6);
231         target.addRoute(new RouteInfo(GATEWAY1));
232         target.addRoute(new RouteInfo(GATEWAY2));
233         target.setMtu(MTU);
234         assertFalse(source.equals(target));
235 
236         target.clear();
237         target.setInterfaceName(NAME);
238         target.addLinkAddress(LINKADDRV4);
239         target.addLinkAddress(LINKADDRV6);
240         // change dnses
241         target.addDnsServer(Address("75.208.7.2"));
242         target.addDnsServer(DNS2);
243         target.addPcscfServer(PCSCFV6);
244         target.addRoute(new RouteInfo(GATEWAY1));
245         target.addRoute(new RouteInfo(GATEWAY2));
246         target.setMtu(MTU);
247         assertFalse(source.equals(target));
248 
249         target.clear();
250         target.setInterfaceName(NAME);
251         target.addLinkAddress(LINKADDRV4);
252         target.addLinkAddress(LINKADDRV6);
253         target.addDnsServer(Address("75.208.7.2"));
254         target.addDnsServer(DNS2);
255         // change pcscf
256         target.addPcscfServer(Address("2001::1"));
257         target.addRoute(new RouteInfo(GATEWAY1));
258         target.addRoute(new RouteInfo(GATEWAY2));
259         target.setMtu(MTU);
260         assertFalse(source.equals(target));
261 
262         target.clear();
263         target.setInterfaceName(NAME);
264         target.addLinkAddress(LINKADDRV4);
265         target.addLinkAddress(LINKADDRV6);
266         target.addDnsServer(DNS1);
267         target.addDnsServer(DNS2);
268         // change gateway
269         target.addRoute(new RouteInfo(Address("75.208.8.2")));
270         target.addRoute(new RouteInfo(GATEWAY2));
271         target.setMtu(MTU);
272         assertFalse(source.equals(target));
273 
274         target.clear();
275         target.setInterfaceName(NAME);
276         target.addLinkAddress(LINKADDRV4);
277         target.addLinkAddress(LINKADDRV6);
278         target.addDnsServer(DNS1);
279         target.addDnsServer(DNS2);
280         target.addRoute(new RouteInfo(GATEWAY1));
281         target.addRoute(new RouteInfo(GATEWAY2));
282         // change mtu
283         target.setMtu(1440);
284         assertFalse(source.equals(target));
285     }
286 
287     @Test
testEqualsDifferentOrder()288     public void testEqualsDifferentOrder() throws Exception {
289         LinkProperties source = new LinkProperties();
290         source.setInterfaceName(NAME);
291         // set 2 link addresses
292         source.addLinkAddress(LINKADDRV4);
293         source.addLinkAddress(LINKADDRV6);
294         // set 2 dnses
295         source.addDnsServer(DNS1);
296         source.addDnsServer(DNS2);
297         // set 2 gateways
298         source.addRoute(new RouteInfo(GATEWAY1));
299         source.addRoute(new RouteInfo(GATEWAY2));
300         source.setMtu(MTU);
301 
302         LinkProperties target = new LinkProperties();
303         // Exchange order
304         target.setInterfaceName(NAME);
305         target.addLinkAddress(LINKADDRV6);
306         target.addLinkAddress(LINKADDRV4);
307         target.addDnsServer(DNS2);
308         target.addDnsServer(DNS1);
309         target.addRoute(new RouteInfo(GATEWAY2));
310         target.addRoute(new RouteInfo(GATEWAY1));
311         target.setMtu(MTU);
312 
313         assertLinkPropertiesEqual(source, target);
314     }
315 
316     @Test
testEqualsDuplicated()317     public void testEqualsDuplicated() throws Exception {
318         LinkProperties source = new LinkProperties();
319         // set 3 link addresses, eg, [A, A, B]
320         source.addLinkAddress(LINKADDRV4);
321         source.addLinkAddress(LINKADDRV4);
322         source.addLinkAddress(LINKADDRV6);
323 
324         LinkProperties target = new LinkProperties();
325         // set 3 link addresses, eg, [A, B, B]
326         target.addLinkAddress(LINKADDRV4);
327         target.addLinkAddress(LINKADDRV6);
328         target.addLinkAddress(LINKADDRV6);
329 
330         assertLinkPropertiesEqual(source, target);
331     }
332 
assertAllRoutesHaveInterface(String iface, LinkProperties lp)333     private void assertAllRoutesHaveInterface(String iface, LinkProperties lp) {
334         for (RouteInfo r : lp.getRoutes()) {
335             assertEquals(iface, r.getInterface());
336         }
337     }
338 
assertAllRoutesNotHaveInterface(String iface, LinkProperties lp)339     private void assertAllRoutesNotHaveInterface(String iface, LinkProperties lp) {
340         for (RouteInfo r : lp.getRoutes()) {
341             assertNotEquals(iface, r.getInterface());
342         }
343     }
344 
345     @Test
testRouteInterfaces()346     public void testRouteInterfaces() {
347         LinkAddress prefix = new LinkAddress(Address("2001:db8::"), 32);
348         InetAddress address = ADDRV6;
349 
350         // Add a route with no interface to a LinkProperties with no interface. No errors.
351         LinkProperties lp = new LinkProperties();
352         RouteInfo r = new RouteInfo(prefix, address, null);
353         assertTrue(lp.addRoute(r));
354         assertEquals(1, lp.getRoutes().size());
355         assertAllRoutesHaveInterface(null, lp);
356 
357         // Adding the same route twice has no effect.
358         assertFalse(lp.addRoute(r));
359         assertEquals(1, lp.getRoutes().size());
360 
361         // Add a route with an interface. Expect an exception.
362         r = new RouteInfo(prefix, address, "wlan0");
363         try {
364           lp.addRoute(r);
365           fail("Adding wlan0 route to LP with no interface, expect exception");
366         } catch (IllegalArgumentException expected) {}
367 
368         // Change the interface name. All the routes should change their interface name too.
369         lp.setInterfaceName("rmnet0");
370         assertAllRoutesHaveInterface("rmnet0", lp);
371         assertAllRoutesNotHaveInterface(null, lp);
372         assertAllRoutesNotHaveInterface("wlan0", lp);
373 
374         // Now add a route with the wrong interface. This causes an exception too.
375         try {
376           lp.addRoute(r);
377           fail("Adding wlan0 route to rmnet0 LP, expect exception");
378         } catch (IllegalArgumentException expected) {}
379 
380         // If the interface name matches, the route is added.
381         r = new RouteInfo(prefix, null, "wlan0");
382         lp.setInterfaceName("wlan0");
383         lp.addRoute(r);
384         assertEquals(2, lp.getRoutes().size());
385         assertAllRoutesHaveInterface("wlan0", lp);
386         assertAllRoutesNotHaveInterface("rmnet0", lp);
387 
388         // Routes with null interfaces are converted to wlan0.
389         r = RouteInfo.makeHostRoute(ADDRV6, null);
390         lp.addRoute(r);
391         assertEquals(3, lp.getRoutes().size());
392         assertAllRoutesHaveInterface("wlan0", lp);
393 
394         // Check comparisons work.
395         LinkProperties lp2 = new LinkProperties(lp);
396         assertAllRoutesHaveInterface("wlan0", lp2);
397         assertEquals(0, lp.compareAllRoutes(lp2).added.size());
398         assertEquals(0, lp.compareAllRoutes(lp2).removed.size());
399 
400         lp2.setInterfaceName("p2p0");
401         assertAllRoutesHaveInterface("p2p0", lp2);
402         assertAllRoutesNotHaveInterface("wlan0", lp2);
403         assertEquals(3, lp.compareAllRoutes(lp2).added.size());
404         assertEquals(3, lp.compareAllRoutes(lp2).removed.size());
405 
406         // Check remove works
407         lp.removeRoute(new RouteInfo(prefix, address, null));
408         assertEquals(3, lp.getRoutes().size());
409         lp.removeRoute(new RouteInfo(prefix, address, "wlan0"));
410         assertEquals(2, lp.getRoutes().size());
411         assertAllRoutesHaveInterface("wlan0", lp);
412         assertAllRoutesNotHaveInterface("p2p0", lp);
413     }
414 
415     @Test
testStackedInterfaces()416     public void testStackedInterfaces() {
417         LinkProperties rmnet0 = new LinkProperties();
418         rmnet0.setInterfaceName("rmnet0");
419         rmnet0.addLinkAddress(LINKADDRV6);
420 
421         LinkProperties clat4 = new LinkProperties();
422         clat4.setInterfaceName("clat4");
423         clat4.addLinkAddress(LINKADDRV4);
424 
425         assertEquals(0, rmnet0.getStackedLinks().size());
426         assertEquals(1, rmnet0.getAddresses().size());
427         assertEquals(1, rmnet0.getLinkAddresses().size());
428         assertEquals(1, rmnet0.getAllAddresses().size());
429         assertEquals(1, rmnet0.getAllLinkAddresses().size());
430 
431         rmnet0.addStackedLink(clat4);
432         assertEquals(1, rmnet0.getStackedLinks().size());
433         assertEquals(1, rmnet0.getAddresses().size());
434         assertEquals(1, rmnet0.getLinkAddresses().size());
435         assertEquals(2, rmnet0.getAllAddresses().size());
436         assertEquals(2, rmnet0.getAllLinkAddresses().size());
437 
438         rmnet0.addStackedLink(clat4);
439         assertEquals(1, rmnet0.getStackedLinks().size());
440         assertEquals(1, rmnet0.getAddresses().size());
441         assertEquals(1, rmnet0.getLinkAddresses().size());
442         assertEquals(2, rmnet0.getAllAddresses().size());
443         assertEquals(2, rmnet0.getAllLinkAddresses().size());
444 
445         assertEquals(0, clat4.getStackedLinks().size());
446 
447         // Modify an item in the returned collection to see what happens.
448         for (LinkProperties link : rmnet0.getStackedLinks()) {
449             if (link.getInterfaceName().equals("clat4")) {
450                link.setInterfaceName("newname");
451             }
452         }
453         for (LinkProperties link : rmnet0.getStackedLinks()) {
454             assertFalse("newname".equals(link.getInterfaceName()));
455         }
456 
457         assertTrue(rmnet0.removeStackedLink("clat4"));
458         assertEquals(0, rmnet0.getStackedLinks().size());
459         assertEquals(1, rmnet0.getAddresses().size());
460         assertEquals(1, rmnet0.getLinkAddresses().size());
461         assertEquals(1, rmnet0.getAllAddresses().size());
462         assertEquals(1, rmnet0.getAllLinkAddresses().size());
463 
464         assertFalse(rmnet0.removeStackedLink("clat4"));
465     }
466 
getFirstLinkAddress(LinkProperties lp)467     private LinkAddress getFirstLinkAddress(LinkProperties lp) {
468         return lp.getLinkAddresses().iterator().next();
469     }
470 
471     @Test
testAddressMethods()472     public void testAddressMethods() {
473         LinkProperties lp = new LinkProperties();
474 
475         // No addresses.
476         assertFalse(lp.hasIpv4Address());
477         assertFalse(lp.hasGlobalIpv6Address());
478 
479         // Addresses on stacked links don't count.
480         LinkProperties stacked = new LinkProperties();
481         stacked.setInterfaceName("stacked");
482         lp.addStackedLink(stacked);
483         stacked.addLinkAddress(LINKADDRV4);
484         stacked.addLinkAddress(LINKADDRV6);
485         assertTrue(stacked.hasIpv4Address());
486         assertTrue(stacked.hasGlobalIpv6Address());
487         assertFalse(lp.hasIpv4Address());
488         assertFalse(lp.hasGlobalIpv6Address());
489         lp.removeStackedLink("stacked");
490         assertFalse(lp.hasIpv4Address());
491         assertFalse(lp.hasGlobalIpv6Address());
492 
493         // Addresses on the base link.
494         // Check the return values of hasIpvXAddress and ensure the add/remove methods return true
495         // iff something changes.
496         assertEquals(0, lp.getLinkAddresses().size());
497         assertTrue(lp.addLinkAddress(LINKADDRV6));
498         assertEquals(1, lp.getLinkAddresses().size());
499         assertFalse(lp.hasIpv4Address());
500         assertTrue(lp.hasGlobalIpv6Address());
501 
502         assertTrue(lp.removeLinkAddress(LINKADDRV6));
503         assertEquals(0, lp.getLinkAddresses().size());
504 
505         assertTrue(lp.addLinkAddress(LINKADDRV6LINKLOCAL));
506         assertEquals(1, lp.getLinkAddresses().size());
507         assertFalse(lp.hasGlobalIpv6Address());
508 
509         assertTrue(lp.addLinkAddress(LINKADDRV4));
510         assertEquals(2, lp.getLinkAddresses().size());
511         assertTrue(lp.hasIpv4Address());
512         assertFalse(lp.hasGlobalIpv6Address());
513 
514         assertTrue(lp.addLinkAddress(LINKADDRV6));
515         assertEquals(3, lp.getLinkAddresses().size());
516         assertTrue(lp.hasIpv4Address());
517         assertTrue(lp.hasGlobalIpv6Address());
518 
519         assertTrue(lp.removeLinkAddress(LINKADDRV6LINKLOCAL));
520         assertEquals(2, lp.getLinkAddresses().size());
521         assertTrue(lp.hasIpv4Address());
522         assertTrue(lp.hasGlobalIpv6Address());
523 
524         // Adding an address twice has no effect.
525         // Removing an address that's not present has no effect.
526         assertFalse(lp.addLinkAddress(LINKADDRV4));
527         assertEquals(2, lp.getLinkAddresses().size());
528         assertTrue(lp.hasIpv4Address());
529         assertTrue(lp.removeLinkAddress(LINKADDRV4));
530         assertEquals(1, lp.getLinkAddresses().size());
531         assertFalse(lp.hasIpv4Address());
532         assertFalse(lp.removeLinkAddress(LINKADDRV4));
533         assertEquals(1, lp.getLinkAddresses().size());
534 
535         // Adding an address that's already present but with different properties causes the
536         // existing address to be updated and returns true.
537         // Start with only LINKADDRV6.
538         assertEquals(1, lp.getLinkAddresses().size());
539         assertEquals(LINKADDRV6, getFirstLinkAddress(lp));
540 
541         // Create a LinkAddress object for the same address, but with different flags.
542         LinkAddress deprecated = new LinkAddress(ADDRV6, 128,
543                 OsConstants.IFA_F_DEPRECATED, OsConstants.RT_SCOPE_UNIVERSE);
544         assertTrue(deprecated.isSameAddressAs(LINKADDRV6));
545         assertFalse(deprecated.equals(LINKADDRV6));
546 
547         // Check that adding it updates the existing address instead of adding a new one.
548         assertTrue(lp.addLinkAddress(deprecated));
549         assertEquals(1, lp.getLinkAddresses().size());
550         assertEquals(deprecated, getFirstLinkAddress(lp));
551         assertFalse(LINKADDRV6.equals(getFirstLinkAddress(lp)));
552 
553         // Removing LINKADDRV6 removes deprecated, because removing addresses ignores properties.
554         assertTrue(lp.removeLinkAddress(LINKADDRV6));
555         assertEquals(0, lp.getLinkAddresses().size());
556     }
557 
558     @Test
testLinkAddresses()559     public void testLinkAddresses() {
560         final LinkProperties lp = new LinkProperties();
561         lp.addLinkAddress(LINKADDRV4);
562         lp.addLinkAddress(LINKADDRV6);
563 
564         final LinkProperties lp2 = new LinkProperties();
565         lp2.addLinkAddress(LINKADDRV6);
566 
567         final LinkProperties lp3 = new LinkProperties();
568         final List<LinkAddress> linkAddresses = Arrays.asList(LINKADDRV4);
569         lp3.setLinkAddresses(linkAddresses);
570 
571         assertFalse(lp.equals(lp2));
572         assertFalse(lp2.equals(lp3));
573 
574         lp.removeLinkAddress(LINKADDRV4);
575         assertTrue(lp.equals(lp2));
576 
577         lp2.setLinkAddresses(lp3.getLinkAddresses());
578         assertTrue(lp2.equals(lp3));
579     }
580 
581     @Test
testNat64Prefix()582     public void testNat64Prefix() throws Exception {
583         LinkProperties lp = new LinkProperties();
584         lp.addLinkAddress(LINKADDRV4);
585         lp.addLinkAddress(LINKADDRV6);
586 
587         assertNull(lp.getNat64Prefix());
588 
589         IpPrefix p = new IpPrefix("64:ff9b::/96");
590         lp.setNat64Prefix(p);
591         assertEquals(p, lp.getNat64Prefix());
592 
593         p = new IpPrefix("2001:db8:a:b:1:2:3::/96");
594         lp.setNat64Prefix(p);
595         assertEquals(p, lp.getNat64Prefix());
596 
597         p = new IpPrefix("2001:db8:a:b:1:2::/80");
598         try {
599             lp.setNat64Prefix(p);
600         } catch (IllegalArgumentException expected) {
601         }
602 
603         p = new IpPrefix("64:ff9b::/64");
604         try {
605             lp.setNat64Prefix(p);
606         } catch (IllegalArgumentException expected) {
607         }
608 
609         assertEquals(new IpPrefix("2001:db8:a:b:1:2:3::/96"), lp.getNat64Prefix());
610 
611         lp.setNat64Prefix(null);
612         assertNull(lp.getNat64Prefix());
613     }
614 
615     @Test
testIsProvisioned()616     public void testIsProvisioned() {
617         LinkProperties lp4 = new LinkProperties();
618         assertFalse("v4only:empty", lp4.isProvisioned());
619         lp4.addLinkAddress(LINKADDRV4);
620         assertFalse("v4only:addr-only", lp4.isProvisioned());
621         lp4.addDnsServer(DNS1);
622         assertFalse("v4only:addr+dns", lp4.isProvisioned());
623         lp4.addRoute(new RouteInfo(GATEWAY1));
624         assertTrue("v4only:addr+dns+route", lp4.isProvisioned());
625         assertTrue("v4only:addr+dns+route", lp4.isIpv4Provisioned());
626         assertFalse("v4only:addr+dns+route", lp4.isIpv6Provisioned());
627 
628         LinkProperties lp6 = new LinkProperties();
629         assertFalse("v6only:empty", lp6.isProvisioned());
630         lp6.addLinkAddress(LINKADDRV6LINKLOCAL);
631         assertFalse("v6only:fe80-only", lp6.isProvisioned());
632         lp6.addDnsServer(DNS6);
633         assertFalse("v6only:fe80+dns", lp6.isProvisioned());
634         lp6.addRoute(new RouteInfo(GATEWAY61));
635         assertFalse("v6only:fe80+dns+route", lp6.isProvisioned());
636         lp6.addLinkAddress(LINKADDRV6);
637         assertTrue("v6only:fe80+global+dns+route", lp6.isIpv6Provisioned());
638         assertTrue("v6only:fe80+global+dns+route", lp6.isProvisioned());
639         lp6.removeLinkAddress(LINKADDRV6LINKLOCAL);
640         assertFalse("v6only:global+dns+route", lp6.isIpv4Provisioned());
641         assertTrue("v6only:global+dns+route", lp6.isIpv6Provisioned());
642         assertTrue("v6only:global+dns+route", lp6.isProvisioned());
643 
644         LinkProperties lp46 = new LinkProperties();
645         lp46.addLinkAddress(LINKADDRV4);
646         lp46.addLinkAddress(LINKADDRV6);
647         lp46.addDnsServer(DNS1);
648         lp46.addDnsServer(DNS6);
649         assertFalse("dualstack:missing-routes", lp46.isProvisioned());
650         lp46.addRoute(new RouteInfo(GATEWAY1));
651         assertTrue("dualstack:v4-provisioned", lp46.isIpv4Provisioned());
652         assertFalse("dualstack:v4-provisioned", lp46.isIpv6Provisioned());
653         assertTrue("dualstack:v4-provisioned", lp46.isProvisioned());
654         lp46.addRoute(new RouteInfo(GATEWAY61));
655         assertTrue("dualstack:both-provisioned", lp46.isIpv4Provisioned());
656         assertTrue("dualstack:both-provisioned", lp46.isIpv6Provisioned());
657         assertTrue("dualstack:both-provisioned", lp46.isProvisioned());
658 
659         // A link with an IPv6 address and default route, but IPv4 DNS server.
660         LinkProperties mixed = new LinkProperties();
661         mixed.addLinkAddress(LINKADDRV6);
662         mixed.addDnsServer(DNS1);
663         mixed.addRoute(new RouteInfo(GATEWAY61));
664         assertFalse("mixed:addr6+route6+dns4", mixed.isIpv4Provisioned());
665         assertFalse("mixed:addr6+route6+dns4", mixed.isIpv6Provisioned());
666         assertFalse("mixed:addr6+route6+dns4", mixed.isProvisioned());
667     }
668 
669     @Test
testCompareProvisioning()670     public void testCompareProvisioning() {
671         LinkProperties v4lp = new LinkProperties();
672         v4lp.addLinkAddress(LINKADDRV4);
673         v4lp.addRoute(new RouteInfo(GATEWAY1));
674         v4lp.addDnsServer(DNS1);
675         assertTrue(v4lp.isProvisioned());
676 
677         LinkProperties v4r = new LinkProperties(v4lp);
678         v4r.removeDnsServer(DNS1);
679         assertFalse(v4r.isProvisioned());
680 
681         assertEquals(ProvisioningChange.STILL_NOT_PROVISIONED,
682                 LinkProperties.compareProvisioning(v4r, v4r));
683         assertEquals(ProvisioningChange.LOST_PROVISIONING,
684                 LinkProperties.compareProvisioning(v4lp, v4r));
685         assertEquals(ProvisioningChange.GAINED_PROVISIONING,
686                 LinkProperties.compareProvisioning(v4r, v4lp));
687         assertEquals(ProvisioningChange.STILL_PROVISIONED,
688                 LinkProperties.compareProvisioning(v4lp, v4lp));
689 
690         // Check that losing IPv4 provisioning on a dualstack network is
691         // seen as a total loss of provisioning.
692         LinkProperties v6lp = new LinkProperties();
693         v6lp.addLinkAddress(LINKADDRV6);
694         v6lp.addRoute(new RouteInfo(GATEWAY61));
695         v6lp.addDnsServer(DNS6);
696         assertFalse(v6lp.isIpv4Provisioned());
697         assertTrue(v6lp.isIpv6Provisioned());
698         assertTrue(v6lp.isProvisioned());
699 
700         LinkProperties v46lp = new LinkProperties(v6lp);
701         v46lp.addLinkAddress(LINKADDRV4);
702         v46lp.addRoute(new RouteInfo(GATEWAY1));
703         v46lp.addDnsServer(DNS1);
704         assertTrue(v46lp.isIpv4Provisioned());
705         assertTrue(v46lp.isIpv6Provisioned());
706         assertTrue(v46lp.isProvisioned());
707 
708         assertEquals(ProvisioningChange.STILL_PROVISIONED,
709                 LinkProperties.compareProvisioning(v4lp, v46lp));
710         assertEquals(ProvisioningChange.STILL_PROVISIONED,
711                 LinkProperties.compareProvisioning(v6lp, v46lp));
712         assertEquals(ProvisioningChange.LOST_PROVISIONING,
713                 LinkProperties.compareProvisioning(v46lp, v6lp));
714         assertEquals(ProvisioningChange.LOST_PROVISIONING,
715                 LinkProperties.compareProvisioning(v46lp, v4lp));
716 
717         // Check that losing and gaining a secondary router does not change
718         // the provisioning status.
719         LinkProperties v6lp2 = new LinkProperties(v6lp);
720         v6lp2.addRoute(new RouteInfo(GATEWAY62));
721         assertTrue(v6lp2.isProvisioned());
722 
723         assertEquals(ProvisioningChange.STILL_PROVISIONED,
724                 LinkProperties.compareProvisioning(v6lp2, v6lp));
725         assertEquals(ProvisioningChange.STILL_PROVISIONED,
726                 LinkProperties.compareProvisioning(v6lp, v6lp2));
727     }
728 
729     @Test
testIsReachable()730     public void testIsReachable() {
731         final LinkProperties v4lp = new LinkProperties();
732         assertFalse(v4lp.isReachable(DNS1));
733         assertFalse(v4lp.isReachable(DNS2));
734 
735         // Add an on-link route, making the on-link DNS server reachable,
736         // but there is still no IPv4 address.
737         assertTrue(v4lp.addRoute(new RouteInfo(
738                 new IpPrefix(NetworkUtils.numericToInetAddress("75.208.0.0"), 16))));
739         assertFalse(v4lp.isReachable(DNS1));
740         assertFalse(v4lp.isReachable(DNS2));
741 
742         // Adding an IPv4 address (right now, any IPv4 address) means we use
743         // the routes to compute likely reachability.
744         assertTrue(v4lp.addLinkAddress(new LinkAddress(ADDRV4, 16)));
745         assertTrue(v4lp.isReachable(DNS1));
746         assertFalse(v4lp.isReachable(DNS2));
747 
748         // Adding a default route makes the off-link DNS server reachable.
749         assertTrue(v4lp.addRoute(new RouteInfo(GATEWAY1)));
750         assertTrue(v4lp.isReachable(DNS1));
751         assertTrue(v4lp.isReachable(DNS2));
752 
753         final LinkProperties v6lp = new LinkProperties();
754         final InetAddress kLinkLocalDns = Address("fe80::6:1");
755         final InetAddress kLinkLocalDnsWithScope = Address("fe80::6:2%43");
756         final InetAddress kOnLinkDns = Address("2001:db8:85a3::53");
757         assertFalse(v6lp.isReachable(kLinkLocalDns));
758         assertFalse(v6lp.isReachable(kLinkLocalDnsWithScope));
759         assertFalse(v6lp.isReachable(kOnLinkDns));
760         assertFalse(v6lp.isReachable(DNS6));
761 
762         // Add a link-local route, making the link-local DNS servers reachable. Because
763         // we assume the presence of an IPv6 link-local address, link-local DNS servers
764         // are considered reachable, but only those with a non-zero scope identifier.
765         assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(Address("fe80::"), 64))));
766         assertFalse(v6lp.isReachable(kLinkLocalDns));
767         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
768         assertFalse(v6lp.isReachable(kOnLinkDns));
769         assertFalse(v6lp.isReachable(DNS6));
770 
771         // Add a link-local address--nothing changes.
772         assertTrue(v6lp.addLinkAddress(LINKADDRV6LINKLOCAL));
773         assertFalse(v6lp.isReachable(kLinkLocalDns));
774         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
775         assertFalse(v6lp.isReachable(kOnLinkDns));
776         assertFalse(v6lp.isReachable(DNS6));
777 
778         // Add a global route on link, but no global address yet. DNS servers reachable
779         // via a route that doesn't require a gateway: give them the benefit of the
780         // doubt and hope the link-local source address suffices for communication.
781         assertTrue(v6lp.addRoute(new RouteInfo(new IpPrefix(Address("2001:db8:85a3::"), 64))));
782         assertFalse(v6lp.isReachable(kLinkLocalDns));
783         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
784         assertTrue(v6lp.isReachable(kOnLinkDns));
785         assertFalse(v6lp.isReachable(DNS6));
786 
787         // Add a global address; the on-link global address DNS server is (still)
788         // presumed reachable.
789         assertTrue(v6lp.addLinkAddress(new LinkAddress(ADDRV6, 64)));
790         assertFalse(v6lp.isReachable(kLinkLocalDns));
791         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
792         assertTrue(v6lp.isReachable(kOnLinkDns));
793         assertFalse(v6lp.isReachable(DNS6));
794 
795         // Adding a default route makes the off-link DNS server reachable.
796         assertTrue(v6lp.addRoute(new RouteInfo(GATEWAY62)));
797         assertFalse(v6lp.isReachable(kLinkLocalDns));
798         assertTrue(v6lp.isReachable(kLinkLocalDnsWithScope));
799         assertTrue(v6lp.isReachable(kOnLinkDns));
800         assertTrue(v6lp.isReachable(DNS6));
801 
802         // Check isReachable on stacked links. This requires that the source IP address be assigned
803         // on the interface returned by the route lookup.
804         LinkProperties stacked = new LinkProperties();
805 
806         // Can't add a stacked link without an interface name.
807         stacked.setInterfaceName("v4-test0");
808         v6lp.addStackedLink(stacked);
809 
810         InetAddress stackedAddress = Address("192.0.0.4");
811         LinkAddress stackedLinkAddress = new LinkAddress(stackedAddress, 32);
812         assertFalse(v6lp.isReachable(stackedAddress));
813         stacked.addLinkAddress(stackedLinkAddress);
814         assertFalse(v6lp.isReachable(stackedAddress));
815         stacked.addRoute(new RouteInfo(stackedLinkAddress));
816         assertTrue(stacked.isReachable(stackedAddress));
817         assertTrue(v6lp.isReachable(stackedAddress));
818 
819         assertFalse(v6lp.isReachable(DNS1));
820         stacked.addRoute(new RouteInfo((IpPrefix) null, stackedAddress));
821         assertTrue(v6lp.isReachable(DNS1));
822     }
823 
824     @Test
testLinkPropertiesEnsureDirectlyConnectedRoutes()825     public void testLinkPropertiesEnsureDirectlyConnectedRoutes() {
826         // IPv4 case: no route added initially
827         LinkProperties rmnet0 = new LinkProperties();
828         rmnet0.setInterfaceName("rmnet0");
829         rmnet0.addLinkAddress(new LinkAddress("10.0.0.2/8"));
830         RouteInfo directRoute0 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
831                 rmnet0.getInterfaceName());
832 
833         // Since no routes is added explicitly, getAllRoutes() should return empty.
834         assertTrue(rmnet0.getAllRoutes().isEmpty());
835         rmnet0.ensureDirectlyConnectedRoutes();
836         // ensureDirectlyConnectedRoutes() should have added the missing local route.
837         assertEqualRoutes(Collections.singletonList(directRoute0), rmnet0.getAllRoutes());
838 
839         // IPv4 case: both direct and default routes added initially
840         LinkProperties rmnet1 = new LinkProperties();
841         rmnet1.setInterfaceName("rmnet1");
842         rmnet1.addLinkAddress(new LinkAddress("10.0.0.3/8"));
843         RouteInfo defaultRoute1 = new RouteInfo((IpPrefix) null, Address("10.0.0.1"),
844                 rmnet1.getInterfaceName());
845         RouteInfo directRoute1 = new RouteInfo(new IpPrefix("10.0.0.0/8"), null,
846                 rmnet1.getInterfaceName());
847         rmnet1.addRoute(defaultRoute1);
848         rmnet1.addRoute(directRoute1);
849 
850         // Check added routes
851         assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
852         // ensureDirectlyConnectedRoutes() shouldn't change the routes since direct connected
853         // route is already part of the configuration.
854         rmnet1.ensureDirectlyConnectedRoutes();
855         assertEqualRoutes(Arrays.asList(defaultRoute1, directRoute1), rmnet1.getAllRoutes());
856 
857         // IPv6 case: only default routes added initially
858         LinkProperties rmnet2 = new LinkProperties();
859         rmnet2.setInterfaceName("rmnet2");
860         rmnet2.addLinkAddress(new LinkAddress("fe80::cafe/64"));
861         rmnet2.addLinkAddress(new LinkAddress("2001:db8::2/64"));
862         RouteInfo defaultRoute2 = new RouteInfo((IpPrefix) null, Address("2001:db8::1"),
863                 rmnet2.getInterfaceName());
864         RouteInfo directRoute2 = new RouteInfo(new IpPrefix("2001:db8::/64"), null,
865                 rmnet2.getInterfaceName());
866         RouteInfo linkLocalRoute2 = new RouteInfo(new IpPrefix("fe80::/64"), null,
867                 rmnet2.getInterfaceName());
868         rmnet2.addRoute(defaultRoute2);
869 
870         assertEqualRoutes(Arrays.asList(defaultRoute2), rmnet2.getAllRoutes());
871         rmnet2.ensureDirectlyConnectedRoutes();
872         assertEqualRoutes(Arrays.asList(defaultRoute2, directRoute2, linkLocalRoute2),
873                 rmnet2.getAllRoutes());
874 
875         // Corner case: no interface name
876         LinkProperties rmnet3 = new LinkProperties();
877         rmnet3.addLinkAddress(new LinkAddress("192.168.0.2/24"));
878         RouteInfo directRoute3 = new RouteInfo(new IpPrefix("192.168.0.0/24"), null,
879                 rmnet3.getInterfaceName());
880 
881         assertTrue(rmnet3.getAllRoutes().isEmpty());
882         rmnet3.ensureDirectlyConnectedRoutes();
883         assertEqualRoutes(Collections.singletonList(directRoute3), rmnet3.getAllRoutes());
884 
885     }
886 
887     @Test
testCompareResult()888     public void testCompareResult() {
889         // Either adding or removing items
890         compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(1),
891                 Arrays.asList(2, 3, 4), new ArrayList<>());
892         compareResult(Arrays.asList(1, 2), Arrays.asList(3, 2, 1, 4),
893                 new ArrayList<>(), Arrays.asList(3, 4));
894 
895 
896         // adding and removing items at the same time
897         compareResult(Arrays.asList(1, 2, 3, 4), Arrays.asList(2, 3, 4, 5),
898                 Arrays.asList(1), Arrays.asList(5));
899         compareResult(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6),
900                 Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));
901 
902         // null cases
903         compareResult(Arrays.asList(1, 2, 3), null, Arrays.asList(1, 2, 3), new ArrayList<>());
904         compareResult(null, Arrays.asList(3, 2, 1), new ArrayList<>(), Arrays.asList(1, 2, 3));
905         compareResult(null, null, new ArrayList<>(), new ArrayList<>());
906     }
907 
assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual)908     private void assertEqualRoutes(Collection<RouteInfo> expected, Collection<RouteInfo> actual) {
909         Set<RouteInfo> expectedSet = new ArraySet<>(expected);
910         Set<RouteInfo> actualSet = new ArraySet<>(actual);
911         // Duplicated entries in actual routes are considered failures
912         assertEquals(actual.size(), actualSet.size());
913 
914         assertEquals(expectedSet, actualSet);
915     }
916 
compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved, List<T> expectAdded)917     private <T> void compareResult(List<T> oldItems, List<T> newItems, List<T> expectRemoved,
918             List<T> expectAdded) {
919         CompareResult<T> result = new CompareResult<>(oldItems, newItems);
920         assertEquals(new ArraySet<>(expectAdded), new ArraySet<>(result.added));
921         assertEquals(new ArraySet<>(expectRemoved), (new ArraySet<>(result.removed)));
922     }
923 
924     @Test
testLinkPropertiesParcelable()925     public void testLinkPropertiesParcelable() throws Exception {
926         LinkProperties source = new LinkProperties();
927         source.setInterfaceName(NAME);
928         // set 2 link addresses
929         source.addLinkAddress(LINKADDRV4);
930         source.addLinkAddress(LINKADDRV6);
931         // set 2 dnses
932         source.addDnsServer(DNS1);
933         source.addDnsServer(DNS2);
934         // set 2 gateways
935         source.addRoute(new RouteInfo(GATEWAY1));
936         source.addRoute(new RouteInfo(GATEWAY2));
937         // set 2 validated private dnses
938         source.addValidatedPrivateDnsServer(DNS6);
939         source.addValidatedPrivateDnsServer(GATEWAY61);
940 
941         source.setMtu(MTU);
942 
943         source.setNat64Prefix(new IpPrefix("2001:db8:1:2:64:64::/96"));
944 
945         TestUtils.assertParcelingIsLossless(source);
946     }
947 
948     @Test
testParcelUninitialized()949     public void testParcelUninitialized() throws Exception {
950         LinkProperties empty = new LinkProperties();
951         TestUtils.assertParcelingIsLossless(empty);
952     }
953 
954     @Test
testConstructor()955     public void testConstructor() {
956         LinkProperties lp = new LinkProperties();
957         checkEmpty(lp);
958         assertLinkPropertiesEqual(lp, new LinkProperties(lp));
959         assertLinkPropertiesEqual(lp, new LinkProperties());
960 
961         lp = makeTestObject();
962         assertLinkPropertiesEqual(lp, new LinkProperties(lp));
963     }
964 
965     @Test
testDnsServers()966     public void testDnsServers() {
967         final LinkProperties lp = new LinkProperties();
968         final List<InetAddress> dnsServers = Arrays.asList(DNS1, DNS2);
969         lp.setDnsServers(dnsServers);
970         assertEquals(2, lp.getDnsServers().size());
971         assertEquals(DNS1, lp.getDnsServers().get(0));
972         assertEquals(DNS2, lp.getDnsServers().get(1));
973 
974         lp.removeDnsServer(DNS1);
975         assertEquals(1, lp.getDnsServers().size());
976         assertEquals(DNS2, lp.getDnsServers().get(0));
977 
978         lp.addDnsServer(DNS6);
979         assertEquals(2, lp.getDnsServers().size());
980         assertEquals(DNS2, lp.getDnsServers().get(0));
981         assertEquals(DNS6, lp.getDnsServers().get(1));
982     }
983 
984     @Test
testValidatedPrivateDnsServers()985     public void testValidatedPrivateDnsServers() {
986         final LinkProperties lp = new LinkProperties();
987         final List<InetAddress> privDnsServers = Arrays.asList(PRIVDNS1, PRIVDNS2);
988         lp.setValidatedPrivateDnsServers(privDnsServers);
989         assertEquals(2, lp.getValidatedPrivateDnsServers().size());
990         assertEquals(PRIVDNS1, lp.getValidatedPrivateDnsServers().get(0));
991         assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(1));
992 
993         lp.removeValidatedPrivateDnsServer(PRIVDNS1);
994         assertEquals(1, lp.getValidatedPrivateDnsServers().size());
995         assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(0));
996 
997         lp.addValidatedPrivateDnsServer(PRIVDNS6);
998         assertEquals(2, lp.getValidatedPrivateDnsServers().size());
999         assertEquals(PRIVDNS2, lp.getValidatedPrivateDnsServers().get(0));
1000         assertEquals(PRIVDNS6, lp.getValidatedPrivateDnsServers().get(1));
1001     }
1002 
1003     @Test
testPcscfServers()1004     public void testPcscfServers() {
1005         final LinkProperties lp = new LinkProperties();
1006         final List<InetAddress> pcscfServers = Arrays.asList(PCSCFV4);
1007         lp.setPcscfServers(pcscfServers);
1008         assertEquals(1, lp.getPcscfServers().size());
1009         assertEquals(PCSCFV4, lp.getPcscfServers().get(0));
1010 
1011         lp.removePcscfServer(PCSCFV4);
1012         assertEquals(0, lp.getPcscfServers().size());
1013 
1014         lp.addPcscfServer(PCSCFV6);
1015         assertEquals(1, lp.getPcscfServers().size());
1016         assertEquals(PCSCFV6, lp.getPcscfServers().get(0));
1017     }
1018 
1019     @Test
testTcpBufferSizes()1020     public void testTcpBufferSizes() {
1021         final LinkProperties lp = makeTestObject();
1022         assertEquals(TCP_BUFFER_SIZES, lp.getTcpBufferSizes());
1023 
1024         lp.setTcpBufferSizes(null);
1025         assertNull(lp.getTcpBufferSizes());
1026     }
1027 
1028     @Test
testHasIpv6DefaultRoute()1029     public void testHasIpv6DefaultRoute() {
1030         final LinkProperties lp = makeTestObject();
1031         assertFalse(lp.hasIPv6DefaultRoute());
1032 
1033         lp.addRoute(new RouteInfo(GATEWAY61));
1034         assertTrue(lp.hasIPv6DefaultRoute());
1035     }
1036 
1037     @Test
testHttpProxy()1038     public void testHttpProxy() {
1039         final LinkProperties lp = makeTestObject();
1040         assertTrue(lp.getHttpProxy().equals(ProxyInfo.buildDirectProxy("test", 8888)));
1041     }
1042 
1043     @Test
testPrivateDnsServerName()1044     public void testPrivateDnsServerName() {
1045         final LinkProperties lp = makeTestObject();
1046         assertEquals(PRIV_DNS_SERVER_NAME, lp.getPrivateDnsServerName());
1047 
1048         lp.setPrivateDnsServerName(null);
1049         assertNull(lp.getPrivateDnsServerName());
1050     }
1051 
1052     @Test
testUsePrivateDns()1053     public void testUsePrivateDns() {
1054         final LinkProperties lp = makeTestObject();
1055         assertTrue(lp.isPrivateDnsActive());
1056 
1057         lp.clear();
1058         assertFalse(lp.isPrivateDnsActive());
1059     }
1060 }
1061