Loading core/java/android/os/INetworkManagementService.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,18 @@ interface INetworkManagementService */ void removeRoute(String iface, in RouteInfo route); /** * Add the specified route to a secondary interface * This will go into a special route table to be accessed * via ip rules */ void addSecondaryRoute(String iface, in RouteInfo route); /** * Remove the specified secondary route. */ void removeSecondaryRoute(String iface, in RouteInfo route); /** * Shuts down the service */ Loading services/java/com/android/server/ConnectivityService.java +50 −27 Original line number Diff line number Diff line Loading @@ -171,6 +171,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { private static final int ENABLED = 1; private static final int DISABLED = 0; private static final boolean ADD = true; private static final boolean REMOVE = false; private static final boolean TO_DEFAULT_TABLE = true; private static final boolean TO_SECONDARY_TABLE = false; // Share the event space with NetworkStateTracker (which can't see this // internal class but sends us events). If you change these, change // NetworkStateTracker.java too. Loading Loading @@ -501,7 +507,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b); mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper()); mTethering = new Tethering(mContext, nmService, statsService, this, mHandler.getLooper()); mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 || mTethering.getTetherableWifiRegexs().length != 0 || mTethering.getTetherableBluetoothRegexs().length != 0) && Loading Loading @@ -1146,23 +1152,24 @@ public class ConnectivityService extends IConnectivityManager.Stub { return false; } private boolean addRoute(LinkProperties p, RouteInfo r) { return modifyRoute(p.getInterfaceName(), p, r, 0, true); private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) { return modifyRoute(p.getInterfaceName(), p, r, 0, ADD, toDefaultTable); } private boolean removeRoute(LinkProperties p, RouteInfo r) { return modifyRoute(p.getInterfaceName(), p, r, 0, false); private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) { return modifyRoute(p.getInterfaceName(), p, r, 0, REMOVE, toDefaultTable); } private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) { return modifyRouteToAddress(lp, addr, true); return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE); } private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) { return modifyRouteToAddress(lp, addr, false); return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE); } private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) { private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd, boolean toDefaultTable) { RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr); if (bestRoute == null) { bestRoute = RouteInfo.makeHostRoute(addr); Loading @@ -1176,15 +1183,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway()); } } return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd); return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd, toDefaultTable); } private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd) { boolean doAdd, boolean toDefaultTable) { if ((ifaceName == null) || (lp == null) || (r == null)) return false; if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) { loge("Error adding route - too much recursion"); loge("Error modifying route - too much recursion"); return false; } Loading @@ -1199,14 +1206,18 @@ public class ConnectivityService extends IConnectivityManager.Stub { // route to it's gateway bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway()); } modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd); modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd, toDefaultTable); } } if (doAdd) { if (VDBG) log("Adding " + r + " for interface " + ifaceName); mAddedRoutes.add(r); try { if (toDefaultTable) { mAddedRoutes.add(r); // only track default table - only one apps can effect mNetd.addRoute(ifaceName, r); } else { mNetd.addSecondaryRoute(ifaceName, r); } } catch (Exception e) { // never crash - catch them all if (VDBG) loge("Exception trying to add a route: " + e); Loading @@ -1215,6 +1226,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } else { // if we remove this one and there are no more like it, then refcount==0 and // we can remove it from the table if (toDefaultTable) { mAddedRoutes.remove(r); if (mAddedRoutes.contains(r) == false) { if (VDBG) log("Removing " + r + " for interface " + ifaceName); Loading @@ -1228,6 +1240,16 @@ public class ConnectivityService extends IConnectivityManager.Stub { } else { if (VDBG) log("not removing " + r + " as it's still in use"); } } else { if (VDBG) log("Removing " + r + " for interface " + ifaceName); try { mNetd.removeSecondaryRoute(ifaceName, r); } catch (Exception e) { // never crash - catch them all if (VDBG) loge("Exception trying to remove a route: " + e); return false; } } } return true; } Loading Loading @@ -1862,14 +1884,21 @@ public class ConnectivityService extends IConnectivityManager.Stub { for (RouteInfo r : routeDiff.removed) { if (isLinkDefault || ! r.isDefaultRoute()) { removeRoute(curLp, r); removeRoute(curLp, r, TO_DEFAULT_TABLE); } if (isLinkDefault == false) { // remove from a secondary route table removeRoute(curLp, r, TO_SECONDARY_TABLE); } } for (RouteInfo r : routeDiff.added) { if (isLinkDefault || ! r.isDefaultRoute()) { addRoute(newLp, r); addRoute(newLp, r, TO_DEFAULT_TABLE); } else { // add to a secondary route table addRoute(newLp, r, TO_SECONDARY_TABLE); // many radios add a default route even when we don't want one. // remove the default route unless somebody else has asked for it String ifaceName = newLp.getInterfaceName(); Loading Loading @@ -2450,12 +2479,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1); boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0); // Short term disabling of Tethering if DUN is required. // TODO - fix multi-connection tethering using policy-base routing int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes(); for (int i : upstreamConnTypes) { if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false; } return tetherEnabledInSettings && mTetheringConfigValid; } Loading services/java/com/android/server/NetworkManagementService.java +48 −11 Original line number Diff line number Diff line Loading @@ -59,7 +59,11 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.NoSuchElementException; import java.util.StringTokenizer; Loading @@ -77,6 +81,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub private static final int ADD = 1; private static final int REMOVE = 2; private static final String DEFAULT = "default"; private static final String SECONDARY = "secondary"; /** * Name representing {@link #setGlobalAlert(long)} limit when delivered to * {@link INetworkManagementEventObserver#limitReached(String, String)}. Loading Loading @@ -500,15 +507,25 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void addRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, ADD, route); modifyRoute(interfaceName, ADD, route, DEFAULT); } public void removeRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, REMOVE, route); modifyRoute(interfaceName, REMOVE, route, DEFAULT); } private void modifyRoute(String interfaceName, int action, RouteInfo route) { public void addSecondaryRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, ADD, route, SECONDARY); } public void removeSecondaryRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, REMOVE, route, SECONDARY); } private void modifyRoute(String interfaceName, int action, RouteInfo route, String type) { ArrayList<String> rsp; StringBuilder cmd; Loading @@ -516,12 +533,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub switch (action) { case ADD: { cmd = new StringBuilder("interface route add " + interfaceName); cmd = new StringBuilder("interface route add " + interfaceName + " " + type); break; } case REMOVE: { cmd = new StringBuilder("interface route remove " + interfaceName); cmd = new StringBuilder("interface route remove " + interfaceName + " " + type); break; } default: Loading Loading @@ -828,14 +845,33 @@ public class NetworkManagementService extends INetworkManagementService.Stub } } private void modifyNat(String cmd, String internalInterface, String externalInterface) throws SocketException { cmd = String.format("nat %s %s %s", cmd, internalInterface, externalInterface); NetworkInterface internalNetworkInterface = NetworkInterface.getByName(internalInterface); Collection<InterfaceAddress>interfaceAddresses = internalNetworkInterface.getInterfaceAddresses(); cmd += " " + interfaceAddresses.size(); for (InterfaceAddress ia : interfaceAddresses) { InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(), ia.getNetworkPrefixLength()); cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength(); } mConnector.doCommand(cmd); } public void enableNat(String internalInterface, String externalInterface) throws IllegalStateException { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); if (DBG) Log.d(TAG, "enableNat(" + internalInterface + ", " + externalInterface + ")"); try { mConnector.doCommand( String.format("nat enable %s %s", internalInterface, externalInterface)); } catch (NativeDaemonConnectorException e) { modifyNat("enable", internalInterface, externalInterface); } catch (Exception e) { Log.e(TAG, "enableNat got Exception " + e.toString()); throw new IllegalStateException( "Unable to communicate to native daemon for enabling NAT interface"); } Loading @@ -845,10 +881,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub throws IllegalStateException { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); if (DBG) Log.d(TAG, "disableNat(" + internalInterface + ", " + externalInterface + ")"); try { mConnector.doCommand( String.format("nat disable %s %s", internalInterface, externalInterface)); } catch (NativeDaemonConnectorException e) { modifyNat("disable", internalInterface, externalInterface); } catch (Exception e) { Log.e(TAG, "disableNat got Exception " + e.toString()); throw new IllegalStateException( "Unable to communicate to native daemon for disabling NAT interface"); } Loading services/java/com/android/server/connectivity/Tethering.java +10 −14 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private final INetworkManagementService mNMService; private final INetworkStatsService mStatsService; private final IConnectivityManager mConnService; private Looper mLooper; private HandlerThread mThread; Loading Loading @@ -127,10 +128,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { // when RNDIS is enabled public Tethering(Context context, INetworkManagementService nmService, INetworkStatsService statsService, Looper looper) { INetworkStatsService statsService, IConnectivityManager connService, Looper looper) { mContext = context; mNMService = nmService; mStatsService = statsService; mConnService = connService; mLooper = looper; mIfaces = new HashMap<String, TetherInterfaceSM>(); Loading Loading @@ -347,10 +349,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } private void sendTetherStateChangedBroadcast() { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); try { if (!cm.isTetheringSupported()) return; if (!mConnService.isTetheringSupported()) return; } catch (RemoteException e) { return; } Loading Loading @@ -910,6 +910,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { mNMService.tetherInterface(mIfaceName); } catch (Exception e) { Log.e(TAG, "Error Tethering: " + e.toString()); setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR); transitionTo(mInitialState); Loading Loading @@ -987,6 +988,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { mNMService.enableNat(mIfaceName, newUpstreamIfaceName); } catch (Exception e) { Log.e(TAG, "Exception enabling Nat: " + e.toString()); try { mNMService.untetherInterface(mIfaceName); } catch (Exception ee) {} Loading Loading @@ -1150,13 +1152,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { boolean retValue = true; if (apnType == ConnectivityManager.TYPE_NONE) return false; if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection(); IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); int result = Phone.APN_REQUEST_FAILED; String enableString = enableString(apnType); if (enableString == null) return false; try { result = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, result = mConnService.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, enableString, new Binder()); } catch (Exception e) { } Loading @@ -1178,10 +1178,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } protected boolean turnOffUpstreamMobileConnection() { if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); try { cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, mConnService.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, enableString(mMobileApnReserved)); } catch (Exception e) { return false; Loading Loading @@ -1234,8 +1232,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } protected void chooseUpstreamType(boolean tryCell) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); int upType = ConnectivityManager.TYPE_NONE; String iface = null; Loading @@ -1251,7 +1247,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { for (Integer netType : mUpstreamIfaceTypes) { NetworkInfo info = null; try { info = cm.getNetworkInfo(netType.intValue()); info = mConnService.getNetworkInfo(netType.intValue()); } catch (RemoteException e) { } if ((info != null) && info.isConnected()) { upType = netType.intValue(); Loading Loading @@ -1283,7 +1279,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } else { LinkProperties linkProperties = null; try { linkProperties = cm.getLinkProperties(upType); linkProperties = mConnService.getLinkProperties(upType); } catch (RemoteException e) { } if (linkProperties != null) iface = linkProperties.getInterfaceName(); } Loading Loading
core/java/android/os/INetworkManagementService.aidl +12 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,18 @@ interface INetworkManagementService */ void removeRoute(String iface, in RouteInfo route); /** * Add the specified route to a secondary interface * This will go into a special route table to be accessed * via ip rules */ void addSecondaryRoute(String iface, in RouteInfo route); /** * Remove the specified secondary route. */ void removeSecondaryRoute(String iface, in RouteInfo route); /** * Shuts down the service */ Loading
services/java/com/android/server/ConnectivityService.java +50 −27 Original line number Diff line number Diff line Loading @@ -171,6 +171,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { private static final int ENABLED = 1; private static final int DISABLED = 0; private static final boolean ADD = true; private static final boolean REMOVE = false; private static final boolean TO_DEFAULT_TABLE = true; private static final boolean TO_SECONDARY_TABLE = false; // Share the event space with NetworkStateTracker (which can't see this // internal class but sends us events). If you change these, change // NetworkStateTracker.java too. Loading Loading @@ -501,7 +507,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); INetworkManagementService nmService = INetworkManagementService.Stub.asInterface(b); mTethering = new Tethering(mContext, nmService, statsService, mHandler.getLooper()); mTethering = new Tethering(mContext, nmService, statsService, this, mHandler.getLooper()); mTetheringConfigValid = ((mTethering.getTetherableUsbRegexs().length != 0 || mTethering.getTetherableWifiRegexs().length != 0 || mTethering.getTetherableBluetoothRegexs().length != 0) && Loading Loading @@ -1146,23 +1152,24 @@ public class ConnectivityService extends IConnectivityManager.Stub { return false; } private boolean addRoute(LinkProperties p, RouteInfo r) { return modifyRoute(p.getInterfaceName(), p, r, 0, true); private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) { return modifyRoute(p.getInterfaceName(), p, r, 0, ADD, toDefaultTable); } private boolean removeRoute(LinkProperties p, RouteInfo r) { return modifyRoute(p.getInterfaceName(), p, r, 0, false); private boolean removeRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable) { return modifyRoute(p.getInterfaceName(), p, r, 0, REMOVE, toDefaultTable); } private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) { return modifyRouteToAddress(lp, addr, true); return modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE); } private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) { return modifyRouteToAddress(lp, addr, false); return modifyRouteToAddress(lp, addr, REMOVE, TO_DEFAULT_TABLE); } private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) { private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd, boolean toDefaultTable) { RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr); if (bestRoute == null) { bestRoute = RouteInfo.makeHostRoute(addr); Loading @@ -1176,15 +1183,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway()); } } return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd); return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd, toDefaultTable); } private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount, boolean doAdd) { boolean doAdd, boolean toDefaultTable) { if ((ifaceName == null) || (lp == null) || (r == null)) return false; if (cycleCount > MAX_HOSTROUTE_CYCLE_COUNT) { loge("Error adding route - too much recursion"); loge("Error modifying route - too much recursion"); return false; } Loading @@ -1199,14 +1206,18 @@ public class ConnectivityService extends IConnectivityManager.Stub { // route to it's gateway bestRoute = RouteInfo.makeHostRoute(r.getGateway(), bestRoute.getGateway()); } modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd); modifyRoute(ifaceName, lp, bestRoute, cycleCount+1, doAdd, toDefaultTable); } } if (doAdd) { if (VDBG) log("Adding " + r + " for interface " + ifaceName); mAddedRoutes.add(r); try { if (toDefaultTable) { mAddedRoutes.add(r); // only track default table - only one apps can effect mNetd.addRoute(ifaceName, r); } else { mNetd.addSecondaryRoute(ifaceName, r); } } catch (Exception e) { // never crash - catch them all if (VDBG) loge("Exception trying to add a route: " + e); Loading @@ -1215,6 +1226,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { } else { // if we remove this one and there are no more like it, then refcount==0 and // we can remove it from the table if (toDefaultTable) { mAddedRoutes.remove(r); if (mAddedRoutes.contains(r) == false) { if (VDBG) log("Removing " + r + " for interface " + ifaceName); Loading @@ -1228,6 +1240,16 @@ public class ConnectivityService extends IConnectivityManager.Stub { } else { if (VDBG) log("not removing " + r + " as it's still in use"); } } else { if (VDBG) log("Removing " + r + " for interface " + ifaceName); try { mNetd.removeSecondaryRoute(ifaceName, r); } catch (Exception e) { // never crash - catch them all if (VDBG) loge("Exception trying to remove a route: " + e); return false; } } } return true; } Loading Loading @@ -1862,14 +1884,21 @@ public class ConnectivityService extends IConnectivityManager.Stub { for (RouteInfo r : routeDiff.removed) { if (isLinkDefault || ! r.isDefaultRoute()) { removeRoute(curLp, r); removeRoute(curLp, r, TO_DEFAULT_TABLE); } if (isLinkDefault == false) { // remove from a secondary route table removeRoute(curLp, r, TO_SECONDARY_TABLE); } } for (RouteInfo r : routeDiff.added) { if (isLinkDefault || ! r.isDefaultRoute()) { addRoute(newLp, r); addRoute(newLp, r, TO_DEFAULT_TABLE); } else { // add to a secondary route table addRoute(newLp, r, TO_SECONDARY_TABLE); // many radios add a default route even when we don't want one. // remove the default route unless somebody else has asked for it String ifaceName = newLp.getInterfaceName(); Loading Loading @@ -2450,12 +2479,6 @@ public class ConnectivityService extends IConnectivityManager.Stub { int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1); boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0); // Short term disabling of Tethering if DUN is required. // TODO - fix multi-connection tethering using policy-base routing int[] upstreamConnTypes = mTethering.getUpstreamIfaceTypes(); for (int i : upstreamConnTypes) { if (i == ConnectivityManager.TYPE_MOBILE_DUN) return false; } return tetherEnabledInSettings && mTetheringConfigValid; } Loading
services/java/com/android/server/NetworkManagementService.java +48 −11 Original line number Diff line number Diff line Loading @@ -59,7 +59,11 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InterfaceAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.NoSuchElementException; import java.util.StringTokenizer; Loading @@ -77,6 +81,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub private static final int ADD = 1; private static final int REMOVE = 2; private static final String DEFAULT = "default"; private static final String SECONDARY = "secondary"; /** * Name representing {@link #setGlobalAlert(long)} limit when delivered to * {@link INetworkManagementEventObserver#limitReached(String, String)}. Loading Loading @@ -500,15 +507,25 @@ public class NetworkManagementService extends INetworkManagementService.Stub public void addRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, ADD, route); modifyRoute(interfaceName, ADD, route, DEFAULT); } public void removeRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, REMOVE, route); modifyRoute(interfaceName, REMOVE, route, DEFAULT); } private void modifyRoute(String interfaceName, int action, RouteInfo route) { public void addSecondaryRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, ADD, route, SECONDARY); } public void removeSecondaryRoute(String interfaceName, RouteInfo route) { mContext.enforceCallingOrSelfPermission(CHANGE_NETWORK_STATE, TAG); modifyRoute(interfaceName, REMOVE, route, SECONDARY); } private void modifyRoute(String interfaceName, int action, RouteInfo route, String type) { ArrayList<String> rsp; StringBuilder cmd; Loading @@ -516,12 +533,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub switch (action) { case ADD: { cmd = new StringBuilder("interface route add " + interfaceName); cmd = new StringBuilder("interface route add " + interfaceName + " " + type); break; } case REMOVE: { cmd = new StringBuilder("interface route remove " + interfaceName); cmd = new StringBuilder("interface route remove " + interfaceName + " " + type); break; } default: Loading Loading @@ -828,14 +845,33 @@ public class NetworkManagementService extends INetworkManagementService.Stub } } private void modifyNat(String cmd, String internalInterface, String externalInterface) throws SocketException { cmd = String.format("nat %s %s %s", cmd, internalInterface, externalInterface); NetworkInterface internalNetworkInterface = NetworkInterface.getByName(internalInterface); Collection<InterfaceAddress>interfaceAddresses = internalNetworkInterface.getInterfaceAddresses(); cmd += " " + interfaceAddresses.size(); for (InterfaceAddress ia : interfaceAddresses) { InetAddress addr = NetworkUtils.getNetworkPart(ia.getAddress(), ia.getNetworkPrefixLength()); cmd = cmd + " " + addr.getHostAddress() + "/" + ia.getNetworkPrefixLength(); } mConnector.doCommand(cmd); } public void enableNat(String internalInterface, String externalInterface) throws IllegalStateException { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); if (DBG) Log.d(TAG, "enableNat(" + internalInterface + ", " + externalInterface + ")"); try { mConnector.doCommand( String.format("nat enable %s %s", internalInterface, externalInterface)); } catch (NativeDaemonConnectorException e) { modifyNat("enable", internalInterface, externalInterface); } catch (Exception e) { Log.e(TAG, "enableNat got Exception " + e.toString()); throw new IllegalStateException( "Unable to communicate to native daemon for enabling NAT interface"); } Loading @@ -845,10 +881,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub throws IllegalStateException { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); if (DBG) Log.d(TAG, "disableNat(" + internalInterface + ", " + externalInterface + ")"); try { mConnector.doCommand( String.format("nat disable %s %s", internalInterface, externalInterface)); } catch (NativeDaemonConnectorException e) { modifyNat("disable", internalInterface, externalInterface); } catch (Exception e) { Log.e(TAG, "disableNat got Exception " + e.toString()); throw new IllegalStateException( "Unable to communicate to native daemon for disabling NAT interface"); } Loading
services/java/com/android/server/connectivity/Tethering.java +10 −14 Original line number Diff line number Diff line Loading @@ -91,6 +91,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private final INetworkManagementService mNMService; private final INetworkStatsService mStatsService; private final IConnectivityManager mConnService; private Looper mLooper; private HandlerThread mThread; Loading Loading @@ -127,10 +128,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { // when RNDIS is enabled public Tethering(Context context, INetworkManagementService nmService, INetworkStatsService statsService, Looper looper) { INetworkStatsService statsService, IConnectivityManager connService, Looper looper) { mContext = context; mNMService = nmService; mStatsService = statsService; mConnService = connService; mLooper = looper; mIfaces = new HashMap<String, TetherInterfaceSM>(); Loading Loading @@ -347,10 +349,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } private void sendTetherStateChangedBroadcast() { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); try { if (!cm.isTetheringSupported()) return; if (!mConnService.isTetheringSupported()) return; } catch (RemoteException e) { return; } Loading Loading @@ -910,6 +910,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { mNMService.tetherInterface(mIfaceName); } catch (Exception e) { Log.e(TAG, "Error Tethering: " + e.toString()); setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR); transitionTo(mInitialState); Loading Loading @@ -987,6 +988,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { try { mNMService.enableNat(mIfaceName, newUpstreamIfaceName); } catch (Exception e) { Log.e(TAG, "Exception enabling Nat: " + e.toString()); try { mNMService.untetherInterface(mIfaceName); } catch (Exception ee) {} Loading Loading @@ -1150,13 +1152,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub { boolean retValue = true; if (apnType == ConnectivityManager.TYPE_NONE) return false; if (apnType != mMobileApnReserved) turnOffUpstreamMobileConnection(); IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); int result = Phone.APN_REQUEST_FAILED; String enableString = enableString(apnType); if (enableString == null) return false; try { result = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, result = mConnService.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, enableString, new Binder()); } catch (Exception e) { } Loading @@ -1178,10 +1178,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } protected boolean turnOffUpstreamMobileConnection() { if (mMobileApnReserved != ConnectivityManager.TYPE_NONE) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); try { cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, mConnService.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, enableString(mMobileApnReserved)); } catch (Exception e) { return false; Loading Loading @@ -1234,8 +1232,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } protected void chooseUpstreamType(boolean tryCell) { IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); int upType = ConnectivityManager.TYPE_NONE; String iface = null; Loading @@ -1251,7 +1247,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { for (Integer netType : mUpstreamIfaceTypes) { NetworkInfo info = null; try { info = cm.getNetworkInfo(netType.intValue()); info = mConnService.getNetworkInfo(netType.intValue()); } catch (RemoteException e) { } if ((info != null) && info.isConnected()) { upType = netType.intValue(); Loading Loading @@ -1283,7 +1279,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } else { LinkProperties linkProperties = null; try { linkProperties = cm.getLinkProperties(upType); linkProperties = mConnService.getLinkProperties(upType); } catch (RemoteException e) { } if (linkProperties != null) iface = linkProperties.getInterfaceName(); } Loading