diff options
| author | 2020-09-25 19:19:15 +0000 | |
|---|---|---|
| committer | 2020-09-25 19:38:39 +0000 | |
| commit | 360eba971edb645c0ba89404b4b75e33a1a6fb15 (patch) | |
| tree | d8dcbc96d80dc775f1e9b79c3cf4031d385a30b5 /services | |
| parent | 608db6dc09b6b4f2aecd5b7f0d03f37cc8fdb42f (diff) | |
Provide more feedback to Settings when sessions fail
This change updates the VPN state when IKEv2 sessions fail, and when
configuration errors occur.
Bug: 162289824
Test: Manual testing with IKEv2/PSK
Change-Id: I2e8c6f421d2898f97b0ac422b2276edf9ef923f1
Merged-In: I2e8c6f421d2898f97b0ac422b2276edf9ef923f1
(cherry picked from commit 0be82d4f4cb215e05ca62df80f6a9e652d1d1aa9)
Diffstat (limited to 'services')
| -rw-r--r-- | services/core/java/com/android/server/connectivity/Vpn.java | 62 | ||||
| -rw-r--r-- | services/core/java/com/android/server/connectivity/VpnIkev2Utils.java | 10 |
2 files changed, 57 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 1c93d4eb599b..347beab0c42f 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -77,6 +77,7 @@ import android.net.ipsec.ike.ChildSessionParams; import android.net.ipsec.ike.IkeSession; import android.net.ipsec.ike.IkeSessionCallback; import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.exceptions.IkeProtocolException; import android.os.Binder; import android.os.Build.VERSION_CODES; import android.os.Bundle; @@ -142,6 +143,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.atomic.AtomicInteger; /** @@ -2300,7 +2302,7 @@ public class Vpn { void onChildTransformCreated( @NonNull Network network, @NonNull IpSecTransform transform, int direction); - void onSessionLost(@NonNull Network network); + void onSessionLost(@NonNull Network network, @Nullable Exception exception); } /** @@ -2457,7 +2459,7 @@ public class Vpn { networkAgent.sendLinkProperties(lp); } catch (Exception e) { Log.d(TAG, "Error in ChildOpened for network " + network, e); - onSessionLost(network); + onSessionLost(network, e); } } @@ -2487,7 +2489,7 @@ public class Vpn { mIpSecManager.applyTunnelModeTransform(mTunnelIface, direction, transform); } catch (IOException e) { Log.d(TAG, "Transform application failed for network " + network, e); - onSessionLost(network); + onSessionLost(network, e); } } @@ -2545,11 +2547,20 @@ public class Vpn { Log.d(TAG, "Ike Session started for network " + network); } catch (Exception e) { Log.i(TAG, "Setup failed for network " + network + ". Aborting", e); - onSessionLost(network); + onSessionLost(network, e); } }); } + /** Marks the state as FAILED, and disconnects. */ + private void markFailedAndDisconnect(Exception exception) { + synchronized (Vpn.this) { + updateState(DetailedState.FAILED, exception.getMessage()); + } + + disconnectVpnRunner(); + } + /** * Handles loss of a session * @@ -2559,7 +2570,7 @@ 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) { + public void onSessionLost(@NonNull Network network, @Nullable Exception exception) { if (!isActiveNetwork(network)) { Log.d(TAG, "onSessionLost() called for obsolete network " + network); @@ -2571,6 +2582,27 @@ public class Vpn { return; } + if (exception instanceof IkeProtocolException) { + final IkeProtocolException ikeException = (IkeProtocolException) exception; + + switch (ikeException.getErrorType()) { + case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough + case IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD: // Fallthrough + case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED: // Fallthrough + case IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED: // Fallthrough + case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough + case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE: + // All the above failures are configuration errors, and are terminal + markFailedAndDisconnect(exception); + return; + // All other cases possibly recoverable. + } + } else if (exception instanceof IllegalArgumentException) { + // Failed to build IKE/ChildSessionParams; fatal profile configuration error + markFailedAndDisconnect(exception); + return; + } + mActiveNetwork = null; // Close all obsolete state, but keep VPN alive incase a usable network comes up. @@ -2620,12 +2652,18 @@ public class Vpn { } /** - * Cleans up all Ikev2VpnRunner internal state + * Disconnects and shuts down this VPN. + * + * <p>This method resets all internal Ikev2VpnRunner state, but unless called via + * VpnRunner#exit(), this Ikev2VpnRunner will still be listed as the active VPN of record + * until the next VPN is started, or the Ikev2VpnRunner is explicitly exited. This is + * necessary to ensure that the detailed state is shown in the Settings VPN menus; if the + * active VPN is cleared, Settings VPNs will not show the resultant state or errors. * * <p>This method MUST always be called on the mExecutor thread in order to ensure * consistency of the Ikev2VpnRunner fields. */ - private void shutdownVpnRunner() { + private void disconnectVpnRunner() { mActiveNetwork = null; mIsRunning = false; @@ -2639,9 +2677,13 @@ public class Vpn { @Override public void exitVpnRunner() { - mExecutor.execute(() -> { - shutdownVpnRunner(); - }); + try { + mExecutor.execute(() -> { + disconnectVpnRunner(); + }); + } catch (RejectedExecutionException ignored) { + // The Ikev2VpnRunner has already shut down. + } } } diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java index 103f659cc258..626303001ba0 100644 --- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java +++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java @@ -270,13 +270,13 @@ public class VpnIkev2Utils { @Override public void onClosed() { Log.d(mTag, "IkeClosed for network " + mNetwork); - mCallback.onSessionLost(mNetwork); // Server requested session closure. Retry? + mCallback.onSessionLost(mNetwork, null); // Server requested session closure. Retry? } @Override public void onClosedExceptionally(@NonNull IkeException exception) { Log.d(mTag, "IkeClosedExceptionally for network " + mNetwork, exception); - mCallback.onSessionLost(mNetwork); + mCallback.onSessionLost(mNetwork, exception); } @Override @@ -306,13 +306,13 @@ public class VpnIkev2Utils { @Override public void onClosed() { Log.d(mTag, "ChildClosed for network " + mNetwork); - mCallback.onSessionLost(mNetwork); + mCallback.onSessionLost(mNetwork, null); } @Override public void onClosedExceptionally(@NonNull IkeException exception) { Log.d(mTag, "ChildClosedExceptionally for network " + mNetwork, exception); - mCallback.onSessionLost(mNetwork); + mCallback.onSessionLost(mNetwork, exception); } @Override @@ -349,7 +349,7 @@ public class VpnIkev2Utils { @Override public void onLost(@NonNull Network network) { Log.d(mTag, "Tearing down; lost network: " + network); - mCallback.onSessionLost(network); + mCallback.onSessionLost(network, null); } } |