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

Commit 31830456 authored by Erik Kline's avatar Erik Kline Committed by Gerrit Code Review
Browse files

Merge "Initial rename to IpServer"

parents e7f1dc66 7a4ccc69
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