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

Commit d981ad6c authored by Mark Chien's avatar Mark Chien Committed by Android (Google) Code Review
Browse files

Merge changes If7997341,I7584253b into mainline-prod

* changes:
  Allow wifi p2p to use legacy dedicated address
  Address comment from aosp/1232197
parents 182387a9 566f797d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -73,6 +73,9 @@
    <!-- Use the old dnsmasq DHCP server for tethering instead of the framework implementation. -->
    <bool translatable="false" name="config_tether_enable_legacy_dhcp_server">false</bool>

    <!-- Use legacy wifi p2p dedicated address instead of randomize address. -->
    <bool translatable="false" name="config_tether_enable_legacy_wifi_p2p_dedicated_ip">false</bool>

    <!-- Dhcp range (min, max) to use for tethering purposes -->
    <string-array translatable="false" name="config_tether_dhcp_range">
    </string-array>
+1 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
            -->
            <item type="bool" name="config_tether_enable_bpf_offload"/>
            <item type="bool" name="config_tether_enable_legacy_dhcp_server"/>
            <item type="bool" name="config_tether_enable_legacy_wifi_p2p_dedicated_ip"/>
            <item type="integer" name="config_tether_offload_poll_interval"/>
            <item type="array" name="config_tether_upstream_types"/>
            <item type="bool" name="config_tether_upstream_automatic"/>
+31 −15
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@
 */
package com.android.networkstack.tethering;

import static android.net.TetheringManager.TETHERING_WIFI_P2P;

import static java.util.Arrays.asList;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.IpPrefix;
@@ -34,9 +38,10 @@ import com.android.internal.util.IndentingPrintWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

/**
 * This class coordinate IP addresses conflict problem.
@@ -55,28 +60,32 @@ public class PrivateAddressCoordinator {
    private static final int BYTE_MASK = 0xff;
    // reserved for bluetooth tethering.
    private static final int BLUETOOTH_RESERVED = 44;
    private static final int WIFI_P2P_RESERVED = 49;
    private static final byte DEFAULT_ID = (byte) 42;

    // Upstream monitor would be stopped when tethering is down. When tethering restart, downstream
    // address may be requested before coordinator get current upstream notification. To ensure
    // coordinator do not select conflict downstream prefix, mUpstreamPrefixMap would not be cleared
    // when tethering is down. Instead coordinator would remove all depcreted upstreams from
    // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprectedUpstreams().
    // when tethering is down. Instead tethering would remove all deprecated upstreams from
    // mUpstreamPrefixMap when tethering is starting. See #maybeRemoveDeprecatedUpstreams().
    private final ArrayMap<Network, List<IpPrefix>> mUpstreamPrefixMap;
    private final ArraySet<IpServer> mDownstreams;
    // IANA has reserved the following three blocks of the IP address space for private intranets:
    // 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
    // Tethering use 192.168.0.0/16 that has 256 contiguous class C network numbers.
    private static final String DEFAULT_TETHERING_PREFIX = "192.168.0.0/16";
    private static final String LEGACY_WIFI_P2P_IFACE_ADDRESS = "192.168.49.1/24";
    private final IpPrefix mTetheringPrefix;
    private final ConnectivityManager mConnectivityMgr;
    private final TetheringConfiguration mConfig;

    public PrivateAddressCoordinator(Context context) {
    public PrivateAddressCoordinator(Context context, TetheringConfiguration config) {
        mDownstreams = new ArraySet<>();
        mUpstreamPrefixMap = new ArrayMap<>();
        mTetheringPrefix = new IpPrefix(DEFAULT_TETHERING_PREFIX);
        mConnectivityMgr = (ConnectivityManager) context.getSystemService(
                Context.CONNECTIVITY_SERVICE);
        mConfig = config;
    }

    /**
@@ -124,26 +133,34 @@ public class PrivateAddressCoordinator {
        mUpstreamPrefixMap.remove(network);
    }

    private void maybeRemoveDeprectedUpstreams() {
        if (!mDownstreams.isEmpty() || mUpstreamPrefixMap.isEmpty()) return;
    /**
     * Maybe remove deprecated upstream records, this would be called once tethering started without
     * any exiting tethered downstream.
     */
    public void maybeRemoveDeprecatedUpstreams() {
        if (mUpstreamPrefixMap.isEmpty()) return;

        final ArrayList<Network> toBeRemoved = new ArrayList<>();
        List<Network> allNetworks = Arrays.asList(mConnectivityMgr.getAllNetworks());
        for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
            final Network network = mUpstreamPrefixMap.keyAt(i);
            if (!allNetworks.contains(network)) toBeRemoved.add(network);
        }
        // Remove all upstreams that are no longer valid networks
        final Set<Network> toBeRemoved = new HashSet<>(mUpstreamPrefixMap.keySet());
        toBeRemoved.removeAll(asList(mConnectivityMgr.getAllNetworks()));

        mUpstreamPrefixMap.removeAll(toBeRemoved);
    }

    private boolean isReservedSubnet(final int subnet) {
        return subnet == BLUETOOTH_RESERVED || subnet == WIFI_P2P_RESERVED;
    }

    /**
     * Pick a random available address and mark its prefix as in use for the provided IpServer,
     * returns null if there is no available address.
     */
    @Nullable
    public LinkAddress requestDownstreamAddress(final IpServer ipServer) {
        maybeRemoveDeprectedUpstreams();
        if (mConfig.shouldEnableWifiP2pDedicatedIp()
                && ipServer.interfaceType() == TETHERING_WIFI_P2P) {
            return new LinkAddress(LEGACY_WIFI_P2P_IFACE_ADDRESS);
        }

        // Address would be 192.168.[subAddress]/24.
        final byte[] bytes = mTetheringPrefix.getRawAddress();
@@ -152,7 +169,7 @@ public class PrivateAddressCoordinator {
        bytes[3] = getSanitizedAddressSuffix(subAddress, (byte) 0, (byte) 1, (byte) 0xff);
        for (int i = 0; i < MAX_UBYTE; i++) {
            final int newSubNet = (subNet + i) & BYTE_MASK;
            if (newSubNet == BLUETOOTH_RESERVED) continue;
            if (isReservedSubnet(newSubNet)) continue;

            bytes[2] = (byte) newSubNet;
            final InetAddress addr;
@@ -237,7 +254,6 @@ public class PrivateAddressCoordinator {
    }

    void dump(final IndentingPrintWriter pw) {
        pw.decreaseIndent();
        pw.println("mUpstreamPrefixMap:");
        pw.increaseIndent();
        for (int i = 0; i < mUpstreamPrefixMap.size(); i++) {
+5 −1
Original line number Diff line number Diff line
@@ -320,10 +320,13 @@ public class Tethering {
        mExecutor = new TetheringThreadExecutor(mHandler);
        mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
        mNetdCallback = new NetdCallback();
        mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext);

        // Load tethering configuration.
        updateConfiguration();
        // It is OK for the configuration to be passed to the PrivateAddressCoordinator at
        // construction time because the only part of the configuration it uses is
        // shouldEnableWifiP2pDedicatedIp(), and currently do not support changing that.
        mPrivateAddressCoordinator = new PrivateAddressCoordinator(mContext, mConfig);

        // Must be initialized after tethering configuration is loaded because BpfCoordinator
        // constructor needs to use the configuration.
@@ -1751,6 +1754,7 @@ public class Tethering {
                    return;
                }

                mPrivateAddressCoordinator.maybeRemoveDeprecatedUpstreams();
                mUpstreamNetworkMonitor.startObserveAllNetworks();

                // TODO: De-duplicate with updateUpstreamWanted() below.
+16 −0
Original line number Diff line number Diff line
@@ -84,6 +84,9 @@ public class TetheringConfiguration {
    public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
            "tether_enable_legacy_dhcp_server";

    public static final String USE_LEGACY_WIFI_P2P_DEDICATED_IP =
            "use_legacy_wifi_p2p_dedicated_ip";

    /**
     * Default value that used to periodic polls tether offload stats from tethering offload HAL
     * to make the data warnings work.
@@ -113,6 +116,7 @@ public class TetheringConfiguration {
    private final int mOffloadPollInterval;
    // TODO: Add to TetheringConfigurationParcel if required.
    private final boolean mEnableBpfOffload;
    private final boolean mEnableWifiP2pDedicatedIp;

    public TetheringConfiguration(Context ctx, SharedLog log, int id) {
        final SharedLog configLog = log.forSubComponent("config");
@@ -156,6 +160,10 @@ public class TetheringConfiguration {
                R.integer.config_tether_offload_poll_interval,
                DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);

        mEnableWifiP2pDedicatedIp = getResourceBoolean(res,
                R.bool.config_tether_enable_legacy_wifi_p2p_dedicated_ip,
                false /* defaultValue */);

        configLog.log(toString());
    }

@@ -199,6 +207,11 @@ public class TetheringConfiguration {
        return !TextUtils.isEmpty(provisioningAppNoUi);
    }

    /** Check whether dedicated wifi p2p address is enabled. */
    public boolean shouldEnableWifiP2pDedicatedIp() {
        return mEnableWifiP2pDedicatedIp;
    }

    /** Does the dumping.*/
    public void dump(PrintWriter pw) {
        pw.print("activeDataSubId: ");
@@ -233,6 +246,9 @@ public class TetheringConfiguration {

        pw.print("enableLegacyDhcpServer: ");
        pw.println(enableLegacyDhcpServer);

        pw.print("enableWifiP2pDedicatedIp: ");
        pw.println(mEnableWifiP2pDedicatedIp);
    }

    /** Returns the string representation of this object.*/
Loading