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

Commit 850eb678 authored by Chad Brubaker's avatar Chad Brubaker Committed by Android Git Automerger
Browse files

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

* commit 'eb3c0d9a':
  Fix support for simultaneous VPN tuns
parents c7726147 eb3c0d9a
Loading
Loading
Loading
Loading
+51 −26
Original line number Original line Diff line number Diff line
@@ -352,6 +352,12 @@ public class Vpn extends BaseNetworkStateTracker {
            Binder.restoreCallingIdentity(token);
            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.
        // Configure the interface. Abort if any of these steps fails.
        ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
        ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
        try {
        try {
@@ -371,12 +377,7 @@ public class Vpn extends BaseNetworkStateTracker {
                        new UserHandle(mUserId))) {
                        new UserHandle(mUserId))) {
                throw new IllegalStateException("Cannot bind " + config.user);
                throw new IllegalStateException("Cannot bind " + config.user);
            }
            }
            if (mConnection != null) {

                mContext.unbindService(mConnection);
            }
            if (mInterface != null && !mInterface.equals(interfaze)) {
                jniReset(mInterface);
            }
            mConnection = connection;
            mConnection = connection;
            mInterface = interfaze;
            mInterface = interfaze;


@@ -385,50 +386,74 @@ public class Vpn extends BaseNetworkStateTracker {
            config.interfaze = mInterface;
            config.interfaze = mInterface;
            config.startTime = SystemClock.elapsedRealtime();
            config.startTime = SystemClock.elapsedRealtime();
            mConfig = config;
            mConfig = config;

            // Set up forwarding and DNS rules.
            // Set up forwarding and DNS rules.
            mVpnUsers = new SparseBooleanArray();
            mVpnUsers = new SparseBooleanArray();
            token = Binder.clearCallingIdentity();
            token = Binder.clearCallingIdentity();
            try {
            try {
                mCallback.setMarkedForwarding(mInterface);
                mCallback.setMarkedForwarding(mInterface);
                mCallback.setRoutes(interfaze, config.routes);
                mCallback.setRoutes(mInterface, config.routes);
                mCallback.override(mInterface, config.dnsServers, config.searchDomains);
                mCallback.override(mInterface, config.dnsServers, config.searchDomains);
                addVpnUserLocked(mUserId);
                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 {
            } finally {
                Binder.restoreCallingIdentity(token);
                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) {
        } catch (RuntimeException e) {
            updateState(DetailedState.FAILED, "establish");
            updateState(DetailedState.FAILED, "establish");
            IoUtils.closeQuietly(tun);
            IoUtils.closeQuietly(tun);
            // make sure marked forwarding is cleared if it was set
            // make sure marked forwarding is cleared if it was set
            token = Binder.clearCallingIdentity();
            try {
            try {
                mCallback.clearMarkedForwarding(mInterface);
                mCallback.clearMarkedForwarding(mInterface);
            } catch (Exception ingored) {
            } catch (Exception ingored) {
                // ignored
                // ignored
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            }
            // restore old state
            mConfig = oldConfig;
            mConnection = oldConnection;
            mVpnUsers = oldUsers;
            mInterface = oldInterface;
            throw e;
            throw e;
        }
        }
        Log.i(TAG, "Established by " + config.user + " on " + mInterface);
        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
        // TODO: ensure that contract class eventually marks as connected
        updateState(DetailedState.AUTHENTICATING, "establish");
        updateState(DetailedState.AUTHENTICATING, "establish");
        return tun;
        return tun;