Loading core/java/com/android/internal/net/VpnConfig.java +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ public class VpnConfig implements Parcelable { public static final String DIALOGS_PACKAGE = "com.android.vpndialogs"; // TODO: Rename this to something that encompasses Settings-based Platform VPNs as well. public static final String LEGACY_VPN = "[Legacy VPN]"; public static Intent getIntentForConfirmation() { Loading services/core/java/com/android/server/connectivity/Vpn.java +92 −23 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.INetworkManagementEventObserver; import android.net.IpPrefix; import android.net.IpSecManager; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.LocalSocket; Loading Loading @@ -180,7 +181,10 @@ public class Vpn { private boolean mIsPackageTargetingAtLeastQ; private String mInterface; private Connection mConnection; private LegacyVpnRunner mLegacyVpnRunner; /** Tracks the runners for all VPN types managed by the platform (eg. LegacyVpn, PlatformVpn) */ private VpnRunner mVpnRunner; private PendingIntent mStatusIntent; private volatile boolean mEnableTeardown = true; private final INetworkManagementService mNetd; Loading Loading @@ -762,7 +766,7 @@ public class Vpn { mNetworkCapabilities.setUids(null); } // Revoke the connection or stop LegacyVpnRunner. // Revoke the connection or stop the VpnRunner. if (mConnection != null) { try { mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION, Loading @@ -772,9 +776,9 @@ public class Vpn { } mContext.unbindService(mConnection); mConnection = null; } else if (mLegacyVpnRunner != null) { mLegacyVpnRunner.exit(); mLegacyVpnRunner = null; } else if (mVpnRunner != null) { mVpnRunner.exit(); mVpnRunner = null; } try { Loading Loading @@ -1506,8 +1510,8 @@ public class Vpn { @Override public void interfaceStatusChanged(String interfaze, boolean up) { synchronized (Vpn.this) { if (!up && mLegacyVpnRunner != null) { mLegacyVpnRunner.check(interfaze); if (!up && mVpnRunner != null && mVpnRunner instanceof LegacyVpnRunner) { ((LegacyVpnRunner) mVpnRunner).exitIfOuterInterfaceIs(interfaze); } } } Loading @@ -1524,9 +1528,10 @@ public class Vpn { mContext.unbindService(mConnection); mConnection = null; agentDisconnect(); } else if (mLegacyVpnRunner != null) { mLegacyVpnRunner.exit(); mLegacyVpnRunner = null; } else if (mVpnRunner != null) { // agentDisconnect must be called from mVpnRunner.exit() mVpnRunner.exit(); mVpnRunner = null; } } } Loading Loading @@ -1909,23 +1914,40 @@ public class Vpn { private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd, VpnProfile profile) { stopLegacyVpnPrivileged(); stopVpnRunnerPrivileged(); // Prepare for the new request. prepareInternal(VpnConfig.LEGACY_VPN); updateState(DetailedState.CONNECTING, "startLegacyVpn"); // Start a new LegacyVpnRunner and we are done! mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd, profile); mLegacyVpnRunner.start(); mVpnRunner = new LegacyVpnRunner(config, racoon, mtpd, profile); mVpnRunner.start(); } /** * Checks if this the currently running VPN (if any) was started by the Settings app * * <p>This includes both Legacy VPNs and Platform VPNs. */ private boolean isSettingsVpnLocked() { return mVpnRunner != null && VpnConfig.LEGACY_VPN.equals(mPackage); } /** Stop VPN runner. Permissions must be checked by callers. */ public synchronized void stopVpnRunnerPrivileged() { if (!isSettingsVpnLocked()) { return; } /** Stop legacy VPN. Permissions must be checked by callers. */ public synchronized void stopLegacyVpnPrivileged() { if (mLegacyVpnRunner != null) { mLegacyVpnRunner.exit(); mLegacyVpnRunner = null; final boolean isLegacyVpn = mVpnRunner instanceof LegacyVpnRunner; mVpnRunner.exit(); mVpnRunner = null; // LegacyVpn uses daemons that must be shut down before new ones are brought up. // The same limitation does not apply to Platform VPNs. if (isLegacyVpn) { synchronized (LegacyVpnRunner.TAG) { // wait for old thread to completely finish before spinning up // new instance, otherwise state updates can be out of order. Loading @@ -1947,7 +1969,7 @@ public class Vpn { * Callers are responsible for checking permissions if needed. */ private synchronized LegacyVpnInfo getLegacyVpnInfoPrivileged() { if (mLegacyVpnRunner == null) return null; if (!isSettingsVpnLocked()) return null; final LegacyVpnInfo info = new LegacyVpnInfo(); info.key = mConfig.user; Loading @@ -1958,14 +1980,53 @@ public class Vpn { return info; } public VpnConfig getLegacyVpnConfig() { if (mLegacyVpnRunner != null) { public synchronized VpnConfig getLegacyVpnConfig() { if (isSettingsVpnLocked()) { return mConfig; } else { return null; } } /** This class represents the common interface for all VPN runners. */ private abstract class VpnRunner extends Thread { protected VpnRunner(String name) { super(name); } public abstract void run(); protected abstract void exit(); } private class IkeV2VpnRunner extends VpnRunner { private static final String TAG = "IkeV2VpnRunner"; private final IpSecManager mIpSecManager; private final VpnProfile mProfile; IkeV2VpnRunner(VpnProfile profile) { super(TAG); mProfile = profile; // TODO: move this to startVpnRunnerPrivileged() mConfig = new VpnConfig(); mIpSecManager = mContext.getSystemService(IpSecManager.class); } @Override public void run() { // TODO: Build IKE config, start IKE session } @Override public void exit() { // TODO: Teardown IKE session & any resources. agentDisconnect(); } } /** * Bringing up a VPN connection takes time, and that is all this thread * does. Here we have plenty of time. The only thing we need to take Loading @@ -1973,7 +2034,7 @@ public class Vpn { * requests will pile up. This could be done in a Handler as a state * machine, but it is much easier to read in the current form. */ private class LegacyVpnRunner extends Thread { private class LegacyVpnRunner extends VpnRunner { private static final String TAG = "LegacyVpnRunner"; private final String[] mDaemons; Loading Loading @@ -2043,13 +2104,21 @@ public class Vpn { mContext.registerReceiver(mBroadcastReceiver, filter); } public void check(String interfaze) { /** * Checks if the parameter matches the underlying interface * * <p>If the underlying interface is torn down, the LegacyVpnRunner also should be. It has * no ability to migrate between interfaces (or Networks). */ public void exitIfOuterInterfaceIs(String interfaze) { if (interfaze.equals(mOuterInterface)) { Log.i(TAG, "Legacy VPN is going down with " + interfaze); exit(); } } /** Tears down this LegacyVpn connection */ @Override public void exit() { // We assume that everything is reset after stopping the daemons. interrupt(); Loading services/core/java/com/android/server/net/LockdownVpnTracker.java +2 −2 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ public class LockdownVpnTracker { if (egressDisconnected || egressChanged) { mAcceptedEgressIface = null; mVpn.stopLegacyVpnPrivileged(); mVpn.stopVpnRunnerPrivileged(); } if (egressDisconnected) { hideNotification(); Loading Loading @@ -218,7 +218,7 @@ public class LockdownVpnTracker { mAcceptedEgressIface = null; mErrorCount = 0; mVpn.stopLegacyVpnPrivileged(); mVpn.stopVpnRunnerPrivileged(); mVpn.setLockdown(false); hideNotification(); Loading Loading
core/java/com/android/internal/net/VpnConfig.java +1 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ public class VpnConfig implements Parcelable { public static final String DIALOGS_PACKAGE = "com.android.vpndialogs"; // TODO: Rename this to something that encompasses Settings-based Platform VPNs as well. public static final String LEGACY_VPN = "[Legacy VPN]"; public static Intent getIntentForConfirmation() { Loading
services/core/java/com/android/server/connectivity/Vpn.java +92 −23 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.INetworkManagementEventObserver; import android.net.IpPrefix; import android.net.IpSecManager; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.LocalSocket; Loading Loading @@ -180,7 +181,10 @@ public class Vpn { private boolean mIsPackageTargetingAtLeastQ; private String mInterface; private Connection mConnection; private LegacyVpnRunner mLegacyVpnRunner; /** Tracks the runners for all VPN types managed by the platform (eg. LegacyVpn, PlatformVpn) */ private VpnRunner mVpnRunner; private PendingIntent mStatusIntent; private volatile boolean mEnableTeardown = true; private final INetworkManagementService mNetd; Loading Loading @@ -762,7 +766,7 @@ public class Vpn { mNetworkCapabilities.setUids(null); } // Revoke the connection or stop LegacyVpnRunner. // Revoke the connection or stop the VpnRunner. if (mConnection != null) { try { mConnection.mService.transact(IBinder.LAST_CALL_TRANSACTION, Loading @@ -772,9 +776,9 @@ public class Vpn { } mContext.unbindService(mConnection); mConnection = null; } else if (mLegacyVpnRunner != null) { mLegacyVpnRunner.exit(); mLegacyVpnRunner = null; } else if (mVpnRunner != null) { mVpnRunner.exit(); mVpnRunner = null; } try { Loading Loading @@ -1506,8 +1510,8 @@ public class Vpn { @Override public void interfaceStatusChanged(String interfaze, boolean up) { synchronized (Vpn.this) { if (!up && mLegacyVpnRunner != null) { mLegacyVpnRunner.check(interfaze); if (!up && mVpnRunner != null && mVpnRunner instanceof LegacyVpnRunner) { ((LegacyVpnRunner) mVpnRunner).exitIfOuterInterfaceIs(interfaze); } } } Loading @@ -1524,9 +1528,10 @@ public class Vpn { mContext.unbindService(mConnection); mConnection = null; agentDisconnect(); } else if (mLegacyVpnRunner != null) { mLegacyVpnRunner.exit(); mLegacyVpnRunner = null; } else if (mVpnRunner != null) { // agentDisconnect must be called from mVpnRunner.exit() mVpnRunner.exit(); mVpnRunner = null; } } } Loading Loading @@ -1909,23 +1914,40 @@ public class Vpn { private synchronized void startLegacyVpn(VpnConfig config, String[] racoon, String[] mtpd, VpnProfile profile) { stopLegacyVpnPrivileged(); stopVpnRunnerPrivileged(); // Prepare for the new request. prepareInternal(VpnConfig.LEGACY_VPN); updateState(DetailedState.CONNECTING, "startLegacyVpn"); // Start a new LegacyVpnRunner and we are done! mLegacyVpnRunner = new LegacyVpnRunner(config, racoon, mtpd, profile); mLegacyVpnRunner.start(); mVpnRunner = new LegacyVpnRunner(config, racoon, mtpd, profile); mVpnRunner.start(); } /** * Checks if this the currently running VPN (if any) was started by the Settings app * * <p>This includes both Legacy VPNs and Platform VPNs. */ private boolean isSettingsVpnLocked() { return mVpnRunner != null && VpnConfig.LEGACY_VPN.equals(mPackage); } /** Stop VPN runner. Permissions must be checked by callers. */ public synchronized void stopVpnRunnerPrivileged() { if (!isSettingsVpnLocked()) { return; } /** Stop legacy VPN. Permissions must be checked by callers. */ public synchronized void stopLegacyVpnPrivileged() { if (mLegacyVpnRunner != null) { mLegacyVpnRunner.exit(); mLegacyVpnRunner = null; final boolean isLegacyVpn = mVpnRunner instanceof LegacyVpnRunner; mVpnRunner.exit(); mVpnRunner = null; // LegacyVpn uses daemons that must be shut down before new ones are brought up. // The same limitation does not apply to Platform VPNs. if (isLegacyVpn) { synchronized (LegacyVpnRunner.TAG) { // wait for old thread to completely finish before spinning up // new instance, otherwise state updates can be out of order. Loading @@ -1947,7 +1969,7 @@ public class Vpn { * Callers are responsible for checking permissions if needed. */ private synchronized LegacyVpnInfo getLegacyVpnInfoPrivileged() { if (mLegacyVpnRunner == null) return null; if (!isSettingsVpnLocked()) return null; final LegacyVpnInfo info = new LegacyVpnInfo(); info.key = mConfig.user; Loading @@ -1958,14 +1980,53 @@ public class Vpn { return info; } public VpnConfig getLegacyVpnConfig() { if (mLegacyVpnRunner != null) { public synchronized VpnConfig getLegacyVpnConfig() { if (isSettingsVpnLocked()) { return mConfig; } else { return null; } } /** This class represents the common interface for all VPN runners. */ private abstract class VpnRunner extends Thread { protected VpnRunner(String name) { super(name); } public abstract void run(); protected abstract void exit(); } private class IkeV2VpnRunner extends VpnRunner { private static final String TAG = "IkeV2VpnRunner"; private final IpSecManager mIpSecManager; private final VpnProfile mProfile; IkeV2VpnRunner(VpnProfile profile) { super(TAG); mProfile = profile; // TODO: move this to startVpnRunnerPrivileged() mConfig = new VpnConfig(); mIpSecManager = mContext.getSystemService(IpSecManager.class); } @Override public void run() { // TODO: Build IKE config, start IKE session } @Override public void exit() { // TODO: Teardown IKE session & any resources. agentDisconnect(); } } /** * Bringing up a VPN connection takes time, and that is all this thread * does. Here we have plenty of time. The only thing we need to take Loading @@ -1973,7 +2034,7 @@ public class Vpn { * requests will pile up. This could be done in a Handler as a state * machine, but it is much easier to read in the current form. */ private class LegacyVpnRunner extends Thread { private class LegacyVpnRunner extends VpnRunner { private static final String TAG = "LegacyVpnRunner"; private final String[] mDaemons; Loading Loading @@ -2043,13 +2104,21 @@ public class Vpn { mContext.registerReceiver(mBroadcastReceiver, filter); } public void check(String interfaze) { /** * Checks if the parameter matches the underlying interface * * <p>If the underlying interface is torn down, the LegacyVpnRunner also should be. It has * no ability to migrate between interfaces (or Networks). */ public void exitIfOuterInterfaceIs(String interfaze) { if (interfaze.equals(mOuterInterface)) { Log.i(TAG, "Legacy VPN is going down with " + interfaze); exit(); } } /** Tears down this LegacyVpn connection */ @Override public void exit() { // We assume that everything is reset after stopping the daemons. interrupt(); Loading
services/core/java/com/android/server/net/LockdownVpnTracker.java +2 −2 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ public class LockdownVpnTracker { if (egressDisconnected || egressChanged) { mAcceptedEgressIface = null; mVpn.stopLegacyVpnPrivileged(); mVpn.stopVpnRunnerPrivileged(); } if (egressDisconnected) { hideNotification(); Loading Loading @@ -218,7 +218,7 @@ public class LockdownVpnTracker { mAcceptedEgressIface = null; mErrorCount = 0; mVpn.stopLegacyVpnPrivileged(); mVpn.stopVpnRunnerPrivileged(); mVpn.setLockdown(false); hideNotification(); Loading