am 05e4dc96: am 850eb678: am eb3c0d9a: am 1aad3ad4: Merge "Fix support for simultaneous VPN tuns" into klp-dev

* commit '05e4dc96fbe47480fcd639ac679683c90ba07484':
  Fix support for simultaneous VPN tuns
This commit is contained in:
Chad Brubaker
2014-03-21 21:16:46 +00:00
committed by Android Git Automerger

View File

@ -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);
} finally {
Binder.restoreCallingIdentity(token);
}
} catch (RuntimeException e) {
updateState(DetailedState.FAILED, "establish");
IoUtils.closeQuietly(tun);
// make sure marked forwarding is cleared if it was set
try {
mCallback.clearMarkedForwarding(mInterface);
} catch (Exception ingored) {
// ignored
}
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");
// 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);
// TODO: ensure that contract class eventually marks as connected
updateState(DetailedState.AUTHENTICATING, "establish");
return tun;