1 /* 2 * Copyright (C) 2018 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.dhcp; 18 19 import static android.net.InetAddresses.parseNumericAddress; 20 import static android.net.dhcp.DhcpServingParams.MTU_UNSET; 21 22 import static com.android.net.module.util.Inet4AddressUtils.inet4AddressToIntHTH; 23 24 import static junit.framework.Assert.assertEquals; 25 import static junit.framework.Assert.assertFalse; 26 import static junit.framework.Assert.assertTrue; 27 28 import android.annotation.NonNull; 29 import android.annotation.Nullable; 30 import android.net.LinkAddress; 31 import android.net.dhcp.DhcpServingParams.InvalidParameterException; 32 33 import androidx.test.filters.SmallTest; 34 import androidx.test.runner.AndroidJUnit4; 35 36 import com.android.net.module.util.Inet4AddressUtils; 37 import com.android.testutils.MiscAsserts; 38 39 import org.junit.Before; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 import java.net.Inet4Address; 44 import java.util.Arrays; 45 import java.util.Collection; 46 import java.util.HashSet; 47 import java.util.Set; 48 49 @RunWith(AndroidJUnit4.class) 50 @SmallTest 51 public class DhcpServingParamsTest { 52 @NonNull 53 private DhcpServingParams.Builder mBuilder; 54 55 private static final Set<Inet4Address> TEST_DEFAULT_ROUTERS = new HashSet<>( 56 Arrays.asList(parseAddr("192.168.0.123"), parseAddr("192.168.0.124"))); 57 private static final long TEST_LEASE_TIME_SECS = 3600L; 58 private static final Set<Inet4Address> TEST_DNS_SERVERS = new HashSet<>( 59 Arrays.asList(parseAddr("192.168.0.126"), parseAddr("192.168.0.127"))); 60 private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2"); 61 private static final Inet4Address TEST_CLIENT_ADDR = parseAddr("192.168.0.42"); 62 private static final LinkAddress TEST_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20); 63 private static final int TEST_MTU = 1500; 64 private static final Set<Inet4Address> TEST_EXCLUDED_ADDRS = new HashSet<>( 65 Arrays.asList(parseAddr("192.168.0.200"), parseAddr("192.168.0.201"))); 66 private static final boolean TEST_METERED = true; 67 private static final boolean TEST_CHANGE_PREFIX_ON_DECLINE = true; 68 69 @Before setUp()70 public void setUp() { 71 mBuilder = new DhcpServingParams.Builder() 72 .setDefaultRouters(TEST_DEFAULT_ROUTERS) 73 .setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS) 74 .setDnsServers(TEST_DNS_SERVERS) 75 .setServerAddr(TEST_LINKADDR) 76 .setLinkMtu(TEST_MTU) 77 .setExcludedAddrs(TEST_EXCLUDED_ADDRS) 78 .setMetered(TEST_METERED) 79 .setSingleClientAddr(TEST_CLIENT_ADDR) 80 .setChangePrefixOnDecline(TEST_CHANGE_PREFIX_ON_DECLINE); 81 } 82 83 @Test testBuild_Immutable()84 public void testBuild_Immutable() throws InvalidParameterException { 85 final Set<Inet4Address> routers = new HashSet<>(TEST_DEFAULT_ROUTERS); 86 final Set<Inet4Address> dnsServers = new HashSet<>(TEST_DNS_SERVERS); 87 final Set<Inet4Address> excludedAddrs = new HashSet<>(TEST_EXCLUDED_ADDRS); 88 89 final DhcpServingParams params = mBuilder 90 .setDefaultRouters(routers) 91 .setDnsServers(dnsServers) 92 .setExcludedAddrs(excludedAddrs) 93 .build(); 94 95 // Modifications to source objects should not affect builder or final parameters 96 final Inet4Address addedAddr = parseAddr("192.168.0.223"); 97 routers.add(addedAddr); 98 dnsServers.add(addedAddr); 99 excludedAddrs.add(addedAddr); 100 101 assertEquals(TEST_DEFAULT_ROUTERS, params.defaultRouters); 102 assertEquals(TEST_LEASE_TIME_SECS, params.dhcpLeaseTimeSecs); 103 assertEquals(TEST_DNS_SERVERS, params.dnsServers); 104 assertEquals(TEST_LINKADDR, params.serverAddr); 105 assertEquals(TEST_MTU, params.linkMtu); 106 assertEquals(TEST_METERED, params.metered); 107 assertEquals(TEST_CHANGE_PREFIX_ON_DECLINE, params.changePrefixOnDecline); 108 109 assertContains(params.excludedAddrs, TEST_EXCLUDED_ADDRS); 110 assertContains(params.excludedAddrs, TEST_DEFAULT_ROUTERS); 111 assertContains(params.excludedAddrs, TEST_DNS_SERVERS); 112 assertContains(params.excludedAddrs, TEST_SERVER_ADDR); 113 114 assertFalse("excludedAddrs should not contain " + addedAddr, 115 params.excludedAddrs.contains(addedAddr)); 116 } 117 118 @Test(expected = InvalidParameterException.class) testBuild_NegativeLeaseTime()119 public void testBuild_NegativeLeaseTime() throws InvalidParameterException { 120 mBuilder.setDhcpLeaseTimeSecs(-1).build(); 121 } 122 123 @Test(expected = InvalidParameterException.class) testBuild_LeaseTimeTooLarge()124 public void testBuild_LeaseTimeTooLarge() throws InvalidParameterException { 125 // Set lease time larger than max value for uint32 126 mBuilder.setDhcpLeaseTimeSecs(1L << 32).build(); 127 } 128 129 @Test testBuild_InfiniteLeaseTime()130 public void testBuild_InfiniteLeaseTime() throws InvalidParameterException { 131 final long infiniteLeaseTime = 0xffffffffL; 132 final DhcpServingParams params = mBuilder 133 .setDhcpLeaseTimeSecs(infiniteLeaseTime).build(); 134 assertEquals(infiniteLeaseTime, params.dhcpLeaseTimeSecs); 135 assertTrue(params.dhcpLeaseTimeSecs > 0L); 136 } 137 138 @Test testBuild_UnsetMtu()139 public void testBuild_UnsetMtu() throws InvalidParameterException { 140 final DhcpServingParams params = mBuilder.setLinkMtu(MTU_UNSET).build(); 141 assertEquals(MTU_UNSET, params.linkMtu); 142 } 143 144 @Test(expected = InvalidParameterException.class) testBuild_MtuTooSmall()145 public void testBuild_MtuTooSmall() throws InvalidParameterException { 146 mBuilder.setLinkMtu(20).build(); 147 } 148 149 @Test(expected = InvalidParameterException.class) testBuild_MtuTooLarge()150 public void testBuild_MtuTooLarge() throws InvalidParameterException { 151 mBuilder.setLinkMtu(65_536).build(); 152 } 153 154 @Test(expected = InvalidParameterException.class) testBuild_IPv6Addr()155 public void testBuild_IPv6Addr() throws InvalidParameterException { 156 mBuilder.setServerAddr(new LinkAddress(parseNumericAddress("fe80::1111"), 120)).build(); 157 } 158 159 @Test(expected = InvalidParameterException.class) testBuild_PrefixTooLarge()160 public void testBuild_PrefixTooLarge() throws InvalidParameterException { 161 mBuilder.setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 15)).build(); 162 } 163 164 @Test(expected = InvalidParameterException.class) testBuild_PrefixTooSmall()165 public void testBuild_PrefixTooSmall() throws InvalidParameterException { 166 mBuilder.setDefaultRouters(parseAddr("192.168.0.254")) 167 .setServerAddr(new LinkAddress(TEST_SERVER_ADDR, 31)) 168 .build(); 169 } 170 171 @Test(expected = InvalidParameterException.class) testBuild_RouterNotInPrefix()172 public void testBuild_RouterNotInPrefix() throws InvalidParameterException { 173 mBuilder.setDefaultRouters(parseAddr("192.168.254.254")).build(); 174 } 175 176 @Test testFromParcelableObject()177 public void testFromParcelableObject() throws InvalidParameterException { 178 final DhcpServingParams params = mBuilder.build(); 179 final DhcpServingParamsParcel parcel = new DhcpServingParamsParcel(); 180 parcel.defaultRouters = toIntArray(TEST_DEFAULT_ROUTERS); 181 parcel.dhcpLeaseTimeSecs = TEST_LEASE_TIME_SECS; 182 parcel.dnsServers = toIntArray(TEST_DNS_SERVERS); 183 parcel.serverAddr = inet4AddressToIntHTH(TEST_SERVER_ADDR); 184 parcel.serverAddrPrefixLength = TEST_LINKADDR.getPrefixLength(); 185 parcel.linkMtu = TEST_MTU; 186 parcel.excludedAddrs = toIntArray(TEST_EXCLUDED_ADDRS); 187 parcel.metered = TEST_METERED; 188 parcel.singleClientAddr = inet4AddressToIntHTH(TEST_CLIENT_ADDR); 189 parcel.changePrefixOnDecline = TEST_CHANGE_PREFIX_ON_DECLINE; 190 final DhcpServingParams parceled = DhcpServingParams.fromParcelableObject(parcel); 191 192 assertEquals(params.defaultRouters, parceled.defaultRouters); 193 assertEquals(params.dhcpLeaseTimeSecs, parceled.dhcpLeaseTimeSecs); 194 assertEquals(params.dnsServers, parceled.dnsServers); 195 assertEquals(params.serverAddr, parceled.serverAddr); 196 assertEquals(params.linkMtu, parceled.linkMtu); 197 assertEquals(params.excludedAddrs, parceled.excludedAddrs); 198 assertEquals(params.metered, parceled.metered); 199 assertEquals(params.singleClientAddr, parceled.singleClientAddr); 200 assertEquals(params.changePrefixOnDecline, parceled.changePrefixOnDecline); 201 202 MiscAsserts.assertFieldCountEquals(10, DhcpServingParamsParcel.class); 203 } 204 205 @Test(expected = InvalidParameterException.class) testFromParcelableObject_NullArgument()206 public void testFromParcelableObject_NullArgument() throws InvalidParameterException { 207 DhcpServingParams.fromParcelableObject(null); 208 } 209 toIntArray(Collection<Inet4Address> addrs)210 private static int[] toIntArray(Collection<Inet4Address> addrs) { 211 return addrs.stream().mapToInt(Inet4AddressUtils::inet4AddressToIntHTH).toArray(); 212 } 213 assertContains(@onNull Set<T> set, @NonNull Set<T> subset)214 private static <T> void assertContains(@NonNull Set<T> set, @NonNull Set<T> subset) { 215 for (final T elem : subset) { 216 assertContains(set, elem); 217 } 218 } 219 assertContains(@onNull Set<T> set, @Nullable T elem)220 private static <T> void assertContains(@NonNull Set<T> set, @Nullable T elem) { 221 assertTrue("Set does not contain " + elem, set.contains(elem)); 222 } 223 224 @NonNull parseAddr(@onNull String inet4Addr)225 private static Inet4Address parseAddr(@NonNull String inet4Addr) { 226 return (Inet4Address) parseNumericAddress(inet4Addr); 227 } 228 } 229