diff options
author | Chad Brubaker <cbrubaker@google.com> | 2014-03-21 23:09:24 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-03-21 23:09:24 +0000 |
commit | ecdbb6a5a325d43c61e2d31f6f69fe9f56752962 (patch) | |
tree | 6de27c86ab3faa2aaed61c40edc5cb2d86b84d8b /services/java | |
parent | aa5a99b3b8655f0d092f76fe97a33b477da5262b (diff) | |
parent | eb3c0d9ac387bb0aea5b4956daac1403253bc76d (diff) | |
download | frameworks_base-ecdbb6a5a325d43c61e2d31f6f69fe9f56752962.zip frameworks_base-ecdbb6a5a325d43c61e2d31f6f69fe9f56752962.tar.gz frameworks_base-ecdbb6a5a325d43c61e2d31f6f69fe9f56752962.tar.bz2 |
am eb3c0d9a: am 1aad3ad4: Merge "Fix support for simultaneous VPN tuns" into klp-dev
* commit 'eb3c0d9ac387bb0aea5b4956daac1403253bc76d':
Fix support for simultaneous VPN tuns
Diffstat (limited to 'services/java')
-rw-r--r-- | services/java/com/android/server/connectivity/Vpn.java | 77 |
1 files changed, 51 insertions, 26 deletions
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java index 0a58552..376414b 100644 --- a/services/java/com/android/server/connectivity/Vpn.java +++ b/services/java/com/android/server/connectivity/Vpn.java @@ -352,6 +352,12 @@ public class Vpn extends BaseNetworkStateTracker { Binder.restoreCallingIdentity(token); } + // Save the old config in case we need to go back. + VpnConfig oldConfig = mConfig; + String oldInterface = mInterface; + Connection oldConnection = mConnection; + SparseBooleanArray oldUsers = mVpnUsers; + // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); try { @@ -371,12 +377,7 @@ public class Vpn extends BaseNetworkStateTracker { new UserHandle(mUserId))) { throw new IllegalStateException("Cannot bind " + config.user); } - if (mConnection != null) { - mContext.unbindService(mConnection); - } - if (mInterface != null && !mInterface.equals(interfaze)) { - jniReset(mInterface); - } + mConnection = connection; mInterface = interfaze; @@ -385,50 +386,74 @@ public class Vpn extends BaseNetworkStateTracker { config.interfaze = mInterface; config.startTime = SystemClock.elapsedRealtime(); mConfig = config; + // Set up forwarding and DNS rules. mVpnUsers = new SparseBooleanArray(); token = Binder.clearCallingIdentity(); try { mCallback.setMarkedForwarding(mInterface); - mCallback.setRoutes(interfaze, config.routes); + mCallback.setRoutes(mInterface, config.routes); mCallback.override(mInterface, config.dnsServers, config.searchDomains); addVpnUserLocked(mUserId); - + // If we are owner assign all Restricted Users to this VPN + if (mUserId == UserHandle.USER_OWNER) { + for (UserInfo user : mgr.getUsers()) { + if (user.isRestricted()) { + try { + addVpnUserLocked(user.id); + } catch (Exception e) { + Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); + } + } + } + } } finally { Binder.restoreCallingIdentity(token); } + if (oldConnection != null) { + mContext.unbindService(oldConnection); + } + if (oldInterface != null && !oldInterface.equals(interfaze)) { + // Remove the old tun's user forwarding rules + // The new tun's user rules have already been added so they will take over + // as rules are deleted. This prevents data leakage as the rules are moved over. + token = Binder.clearCallingIdentity(); + try { + final int size = oldUsers.size(); + final boolean forwardDns = (oldConfig.dnsServers != null && + oldConfig.dnsServers.size() != 0); + for (int i = 0; i < size; i++) { + int user = oldUsers.keyAt(i); + mCallback.clearUserForwarding(oldInterface, user, forwardDns); + } + mCallback.clearMarkedForwarding(oldInterface); + } finally { + Binder.restoreCallingIdentity(token); + } + jniReset(oldInterface); + } } catch (RuntimeException e) { updateState(DetailedState.FAILED, "establish"); IoUtils.closeQuietly(tun); // make sure marked forwarding is cleared if it was set + token = Binder.clearCallingIdentity(); try { mCallback.clearMarkedForwarding(mInterface); } catch (Exception ingored) { // ignored + } finally { + Binder.restoreCallingIdentity(token); } + // restore old state + mConfig = oldConfig; + mConnection = oldConnection; + mVpnUsers = oldUsers; + mInterface = oldInterface; throw e; } Log.i(TAG, "Established by " + config.user + " on " + mInterface); - - // If we are owner assign all Restricted Users to this VPN - if (mUserId == UserHandle.USER_OWNER) { - token = Binder.clearCallingIdentity(); - try { - for (UserInfo user : mgr.getUsers()) { - if (user.isRestricted()) { - try { - addVpnUserLocked(user.id); - } catch (Exception e) { - Log.wtf(TAG, "Failed to add user " + user.id + " to owner's VPN"); - } - } - } - } finally { - Binder.restoreCallingIdentity(token); - } - } // TODO: ensure that contract class eventually marks as connected updateState(DetailedState.AUTHENTICATING, "establish"); return tun; |