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

Commit c5a10af8 authored by Yan Yan's avatar Yan Yan Committed by Automerger Merge Worker
Browse files

Merge "Use token to identify IKE Session" am: 2775f8a1 am: 86c048a4 am:...

Merge "Use token to identify IKE Session" am: 2775f8a1 am: 86c048a4 am: 5584c1c8 am: cd745de0

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2083849



Change-Id: I180fe5176a83f822590332bbe961d72a31857077
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 70cdaafd cd745de0
Loading
Loading
Loading
Loading
+86 −46
Original line number Diff line number Diff line
@@ -2593,13 +2593,13 @@ public class Vpn {

        void onDefaultNetworkLinkPropertiesChanged(@NonNull LinkProperties lp);

        void onChildOpened(
                @NonNull Network network, @NonNull ChildSessionConfiguration childConfig);
        void onDefaultNetworkLost(@NonNull Network network);

        void onChildTransformCreated(
                @NonNull Network network, @NonNull IpSecTransform transform, int direction);
        void onChildOpened(int token, @NonNull ChildSessionConfiguration childConfig);

        void onSessionLost(@NonNull Network network, @Nullable Exception exception);
        void onChildTransformCreated(int token, @NonNull IpSecTransform transform, int direction);

        void onSessionLost(int token, @Nullable Exception exception);
    }

    /**
@@ -2646,6 +2646,13 @@ public class Vpn {
        /** Signal to ensure shutdown is honored even if a new Network is connected. */
        private boolean mIsRunning = true;

        /**
         * The token used by the primary/current/active IKE session.
         *
         * <p>This token MUST be updated when the VPN switches to use a new IKE session.
         */
        private int mCurrentToken = -1;

        @Nullable private IpSecTunnelInterface mTunnelIface;
        @Nullable private IkeSession mSession;
        @Nullable private Network mActiveNetwork;
@@ -2699,22 +2706,25 @@ public class Vpn {
            return Objects.equals(mActiveNetwork, network) && mIsRunning;
        }

        private boolean isActiveToken(int token) {
            return (mCurrentToken == token) && mIsRunning;
        }

        /**
         * Called when an IKE Child session has been opened, signalling completion of the startup.
         *
         * <p>This method is only ever called once per IkeSession, and MUST run on the mExecutor
         * thread in order to ensure consistency of the Ikev2VpnRunner fields.
         */
        public void onChildOpened(
                @NonNull Network network, @NonNull ChildSessionConfiguration childConfig) {
            if (!isActiveNetwork(network)) {
                Log.d(TAG, "onOpened called for obsolete network " + network);
        public void onChildOpened(int token, @NonNull ChildSessionConfiguration childConfig) {
            if (!isActiveToken(token)) {
                Log.d(TAG, "onChildOpened called for obsolete token " + token);

                // Do nothing; this signals that either: (1) a new/better Network was found,
                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
                // IKE session was already shut down (exited, or an error was encountered somewhere
                // else). In both cases, all resources and sessions are torn down via
                // resetIkeState().
                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
                // or an error was encountered somewhere else). In both cases, all resources and
                // sessions are torn down via resetIkeState().
                return;
            }

@@ -2751,7 +2761,7 @@ public class Vpn {
                    mConfig.dnsServers.clear();
                    mConfig.dnsServers.addAll(dnsAddrStrings);

                    mConfig.underlyingNetworks = new Network[] {network};
                    mConfig.underlyingNetworks = new Network[] {mActiveNetwork};

                    mConfig.disallowedApplications = getAppExclusionList(mPackage);

@@ -2767,7 +2777,8 @@ public class Vpn {
                        return; // Link properties are already sent.
                    } else {
                        // Underlying networks also set in agentConnect()
                        networkAgent.setUnderlyingNetworks(Collections.singletonList(network));
                        networkAgent.setUnderlyingNetworks(
                                Collections.singletonList(mActiveNetwork));
                    }

                    lp = makeLinkProperties(); // Accesses VPN instance fields; must be locked
@@ -2775,8 +2786,8 @@ public class Vpn {

                networkAgent.sendLinkProperties(lp);
            } catch (Exception e) {
                Log.d(TAG, "Error in ChildOpened for network " + network, e);
                onSessionLost(network, e);
                Log.d(TAG, "Error in ChildOpened for token " + token, e);
                onSessionLost(token, e);
            }
        }

@@ -2788,15 +2799,15 @@ public class Vpn {
         * consistency of the Ikev2VpnRunner fields.
         */
        public void onChildTransformCreated(
                @NonNull Network network, @NonNull IpSecTransform transform, int direction) {
            if (!isActiveNetwork(network)) {
                Log.d(TAG, "ChildTransformCreated for obsolete network " + network);
                int token, @NonNull IpSecTransform transform, int direction) {
            if (!isActiveToken(token)) {
                Log.d(TAG, "ChildTransformCreated for obsolete token " + token);

                // Do nothing; this signals that either: (1) a new/better Network was found,
                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
                // IKE session was already shut down (exited, or an error was encountered somewhere
                // else). In both cases, all resources and sessions are torn down via
                // resetIkeState().
                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
                // or an error was encountered somewhere else). In both cases, all resources and
                // sessions are torn down via resetIkeState().
                return;
            }

@@ -2805,8 +2816,8 @@ public class Vpn {
                // them alive for us
                mIpSecManager.applyTunnelModeTransform(mTunnelIface, direction, transform);
            } catch (IOException e) {
                Log.d(TAG, "Transform application failed for network " + network, e);
                onSessionLost(network, e);
                Log.d(TAG, "Transform application failed for token " + token, e);
                onSessionLost(token, e);
            }
        }

@@ -2864,19 +2875,21 @@ public class Vpn {
                                network);
                NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());

                mSession = mIkev2SessionCreator.createIkeSession(
                final int token = ++mCurrentToken;
                mSession =
                        mIkev2SessionCreator.createIkeSession(
                                mContext,
                                ikeSessionParams,
                                childSessionParams,
                                mExecutor,
                                new VpnIkev2Utils.IkeSessionCallbackImpl(
                                TAG, IkeV2VpnRunner.this, network),
                                        TAG, IkeV2VpnRunner.this, token),
                                new VpnIkev2Utils.ChildSessionCallbackImpl(
                                TAG, IkeV2VpnRunner.this, network));
                Log.d(TAG, "Ike Session started for network " + network);
                                        TAG, IkeV2VpnRunner.this, token));
                Log.d(TAG, "IKE session started for token " + token);
            } catch (Exception e) {
                Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
                onSessionLost(network, e);
                Log.i(TAG, "Setup failed for token " + mCurrentToken + ". Aborting", e);
                onSessionLost(mCurrentToken, e);
            }
        }

@@ -2890,6 +2903,29 @@ public class Vpn {
            mUnderlyingLinkProperties = lp;
        }

        /**
         * Handles loss of the default underlying network
         *
         * <p>The Ikev2VpnRunner will kill the IKE session and reset the VPN.
         *
         * <p>This method MUST always be called on the mExecutor thread in order to ensure
         * consistency of the Ikev2VpnRunner fields.
         */
        public void onDefaultNetworkLost(@NonNull Network network) {
            if (!isActiveNetwork(network)) {
                Log.d(TAG, "onDefaultNetworkLost called for obsolete network " + network);

                // Do nothing; this signals that either: (1) a new/better Network was found,
                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
                // or an error was encountered somewhere else). In both cases, all resources and
                // sessions are torn down via resetIkeState().
                return;
            }

            handleSessionLost(null);
        }

        /** Marks the state as FAILED, and disconnects. */
        private void markFailedAndDisconnect(Exception exception) {
            synchronized (Vpn.this) {
@@ -2908,18 +2944,22 @@ public class Vpn {
         * <p>This method MUST always be called on the mExecutor thread in order to ensure
         * consistency of the Ikev2VpnRunner fields.
         */
        public void onSessionLost(@NonNull Network network, @Nullable Exception exception) {
            if (!isActiveNetwork(network)) {
                Log.d(TAG, "onSessionLost() called for obsolete network " + network);
        public void onSessionLost(int token, @Nullable Exception exception) {
            if (!isActiveToken(token)) {
                Log.d(TAG, "onSessionLost() called for obsolete token " + token);

                // Do nothing; this signals that either: (1) a new/better Network was found,
                // and the Ikev2VpnRunner has switched to it in onDefaultNetworkChanged, or (2) this
                // IKE session was already shut down (exited, or an error was encountered somewhere
                // else). In both cases, all resources and sessions are torn down via
                // onSessionLost() and resetIkeState().
                // and the Ikev2VpnRunner has switched to it by restarting a new IKE session in
                // onDefaultNetworkChanged, or (2) this IKE session was already shut down (exited,
                // or an error was encountered somewhere else). In both cases, all resources and
                // sessions are torn down via resetIkeState().
                return;
            }

            handleSessionLost(exception);
        }

        private void handleSessionLost(@Nullable Exception exception) {
            synchronized (Vpn.this) {
                if (exception instanceof IkeProtocolException) {
                    final IkeProtocolException ikeException = (IkeProtocolException) exception;
@@ -3037,7 +3077,7 @@ public class Vpn {

            // Close all obsolete state, but keep VPN alive incase a usable network comes up.
            // (Mirrors VpnService behavior)
            Log.d(TAG, "Resetting state for network: " + network);
            Log.d(TAG, "Resetting state for token: " + mCurrentToken);

            synchronized (Vpn.this) {
                // Since this method handles non-fatal errors only, set mInterface to null to
+23 −24
Original line number Diff line number Diff line
@@ -298,35 +298,35 @@ public class VpnIkev2Utils {
    static class IkeSessionCallbackImpl implements IkeSessionCallback {
        private final String mTag;
        private final Vpn.IkeV2VpnRunnerCallback mCallback;
        private final Network mNetwork;
        private final int mToken;

        IkeSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, Network network) {
        IkeSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, int token) {
            mTag = tag;
            mCallback = callback;
            mNetwork = network;
            mToken = token;
        }

        @Override
        public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
            Log.d(mTag, "IkeOpened for network " + mNetwork);
            Log.d(mTag, "IkeOpened for token " + mToken);
            // Nothing to do here.
        }

        @Override
        public void onClosed() {
            Log.d(mTag, "IkeClosed for network " + mNetwork);
            mCallback.onSessionLost(mNetwork, null); // Server requested session closure. Retry?
            Log.d(mTag, "IkeClosed for token " + mToken);
            mCallback.onSessionLost(mToken, null); // Server requested session closure. Retry?
        }

        @Override
        public void onClosedExceptionally(@NonNull IkeException exception) {
            Log.d(mTag, "IkeClosedExceptionally for network " + mNetwork, exception);
            mCallback.onSessionLost(mNetwork, exception);
            Log.d(mTag, "IkeClosedExceptionally for token " + mToken, exception);
            mCallback.onSessionLost(mToken, exception);
        }

        @Override
        public void onError(@NonNull IkeProtocolException exception) {
            Log.d(mTag, "IkeError for network " + mNetwork, exception);
            Log.d(mTag, "IkeError for token " + mToken, exception);
            // Non-fatal, log and continue.
        }
    }
@@ -334,36 +334,36 @@ public class VpnIkev2Utils {
    static class ChildSessionCallbackImpl implements ChildSessionCallback {
        private final String mTag;
        private final Vpn.IkeV2VpnRunnerCallback mCallback;
        private final Network mNetwork;
        private final int mToken;

        ChildSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, Network network) {
        ChildSessionCallbackImpl(String tag, Vpn.IkeV2VpnRunnerCallback callback, int token) {
            mTag = tag;
            mCallback = callback;
            mNetwork = network;
            mToken = token;
        }

        @Override
        public void onOpened(@NonNull ChildSessionConfiguration childConfig) {
            Log.d(mTag, "ChildOpened for network " + mNetwork);
            mCallback.onChildOpened(mNetwork, childConfig);
            Log.d(mTag, "ChildOpened for token " + mToken);
            mCallback.onChildOpened(mToken, childConfig);
        }

        @Override
        public void onClosed() {
            Log.d(mTag, "ChildClosed for network " + mNetwork);
            mCallback.onSessionLost(mNetwork, null);
            Log.d(mTag, "ChildClosed for token " + mToken);
            mCallback.onSessionLost(mToken, null);
        }

        @Override
        public void onClosedExceptionally(@NonNull IkeException exception) {
            Log.d(mTag, "ChildClosedExceptionally for network " + mNetwork, exception);
            mCallback.onSessionLost(mNetwork, exception);
            Log.d(mTag, "ChildClosedExceptionally for token " + mToken, exception);
            mCallback.onSessionLost(mToken, exception);
        }

        @Override
        public void onIpSecTransformCreated(@NonNull IpSecTransform transform, int direction) {
            Log.d(mTag, "ChildTransformCreated; Direction: " + direction + "; network " + mNetwork);
            mCallback.onChildTransformCreated(mNetwork, transform, direction);
            Log.d(mTag, "ChildTransformCreated; Direction: " + direction + "; token " + mToken);
            mCallback.onChildTransformCreated(mToken, transform, direction);
        }

        @Override
@@ -371,8 +371,7 @@ public class VpnIkev2Utils {
            // Nothing to be done; no references to the IpSecTransform are held by the
            // Ikev2VpnRunner (or this callback class), and this transform will be closed by the
            // IKE library.
            Log.d(mTag,
                    "ChildTransformDeleted; Direction: " + direction + "; for network " + mNetwork);
            Log.d(mTag, "ChildTransformDeleted; Direction: " + direction + "; for token " + mToken);
        }
    }

@@ -412,8 +411,8 @@ public class VpnIkev2Utils {

        @Override
        public void onLost(@NonNull Network network) {
            Log.d(mTag, "Tearing down; lost network: " + network);
            mExecutor.execute(() -> mCallback.onSessionLost(network, null));
            Log.d(mTag, "onLost called for network: " + network);
            mExecutor.execute(() -> mCallback.onDefaultNetworkLost(network));
        }
    }