Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6209cf0 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN Committed by Gerrit Code Review
Browse files

Merge "Add parceling for DhcpServingParams"

parents 68325959 761198a0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -825,6 +825,7 @@ aidl_interface {
    local_include_dir: "core/java",
    srcs: [
        "core/java/android/net/INetworkStackConnector.aidl",
        "core/java/android/net/dhcp/DhcpServingParamsParcel.aidl",
    ],
    api_dir: "aidl/networkstack",
}
+30 −0
Original line number Diff line number Diff line
/**
 *
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.dhcp;

parcelable DhcpServingParamsParcel {
    int serverAddr;
    int serverAddrPrefixLength;
    int[] defaultRouters;
    int[] dnsServers;
    int[] excludedAddrs;
    long dhcpLeaseTimeSecs;
    int linkMtu;
    boolean metered;
}
+72 −36
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.net.dhcp;

import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
import static android.net.NetworkUtils.intToInet4AddressHTH;
import static android.net.dhcp.DhcpPacket.INFINITE_LEASE;
import static android.net.util.NetworkConstants.IPV4_MAX_MTU;
import static android.net.util.NetworkConstants.IPV4_MIN_MTU;
@@ -24,6 +25,7 @@ import static android.net.util.NetworkConstants.IPV4_MIN_MTU;
import static java.lang.Integer.toUnsignedLong;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.NetworkUtils;
@@ -103,6 +105,37 @@ public class DhcpServingParams {
        this.metered = metered;
    }

    /**
     * Create parameters from a stable AIDL-compatible parcel.
     */
    public static DhcpServingParams fromParcelableObject(@NonNull DhcpServingParamsParcel parcel)
            throws InvalidParameterException {
        final LinkAddress serverAddr = new LinkAddress(
                intToInet4AddressHTH(parcel.serverAddr),
                parcel.serverAddrPrefixLength);
        return new Builder()
                .setServerAddr(serverAddr)
                .setDefaultRouters(toInet4AddressSet(parcel.defaultRouters))
                .setDnsServers(toInet4AddressSet(parcel.dnsServers))
                .setExcludedAddrs(toInet4AddressSet(parcel.excludedAddrs))
                .setDhcpLeaseTimeSecs(parcel.dhcpLeaseTimeSecs)
                .setLinkMtu(parcel.linkMtu)
                .setMetered(parcel.metered)
                .build();
    }

    private static Set<Inet4Address> toInet4AddressSet(@Nullable int[] addrs) {
        if (addrs == null) {
            return new HashSet<>(0);
        }

        final HashSet<Inet4Address> res = new HashSet<>();
        for (int addr : addrs) {
            res.add(intToInet4AddressHTH(addr));
        }
        return res;
    }

    @NonNull
    public Inet4Address getServerInet4Addr() {
        return (Inet4Address) serverAddr.getAddress();
@@ -134,13 +167,13 @@ public class DhcpServingParams {
     * of the parameters.
     */
    public static class Builder {
        private LinkAddress serverAddr;
        private Set<Inet4Address> defaultRouters;
        private Set<Inet4Address> dnsServers;
        private Set<Inet4Address> excludedAddrs;
        private long dhcpLeaseTimeSecs;
        private int linkMtu = MTU_UNSET;
        private boolean metered;
        private LinkAddress mServerAddr;
        private Set<Inet4Address> mDefaultRouters;
        private Set<Inet4Address> mDnsServers;
        private Set<Inet4Address> mExcludedAddrs;
        private long mDhcpLeaseTimeSecs;
        private int mLinkMtu = MTU_UNSET;
        private boolean mMetered;

        /**
         * Set the server address and served prefix for the DHCP server.
@@ -148,7 +181,7 @@ public class DhcpServingParams {
         * <p>This parameter is required.
         */
        public Builder setServerAddr(@NonNull LinkAddress serverAddr) {
            this.serverAddr = serverAddr;
            this.mServerAddr = serverAddr;
            return this;
        }

@@ -159,7 +192,7 @@ public class DhcpServingParams {
         * always be set explicitly before building the {@link DhcpServingParams}.
         */
        public Builder setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
            this.defaultRouters = defaultRouters;
            this.mDefaultRouters = defaultRouters;
            return this;
        }

@@ -189,7 +222,7 @@ public class DhcpServingParams {
         * {@link DhcpServingParams}.
         */
        public Builder setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
            this.dnsServers = dnsServers;
            this.mDnsServers = dnsServers;
            return this;
        }

@@ -219,7 +252,7 @@ public class DhcpServingParams {
         * and do not need to be set here.
         */
        public Builder setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
            this.excludedAddrs = excludedAddrs;
            this.mExcludedAddrs = excludedAddrs;
            return this;
        }

@@ -239,7 +272,7 @@ public class DhcpServingParams {
         * <p>This parameter is required.
         */
        public Builder setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
            this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
            this.mDhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
            return this;
        }

@@ -250,7 +283,7 @@ public class DhcpServingParams {
         * is optional and defaults to {@link #MTU_UNSET}.
         */
        public Builder setLinkMtu(int linkMtu) {
            this.linkMtu = linkMtu;
            this.mLinkMtu = linkMtu;
            return this;
        }

@@ -260,7 +293,7 @@ public class DhcpServingParams {
         * <p>If not set, the default value is false.
         */
        public Builder setMetered(boolean metered) {
            this.metered = metered;
            this.mMetered = metered;
            return this;
        }

@@ -274,54 +307,57 @@ public class DhcpServingParams {
         */
        @NonNull
        public DhcpServingParams build() throws InvalidParameterException {
            if (serverAddr == null) {
            if (mServerAddr == null) {
                throw new InvalidParameterException("Missing serverAddr");
            }
            if (defaultRouters == null) {
            if (mDefaultRouters == null) {
                throw new InvalidParameterException("Missing defaultRouters");
            }
            if (dnsServers == null) {
            if (mDnsServers == null) {
                // Empty set is OK, but enforce explicitly setting it
                throw new InvalidParameterException("Missing dnsServers");
            }
            if (dhcpLeaseTimeSecs <= 0 || dhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
                throw new InvalidParameterException("Invalid lease time: " + dhcpLeaseTimeSecs);
            if (mDhcpLeaseTimeSecs <= 0 || mDhcpLeaseTimeSecs > toUnsignedLong(INFINITE_LEASE)) {
                throw new InvalidParameterException("Invalid lease time: " + mDhcpLeaseTimeSecs);
            }
            if (linkMtu != MTU_UNSET && (linkMtu < IPV4_MIN_MTU || linkMtu > IPV4_MAX_MTU)) {
                throw new InvalidParameterException("Invalid link MTU: " + linkMtu);
            if (mLinkMtu != MTU_UNSET && (mLinkMtu < IPV4_MIN_MTU || mLinkMtu > IPV4_MAX_MTU)) {
                throw new InvalidParameterException("Invalid link MTU: " + mLinkMtu);
            }
            if (!serverAddr.isIPv4()) {
            if (!mServerAddr.isIPv4()) {
                throw new InvalidParameterException("serverAddr must be IPv4");
            }
            if (serverAddr.getPrefixLength() < MIN_PREFIX_LENGTH
                    || serverAddr.getPrefixLength() > MAX_PREFIX_LENGTH) {
            if (mServerAddr.getPrefixLength() < MIN_PREFIX_LENGTH
                    || mServerAddr.getPrefixLength() > MAX_PREFIX_LENGTH) {
                throw new InvalidParameterException("Prefix length is not in supported range");
            }

            final IpPrefix prefix = makeIpPrefix(serverAddr);
            for (Inet4Address addr : defaultRouters) {
            final IpPrefix prefix = makeIpPrefix(mServerAddr);
            for (Inet4Address addr : mDefaultRouters) {
                if (!prefix.contains(addr)) {
                    throw new InvalidParameterException(String.format(
                            "Default router %s is not in server prefix %s", addr, serverAddr));
                            "Default router %s is not in server prefix %s", addr, mServerAddr));
                }
            }

            final Set<Inet4Address> excl = new HashSet<>();
            if (excludedAddrs != null) {
                excl.addAll(excludedAddrs);
            if (mExcludedAddrs != null) {
                excl.addAll(mExcludedAddrs);
            }
            excl.add((Inet4Address) serverAddr.getAddress());
            excl.addAll(defaultRouters);
            excl.addAll(dnsServers);
            excl.add((Inet4Address) mServerAddr.getAddress());
            excl.addAll(mDefaultRouters);
            excl.addAll(mDnsServers);

            return new DhcpServingParams(serverAddr,
                    Collections.unmodifiableSet(new HashSet<>(defaultRouters)),
                    Collections.unmodifiableSet(new HashSet<>(dnsServers)),
            return new DhcpServingParams(mServerAddr,
                    Collections.unmodifiableSet(new HashSet<>(mDefaultRouters)),
                    Collections.unmodifiableSet(new HashSet<>(mDnsServers)),
                    Collections.unmodifiableSet(excl),
                    dhcpLeaseTimeSecs, linkMtu, metered);
                    mDhcpLeaseTimeSecs, mLinkMtu, mMetered);
        }
    }

    /**
     * Utility method to create an IpPrefix with the address and prefix length of a LinkAddress.
     */
    @NonNull
    static IpPrefix makeIpPrefix(@NonNull LinkAddress addr) {
        return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
+172 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.dhcp;

import static android.net.NetworkUtils.inet4AddressToIntHTH;

import android.annotation.NonNull;
import android.net.LinkAddress;

import com.google.android.collect.Sets;

import java.net.Inet4Address;
import java.util.Collection;
import java.util.Set;

/**
 * Subclass of {@link DhcpServingParamsParcel} with additional utility methods for building.
 *
 * <p>This utility class does not check for validity of the parameters: invalid parameters are
 * reported by the receiving module when unparceling the parcel.
 *
 * @see DhcpServingParams
 * @hide
 */
public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
    public static final int MTU_UNSET = 0;

    /**
     * Set the server address and served prefix for the DHCP server.
     *
     * <p>This parameter is required.
     */
    public DhcpServingParamsParcelExt setServerAddr(@NonNull LinkAddress serverAddr) {
        this.serverAddr = inet4AddressToIntHTH((Inet4Address) serverAddr.getAddress());
        this.serverAddrPrefixLength = serverAddr.getPrefixLength();
        return this;
    }

    /**
     * Set the default routers to be advertised to DHCP clients.
     *
     * <p>Each router must be inside the served prefix. This may be an empty set, but it must
     * always be set explicitly.
     */
    public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Set<Inet4Address> defaultRouters) {
        this.defaultRouters = toIntArray(defaultRouters);
        return this;
    }

    /**
     * Set the default routers to be advertised to DHCP clients.
     *
     * <p>Each router must be inside the served prefix. This may be an empty list of routers,
     * but it must always be set explicitly.
     */
    public DhcpServingParamsParcelExt setDefaultRouters(@NonNull Inet4Address... defaultRouters) {
        return setDefaultRouters(Sets.newArraySet(defaultRouters));
    }

    /**
     * Convenience method to build the parameters with no default router.
     *
     * <p>Equivalent to calling {@link #setDefaultRouters(Inet4Address...)} with no address.
     */
    public DhcpServingParamsParcelExt setNoDefaultRouter() {
        return setDefaultRouters();
    }

    /**
     * Set the DNS servers to be advertised to DHCP clients.
     *
     * <p>This may be an empty set, but it must always be set explicitly.
     */
    public DhcpServingParamsParcelExt setDnsServers(@NonNull Set<Inet4Address> dnsServers) {
        this.dnsServers = toIntArray(dnsServers);
        return this;
    }

    /**
     * Set the DNS servers to be advertised to DHCP clients.
     *
     * <p>This may be an empty list of servers, but it must always be set explicitly.
     */
    public DhcpServingParamsParcelExt setDnsServers(@NonNull Inet4Address... dnsServers) {
        return setDnsServers(Sets.newArraySet(dnsServers));
    }

    /**
     * Convenience method to build the parameters with no DNS server.
     *
     * <p>Equivalent to calling {@link #setDnsServers(Inet4Address...)} with no address.
     */
    public DhcpServingParamsParcelExt setNoDnsServer() {
        return setDnsServers();
    }

    /**
     * Set excluded addresses that the DHCP server is not allowed to assign to clients.
     *
     * <p>This parameter is optional. DNS servers and default routers are always excluded
     * and do not need to be set here.
     */
    public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Set<Inet4Address> excludedAddrs) {
        this.excludedAddrs = toIntArray(excludedAddrs);
        return this;
    }

    /**
     * Set excluded addresses that the DHCP server is not allowed to assign to clients.
     *
     * <p>This parameter is optional. DNS servers and default routers are always excluded
     * and do not need to be set here.
     */
    public DhcpServingParamsParcelExt setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) {
        return setExcludedAddrs(Sets.newArraySet(excludedAddrs));
    }

    /**
     * Set the lease time for leases assigned by the DHCP server.
     *
     * <p>This parameter is required.
     */
    public DhcpServingParamsParcelExt setDhcpLeaseTimeSecs(long dhcpLeaseTimeSecs) {
        this.dhcpLeaseTimeSecs = dhcpLeaseTimeSecs;
        return this;
    }

    /**
     * Set the link MTU to be advertised to DHCP clients.
     *
     * <p>If set to {@link #MTU_UNSET}, no MTU will be advertised to clients. This parameter
     * is optional and defaults to {@link #MTU_UNSET}.
     */
    public DhcpServingParamsParcelExt setLinkMtu(int linkMtu) {
        this.linkMtu = linkMtu;
        return this;
    }

    /**
     * Set whether the DHCP server should send the ANDROID_METERED vendor-specific option.
     *
     * <p>If not set, the default value is false.
     */
    public DhcpServingParamsParcelExt setMetered(boolean metered) {
        this.metered = metered;
        return this;
    }

    private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
        int[] res = new int[addrs.size()];
        int i = 0;
        for (Inet4Address addr : addrs) {
            res[i] = inet4AddressToIntHTH(addr);
            i++;
        }
        return res;
    }
}
+113 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net.dhcp;

import static android.net.InetAddresses.parseNumericAddress;

import static com.google.android.collect.Sets.newHashSet;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import android.net.LinkAddress;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.net.Inet4Address;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class DhcpServingParamsParcelExtTest {
    private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123");
    private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b;
    private static final int TEST_PREFIX_LENGTH = 17;
    private static final int TEST_LEASE_TIME_SECS = 120;
    private static final int TEST_MTU = 1000;
    private static final Set<Inet4Address> TEST_ADDRESS_SET =
            newHashSet(inet4Addr("192.168.1.123"), inet4Addr("192.168.1.124"));
    private static final Set<Integer> TEST_ADDRESS_SET_PARCELED =
            newHashSet(0xc0a8017b, 0xc0a8017c);

    private DhcpServingParamsParcelExt mParcel;

    @Before
    public void setUp() {
        mParcel = new DhcpServingParamsParcelExt();
    }

    @Test
    public void testSetServerAddr() {
        mParcel.setServerAddr(new LinkAddress(TEST_ADDRESS, TEST_PREFIX_LENGTH));

        assertEquals(TEST_ADDRESS_PARCELED, mParcel.serverAddr);
        assertEquals(TEST_PREFIX_LENGTH, mParcel.serverAddrPrefixLength);
    }

    @Test
    public void testSetDefaultRouters() {
        mParcel.setDefaultRouters(TEST_ADDRESS_SET);
        assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.defaultRouters));
    }

    @Test
    public void testSetDnsServers() {
        mParcel.setDnsServers(TEST_ADDRESS_SET);
        assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.dnsServers));
    }

    @Test
    public void testSetExcludedAddrs() {
        mParcel.setExcludedAddrs(TEST_ADDRESS_SET);
        assertEquals(TEST_ADDRESS_SET_PARCELED, asSet(mParcel.excludedAddrs));
    }

    @Test
    public void testSetDhcpLeaseTimeSecs() {
        mParcel.setDhcpLeaseTimeSecs(TEST_LEASE_TIME_SECS);
        assertEquals(TEST_LEASE_TIME_SECS, mParcel.dhcpLeaseTimeSecs);
    }

    @Test
    public void testSetLinkMtu() {
        mParcel.setLinkMtu(TEST_MTU);
        assertEquals(TEST_MTU, mParcel.linkMtu);
    }

    @Test
    public void testSetMetered() {
        mParcel.setMetered(true);
        assertTrue(mParcel.metered);
        mParcel.setMetered(false);
        assertFalse(mParcel.metered);
    }

    private static Inet4Address inet4Addr(String addr) {
        return (Inet4Address) parseNumericAddress(addr);
    }

    private static Set<Integer> asSet(int[] ints) {
        return IntStream.of(ints).boxed().collect(Collectors.toSet());
    }
}
Loading