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

Commit 86d212b4 authored by Treehugger Robot's avatar Treehugger Robot Committed by Mark Chien
Browse files

Assign specific client address to dhcp server

Bug: 141256482
Test: manual
      atest TetheringTests

Merged-In: Ief76c98c843ba5420224cbf0f34464f366c891b7
Change-Id: Ief76c98c843ba5420224cbf0f34464f366c891b7
parent 7f091e01
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -571,9 +571,8 @@ public class TetheringManager {
            /**
             * Configure tethering with static IPv4 assignment.
             *
             * The clientAddress must be in the localIPv4Address prefix. A DHCP server will be
             * started, but will only be able to offer the client address. The two addresses must
             * be in the same prefix.
             * A DHCP server will be started, but will only be able to offer the client address.
             * The two addresses must be in the same prefix.
             *
             * @param localIPv4Address The preferred local IPv4 link address to use.
             * @param clientAddress The static client address.
@@ -584,10 +583,7 @@ public class TetheringManager {
                    @NonNull final LinkAddress clientAddress) {
                Objects.requireNonNull(localIPv4Address);
                Objects.requireNonNull(clientAddress);
                if (localIPv4Address.getPrefixLength() != clientAddress.getPrefixLength()
                        || !localIPv4Address.isIpv4() || !clientAddress.isIpv4()
                        || !new IpPrefix(localIPv4Address.toString()).equals(
                        new IpPrefix(clientAddress.toString()))) {
                if (!checkStaticAddressConfiguration(localIPv4Address, clientAddress)) {
                    throw new IllegalArgumentException("Invalid server or client addresses");
                }

@@ -656,6 +652,19 @@ public class TetheringManager {
            return mRequestParcel.showProvisioningUi;
        }

        /**
         * Check whether the two addresses are ipv4 and in the same prefix.
         * @hide
         */
        public static boolean checkStaticAddressConfiguration(
                @NonNull final LinkAddress localIPv4Address,
                @NonNull final LinkAddress clientAddress) {
            return localIPv4Address.getPrefixLength() == clientAddress.getPrefixLength()
                    && localIPv4Address.isIpv4() && clientAddress.isIpv4()
                    && new IpPrefix(localIPv4Address.toString()).equals(
                    new IpPrefix(clientAddress.toString()));
        }

        /**
         * Get a TetheringRequestParcel from the configuration
         * @hide
+14 −1
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package android.net.dhcp;

import static android.net.shared.Inet4AddressUtils.inet4AddressToIntHTH;

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

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.net.Inet4Address;
import java.util.Collection;
import java.util.Collections;
@@ -160,6 +162,17 @@ public class DhcpServingParamsParcelExt extends DhcpServingParamsParcel {
        return this;
    }

    /**
     * Set the client address to tell DHCP server only offer this address.
     * The client's prefix length is the same as server's.
     *
     * <p>If not set, the default value is null.
     */
    public DhcpServingParamsParcelExt setSingleClientAddr(@Nullable Inet4Address clientAddr) {
        this.clientAddr = clientAddr == null ? 0 : inet4AddressToIntHTH(clientAddr);
        return this;
    }

    private static int[] toIntArray(@NonNull Collection<Inet4Address> addrs) {
        int[] res = new int[addrs.size()];
        int i = 0;
+24 −8
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.net.ip;

import static android.net.InetAddresses.parseNumericAddress;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.TetheringManager.TetheringRequest.checkStaticAddressConfiguration;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.util.NetworkConstants.FF;
@@ -511,17 +512,24 @@ public class IpServer extends StateMachine {
        }
    }

    private boolean startDhcp(Inet4Address addr, int prefixLen) {
    private boolean startDhcp(final LinkAddress serverLinkAddr, final LinkAddress clientLinkAddr) {
        if (mUsingLegacyDhcp) {
            return true;
        }

        final Inet4Address addr = (Inet4Address) serverLinkAddr.getAddress();
        final int prefixLen = serverLinkAddr.getPrefixLength();
        final Inet4Address clientAddr = clientLinkAddr == null ? null :
                (Inet4Address) clientLinkAddr.getAddress();

        final DhcpServingParamsParcel params;
        params = new DhcpServingParamsParcelExt()
                .setDefaultRouters(addr)
                .setDhcpLeaseTimeSecs(DHCP_LEASE_TIME_SECS)
                .setDnsServers(addr)
                .setServerAddr(new LinkAddress(addr, prefixLen))
                .setMetered(true);
                .setServerAddr(serverLinkAddr)
                .setMetered(true)
                .setSingleClientAddr(clientAddr);
        // TODO: also advertise link MTU

        mDhcpServerStartIndex++;
@@ -556,9 +564,10 @@ public class IpServer extends StateMachine {
        }
    }

    private boolean configureDhcp(boolean enable, Inet4Address addr, int prefixLen) {
    private boolean configureDhcp(boolean enable, final LinkAddress serverAddr,
            final LinkAddress clientAddr) {
        if (enable) {
            return startDhcp(addr, prefixLen);
            return startDhcp(serverAddr, clientAddr);
        } else {
            stopDhcp();
            return true;
@@ -606,7 +615,7 @@ public class IpServer extends StateMachine {
                // code that calls into NetworkManagementService directly.
                srvAddr = (Inet4Address) parseNumericAddress(BLUETOOTH_IFACE_ADDR);
                mIpv4Address = new LinkAddress(srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
                return configureDhcp(enabled, srvAddr, BLUETOOTH_DHCP_PREFIX_LENGTH);
                return configureDhcp(enabled, mIpv4Address, null /* clientAddress */);
            }
            mIpv4Address = new LinkAddress(srvAddr, prefixLen);
        } catch (IllegalArgumentException e) {
@@ -643,7 +652,7 @@ public class IpServer extends StateMachine {
            mLinkProperties.removeRoute(route);
        }

        return configureDhcp(enabled, srvAddr, prefixLen);
        return configureDhcp(enabled, mIpv4Address, mStaticIpv4ClientAddr);
    }

    private String getRandomWifiIPv4Address() {
@@ -962,7 +971,14 @@ public class IpServer extends StateMachine {
    }

    private void maybeConfigureStaticIp(final TetheringRequestParcel request) {
        if (request == null) return;
        // Ignore static address configuration if they are invalid or null. In theory, static
        // addresses should not be invalid here because TetheringManager do not allow caller to
        // specify invalid static address configuration.
        if (request == null || request.localIPv4Address == null
                || request.staticClientAddress == null || !checkStaticAddressConfiguration(
                request.localIPv4Address, request.staticClientAddress)) {
            return;
        }

        mStaticIpv4ServerAddr = request.localIPv4Address;
        mStaticIpv4ClientAddr = request.staticClientAddress;
+8 −0
Original line number Diff line number Diff line
@@ -42,7 +42,9 @@ import java.util.stream.IntStream;
@SmallTest
public class DhcpServingParamsParcelExtTest {
    private static final Inet4Address TEST_ADDRESS = inet4Addr("192.168.0.123");
    private static final Inet4Address TEST_CLIENT_ADDRESS = inet4Addr("192.168.0.42");
    private static final int TEST_ADDRESS_PARCELED = 0xc0a8007b;
    private static final int TEST_CLIENT_ADDRESS_PARCELED = 0xc0a8002a;
    private static final int TEST_PREFIX_LENGTH = 17;
    private static final int TEST_LEASE_TIME_SECS = 120;
    private static final int TEST_MTU = 1000;
@@ -105,6 +107,12 @@ public class DhcpServingParamsParcelExtTest {
        assertFalse(mParcel.metered);
    }

    @Test
    public void testSetClientAddr() {
        mParcel.setSingleClientAddr(TEST_CLIENT_ADDRESS);
        assertEquals(TEST_CLIENT_ADDRESS_PARCELED, mParcel.clientAddr);
    }

    private static Inet4Address inet4Addr(String addr) {
        return (Inet4Address) parseNumericAddress(addr);
    }
+14 −6
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_FAILED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STARTED;
import static android.net.TetheringManager.TETHER_HARDWARE_OFFLOAD_STOPPED;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.shared.Inet4AddressUtils.intToInet4AddressHTH;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
@@ -1668,10 +1669,13 @@ public class TetheringTest {
    }

    @Test
    public void testRequestStaticServerIp() throws Exception {
        final LinkAddress serverLinkAddr = new LinkAddress("192.168.20.1/24");
        final LinkAddress clientLinkAddr = new LinkAddress("192.168.20.42/24");
        final String serverAddr = "192.168.20.1";
    public void testRequestStaticIp() throws Exception {
        final LinkAddress serverLinkAddr = new LinkAddress("192.168.0.123/24");
        final LinkAddress clientLinkAddr = new LinkAddress("192.168.0.42/24");
        final String serverAddr = "192.168.0.123";
        final int clientAddrParceled = 0xc0a8002a;
        final ArgumentCaptor<DhcpServingParamsParcel> dhcpParamsCaptor =
                ArgumentCaptor.forClass(DhcpServingParamsParcel.class);
        mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB,
                  serverLinkAddr, clientLinkAddr), null);
        mLooper.dispatchAll();
@@ -1680,8 +1684,12 @@ public class TetheringTest {
        sendUsbBroadcast(true, true, true, TETHERING_USB);
        mLooper.dispatchAll();
        verify(mNetd).interfaceSetCfg(argThat(cfg -> serverAddr.equals(cfg.ipv4Addr)));

        // TODO: test static client address.
        verify(mIpServerDependencies, times(1)).makeDhcpServer(any(), dhcpParamsCaptor.capture(),
                any());
        final DhcpServingParamsParcel params = dhcpParamsCaptor.getValue();
        assertEquals(serverAddr, intToInet4AddressHTH(params.serverAddr).getHostAddress());
        assertEquals(24, params.serverAddrPrefixLength);
        assertEquals(clientAddrParceled, params.clientAddr);
    }

    // TODO: Test that a request for hotspot mode doesn't interfere with an