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

Commit 8c6df2e9 authored by Erik Kline's avatar Erik Kline Committed by android-build-merger
Browse files

Merge "Initial rename to IpServer" am: 31830456

am: 38f2c4ea

Change-Id: If256c7b210d17d861fb41c303deab0fe80280901
parents dcedc99b 38f2c4ea
Loading
Loading
Loading
Loading
+93 −121

File changed.

Preview size limit exceeded, changes collapsed.

+0 −66
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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 com.android.server.connectivity.tethering;

import android.net.LinkProperties;

/**
 * @hide
 *
 * Interface with methods necessary to notify that a given interface is ready for tethering.
 *
 * Rename to something more representative, e.g. IpServingControlCallback.
 *
 * All methods MUST be called on the TetherMasterSM main Looper's thread.
 */
public class IControlsTethering {
    public static final int STATE_UNAVAILABLE = 0;
    public static final int STATE_AVAILABLE   = 1;
    public static final int STATE_TETHERED    = 2;
    public static final int STATE_LOCAL_ONLY  = 3;

    public static String getStateString(int state) {
        switch (state) {
            case STATE_UNAVAILABLE: return "UNAVAILABLE";
            case STATE_AVAILABLE:   return "AVAILABLE";
            case STATE_TETHERED:    return "TETHERED";
            case STATE_LOCAL_ONLY:  return "LOCAL_ONLY";
        }
        return "UNKNOWN: " + state;
    }

    /**
     * Notify that |who| has changed its tethering state.
     *
     * TODO: Remove the need for the |who| argument.
     *
     * @param who corresponding instance of a TetherInterfaceStateMachine
     * @param state one of IControlsTethering.STATE_*
     * @param lastError one of ConnectivityManager.TETHER_ERROR_*
     */
    public void updateInterfaceState(TetherInterfaceStateMachine who, int state, int lastError) {}

    /**
     * Notify that |who| has new LinkProperties.
     *
     * TODO: Remove the need for the |who| argument.
     *
     * @param who corresponding instance of a TetherInterfaceStateMachine
     * @param newLp the new LinkProperties to report
     */
    public void updateLinkProperties(TetherInterfaceStateMachine who, LinkProperties newLp) {}
}
+24 −24
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.connectivity.tethering;

import android.net.ConnectivityManager;
import android.net.ip.IpServer;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -50,19 +51,19 @@ public class IPv6TetheringCoordinator {
    private static final boolean VDBG = false;

    private static class Downstream {
        public final TetherInterfaceStateMachine tism;
        public final int mode;  // IControlsTethering.STATE_*
        public final IpServer ipServer;
        public final int mode;  // IpServer.STATE_*
        // Used to append to a ULA /48, constructing a ULA /64 for local use.
        public final short subnetId;

        Downstream(TetherInterfaceStateMachine tism, int mode, short subnetId) {
            this.tism = tism;
        Downstream(IpServer ipServer, int mode, short subnetId) {
            this.ipServer = ipServer;
            this.mode = mode;
            this.subnetId = subnetId;
        }
    }

    private final ArrayList<TetherInterfaceStateMachine> mNotifyList;
    private final ArrayList<IpServer> mNotifyList;
    private final SharedLog mLog;
    // NOTE: mActiveDownstreams is a list and not a hash data structure because
    // we keep active downstreams in arrival order.  This is done so /64s can
@@ -74,8 +75,7 @@ public class IPv6TetheringCoordinator {
    private short mNextSubnetId;
    private NetworkState mUpstreamNetworkState;

    public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList,
                                    SharedLog log) {
    public IPv6TetheringCoordinator(ArrayList<IpServer> notifyList, SharedLog log) {
        mNotifyList = notifyList;
        mLog = log.forSubComponent(TAG);
        mActiveDownstreams = new LinkedList<>();
@@ -83,7 +83,7 @@ public class IPv6TetheringCoordinator {
        mNextSubnetId = 0;
    }

    public void addActiveDownstream(TetherInterfaceStateMachine downstream, int mode) {
    public void addActiveDownstream(IpServer downstream, int mode) {
        if (findDownstream(downstream) == null) {
            // Adding a new downstream appends it to the list. Adding a
            // downstream a second time without first removing it has no effect.
@@ -98,7 +98,7 @@ public class IPv6TetheringCoordinator {
        }
    }

    public void removeActiveDownstream(TetherInterfaceStateMachine downstream) {
    public void removeActiveDownstream(IpServer downstream) {
        stopIPv6TetheringOn(downstream);
        if (mActiveDownstreams.remove(findDownstream(downstream))) {
            updateIPv6TetheringInterfaces();
@@ -133,8 +133,8 @@ public class IPv6TetheringCoordinator {
    }

    private void stopIPv6TetheringOnAllInterfaces() {
        for (TetherInterfaceStateMachine sm : mNotifyList) {
            stopIPv6TetheringOn(sm);
        for (IpServer ipServer : mNotifyList) {
            stopIPv6TetheringOn(ipServer);
        }
    }

@@ -156,28 +156,28 @@ public class IPv6TetheringCoordinator {
    }

    private void updateIPv6TetheringInterfaces() {
        for (TetherInterfaceStateMachine sm : mNotifyList) {
            final LinkProperties lp = getInterfaceIPv6LinkProperties(sm);
            sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
        for (IpServer ipServer : mNotifyList) {
            final LinkProperties lp = getInterfaceIPv6LinkProperties(ipServer);
            ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, lp);
            break;
        }
    }

    private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) {
        if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) {
    private LinkProperties getInterfaceIPv6LinkProperties(IpServer ipServer) {
        if (ipServer.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) {
            // TODO: Figure out IPv6 support on PAN interfaces.
            return null;
        }

        final Downstream ds = findDownstream(sm);
        final Downstream ds = findDownstream(ipServer);
        if (ds == null) return null;

        if (ds.mode == IControlsTethering.STATE_LOCAL_ONLY) {
        if (ds.mode == IpServer.STATE_LOCAL_ONLY) {
            // Build a Unique Locally-assigned Prefix configuration.
            return getUniqueLocalConfig(mUniqueLocalPrefix, ds.subnetId);
        }

        // This downstream is in IControlsTethering.STATE_TETHERED mode.
        // This downstream is in IpServer.STATE_TETHERED mode.
        if (mUpstreamNetworkState == null || mUpstreamNetworkState.linkProperties == null) {
            return null;
        }
@@ -188,7 +188,7 @@ public class IPv6TetheringCoordinator {
        // IPv6 toward the oldest (first requested) active downstream.

        final Downstream currentActive = mActiveDownstreams.peek();
        if (currentActive != null && currentActive.tism == sm) {
        if (currentActive != null && currentActive.ipServer == ipServer) {
            final LinkProperties lp = getIPv6OnlyLinkProperties(
                    mUpstreamNetworkState.linkProperties);
            if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) {
@@ -199,9 +199,9 @@ public class IPv6TetheringCoordinator {
        return null;
    }

    Downstream findDownstream(TetherInterfaceStateMachine tism) {
    Downstream findDownstream(IpServer ipServer) {
        for (Downstream ds : mActiveDownstreams) {
            if (ds.tism == tism) return ds;
            if (ds.ipServer == ipServer) return ds;
        }
        return null;
    }
@@ -304,7 +304,7 @@ public class IPv6TetheringCoordinator {
                ns.linkProperties);
    }

    private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) {
        sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
    private static void stopIPv6TetheringOn(IpServer ipServer) {
        ipServer.sendMessage(IpServer.CMD_IPV6_TETHER_UPDATE, 0, 0, null);
    }
}
+4 −16
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.net.INetd;
import android.net.NetworkRequest;
import android.net.dhcp.DhcpServer;
import android.net.dhcp.DhcpServingParams;
import android.net.ip.IpServer;
import android.net.ip.RouterAdvertisementDaemon;
import android.net.util.InterfaceParams;
import android.net.util.NetdService;
@@ -49,20 +50,12 @@ public class TetheringDependencies {
    }

    public IPv6TetheringCoordinator getIPv6TetheringCoordinator(
            ArrayList<TetherInterfaceStateMachine> notifyList, SharedLog log) {
            ArrayList<IpServer> notifyList, SharedLog log) {
        return new IPv6TetheringCoordinator(notifyList, log);
    }

    public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) {
        return new RouterAdvertisementDaemon(ifParams);
    }

    public InterfaceParams getInterfaceParams(String ifName) {
        return InterfaceParams.getByName(ifName);
    }

    public INetd getNetdService() {
        return NetdService.getInstance();
    public IpServer.Dependencies getIpServerDependencies() {
        return new IpServer.Dependencies();
    }

    public boolean isTetheringSupported() {
@@ -72,9 +65,4 @@ public class TetheringDependencies {
    public NetworkRequest getDefaultNetworkRequest() {
        return null;
    }

    public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface, DhcpServingParams params,
            SharedLog log) {
        return new DhcpServer(looper, iface, params, log);
    }
}
+74 −25
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.server.connectivity.tethering;
package android.net.ip;

import static android.net.NetworkUtils.numericToInetAddress;
import static android.net.util.NetworkConstants.asByte;
@@ -31,11 +31,10 @@ import android.net.LinkProperties;
import android.net.RouteInfo;
import android.net.dhcp.DhcpServer;
import android.net.dhcp.DhcpServingParams;
import android.net.ip.InterfaceController;
import android.net.ip.RouterAdvertisementDaemon;
import android.net.ip.RouterAdvertisementDaemon.RaParams;
import android.net.util.InterfaceParams;
import android.net.util.InterfaceSet;
import android.net.util.NetdService;
import android.net.util.SharedLog;
import android.os.INetworkManagementService;
import android.os.Looper;
@@ -67,7 +66,22 @@ import java.util.Set;
 *
 * @hide
 */
public class TetherInterfaceStateMachine extends StateMachine {
public class IpServer extends StateMachine {
    public static final int STATE_UNAVAILABLE = 0;
    public static final int STATE_AVAILABLE   = 1;
    public static final int STATE_TETHERED    = 2;
    public static final int STATE_LOCAL_ONLY  = 3;

    public static String getStateString(int state) {
        switch (state) {
            case STATE_UNAVAILABLE: return "UNAVAILABLE";
            case STATE_AVAILABLE:   return "AVAILABLE";
            case STATE_TETHERED:    return "TETHERED";
            case STATE_LOCAL_ONLY:  return "LOCAL_ONLY";
        }
        return "UNKNOWN: " + state;
    }

    private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64");
    private static final byte DOUG_ADAMS = (byte) 42;

@@ -83,15 +97,53 @@ public class TetherInterfaceStateMachine extends StateMachine {
    // TODO: have this configurable
    private static final int DHCP_LEASE_TIME_SECS = 3600;

    private final static String TAG = "TetherInterfaceSM";
    private final static String TAG = "IpServer";
    private final static boolean DBG = false;
    private final static boolean VDBG = false;
    private static final Class[] messageClasses = {
            TetherInterfaceStateMachine.class
            IpServer.class
    };
    private static final SparseArray<String> sMagicDecoderRing =
            MessageUtils.findMessageNames(messageClasses);

    public static class Callback {
        /**
         * Notify that |who| has changed its tethering state.
         *
         * @param who the calling instance of IpServer
         * @param state one of STATE_*
         * @param lastError one of ConnectivityManager.TETHER_ERROR_*
         */
        public void updateInterfaceState(IpServer who, int state, int lastError) {}

        /**
         * Notify that |who| has new LinkProperties.
         *
         * @param who the calling instance of IpServer
         * @param newLp the new LinkProperties to report
         */
        public void updateLinkProperties(IpServer who, LinkProperties newLp) {}
    }

    public static class Dependencies {
        public RouterAdvertisementDaemon getRouterAdvertisementDaemon(InterfaceParams ifParams) {
            return new RouterAdvertisementDaemon(ifParams);
        }

        public InterfaceParams getInterfaceParams(String ifName) {
            return InterfaceParams.getByName(ifName);
        }

        public INetd getNetdService() {
            return NetdService.getInstance();
        }

        public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
                DhcpServingParams params, SharedLog log) {
            return new DhcpServer(looper, iface, params, log);
        }
    }

    private static final int BASE_IFACE              = Protocol.BASE_TETHERING + 100;
    // request from the user that it wants to tether
    public static final int CMD_TETHER_REQUESTED            = BASE_IFACE + 2;
@@ -123,7 +175,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
    private final INetworkManagementService mNMService;
    private final INetd mNetd;
    private final INetworkStatsService mStatsService;
    private final IControlsTethering mTetherController;
    private final Callback mCallback;
    private final InterfaceController mInterfaceCtrl;

    private final String mIfaceName;
@@ -131,7 +183,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
    private final LinkProperties mLinkProperties;
    private final boolean mUsingLegacyDhcp;

    private final TetheringDependencies mDeps;
    private final Dependencies mDeps;

    private int mLastError;
    private int mServingMode;
@@ -148,17 +200,16 @@ public class TetherInterfaceStateMachine extends StateMachine {
    private DhcpServer mDhcpServer;
    private RaParams mLastRaParams;

    public TetherInterfaceStateMachine(
    public IpServer(
            String ifaceName, Looper looper, int interfaceType, SharedLog log,
            INetworkManagementService nMService, INetworkStatsService statsService,
            IControlsTethering tetherController, boolean usingLegacyDhcp,
            TetheringDependencies deps) {
            Callback callback, boolean usingLegacyDhcp, Dependencies deps) {
        super(ifaceName, looper);
        mLog = log.forSubComponent(ifaceName);
        mNMService = nMService;
        mNetd = deps.getNetdService();
        mStatsService = statsService;
        mTetherController = tetherController;
        mCallback = callback;
        mInterfaceCtrl = new InterfaceController(ifaceName, nMService, mNetd, mLog);
        mIfaceName = ifaceName;
        mInterfaceType = interfaceType;
@@ -167,7 +218,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
        mDeps = deps;
        resetLinkProperties();
        mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
        mServingMode = IControlsTethering.STATE_AVAILABLE;
        mServingMode = STATE_AVAILABLE;

        mInitialState = new InitialState();
        mLocalHotspotState = new LocalHotspotState();
@@ -521,14 +572,12 @@ public class TetherInterfaceStateMachine extends StateMachine {

    private void sendInterfaceState(int newInterfaceState) {
        mServingMode = newInterfaceState;
        mTetherController.updateInterfaceState(
                TetherInterfaceStateMachine.this, newInterfaceState, mLastError);
        mCallback.updateInterfaceState(this, newInterfaceState, mLastError);
        sendLinkProperties();
    }

    private void sendLinkProperties() {
        mTetherController.updateLinkProperties(
                TetherInterfaceStateMachine.this, new LinkProperties(mLinkProperties));
        mCallback.updateLinkProperties(this, new LinkProperties(mLinkProperties));
    }

    private void resetLinkProperties() {
@@ -539,7 +588,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
    class InitialState extends State {
        @Override
        public void enter() {
            sendInterfaceState(IControlsTethering.STATE_AVAILABLE);
            sendInterfaceState(STATE_AVAILABLE);
        }

        @Override
@@ -549,10 +598,10 @@ public class TetherInterfaceStateMachine extends StateMachine {
                case CMD_TETHER_REQUESTED:
                    mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
                    switch (message.arg1) {
                        case IControlsTethering.STATE_LOCAL_ONLY:
                        case STATE_LOCAL_ONLY:
                            transitionTo(mLocalHotspotState);
                            break;
                        case IControlsTethering.STATE_TETHERED:
                        case STATE_TETHERED:
                            transitionTo(mTetheredState);
                            break;
                        default:
@@ -649,7 +698,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
    // problematic because transitioning during a multi-state jump yields
    // a Log.wtf(). Ultimately, there should be only one ServingState,
    // and forwarding and NAT rules should be handled by a coordinating
    // functional element outside of TetherInterfaceStateMachine.
    // functional element outside of IpServer.
    class LocalHotspotState extends BaseServingState {
        @Override
        public void enter() {
@@ -659,7 +708,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
            }

            if (DBG) Log.d(TAG, "Local hotspot " + mIfaceName);
            sendInterfaceState(IControlsTethering.STATE_LOCAL_ONLY);
            sendInterfaceState(STATE_LOCAL_ONLY);
        }

        @Override
@@ -685,7 +734,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
    // problematic because transitioning during a multi-state jump yields
    // a Log.wtf(). Ultimately, there should be only one ServingState,
    // and forwarding and NAT rules should be handled by a coordinating
    // functional element outside of TetherInterfaceStateMachine.
    // functional element outside of IpServer.
    class TetheredState extends BaseServingState {
        @Override
        public void enter() {
@@ -695,7 +744,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
            }

            if (DBG) Log.d(TAG, "Tethered " + mIfaceName);
            sendInterfaceState(IControlsTethering.STATE_TETHERED);
            sendInterfaceState(STATE_TETHERED);
        }

        @Override
@@ -817,7 +866,7 @@ public class TetherInterfaceStateMachine extends StateMachine {
        @Override
        public void enter() {
            mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
            sendInterfaceState(IControlsTethering.STATE_UNAVAILABLE);
            sendInterfaceState(STATE_UNAVAILABLE);
        }
    }

Loading