diff options
| author | 2023-07-04 11:32:05 +0000 | |
|---|---|---|
| committer | 2023-07-04 11:32:05 +0000 | |
| commit | 8d684dbd8da29f331730cba9b3b513930b82120d (patch) | |
| tree | 7671049c06d7f1a73b33e96782025adbe85d8c69 | |
| parent | 3367272599bf301886b71432db0958473dfec885 (diff) | |
| parent | afbda8694b16eabb101dc77bac6f55e017075a4a (diff) | |
Perform VPN data stall recovery on unvalidated VPN network am: b4f300d70d am: 837c8f6729 am: 98c786248f am: afbda8694b
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2643292
Change-Id: I643e44ae932c2a2f21c88c40e56a6ae834e88cf9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | services/core/java/com/android/server/connectivity/Vpn.java | 93 |
1 files changed, 37 insertions, 56 deletions
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 6b69e1caa985..0786411695b0 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -22,7 +22,6 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; -import static android.net.NetworkCapabilities.TRANSPORT_VPN; import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN; @@ -280,15 +279,22 @@ public class Vpn { private static final int VPN_DEFAULT_SCORE = 101; /** - * The reset session timer for data stall. If a session has not successfully revalidated after - * the delay, the session will be torn down and restarted in an attempt to recover. Delay + * The recovery timer for data stall. If a session has not successfully revalidated after + * the delay, the session will perform MOBIKE or be restarted in an attempt to recover. Delay * counter is reset on successful validation only. * + * <p>The first {@code MOBIKE_RECOVERY_ATTEMPT} timers are used for performing MOBIKE. + * System will perform session reset for the remaining timers. * <p>If retries have exceeded the length of this array, the last entry in the array will be * used as a repeating interval. */ - private static final long[] DATA_STALL_RESET_DELAYS_SEC = {30L, 60L, 120L, 240L, 480L, 960L}; - + // TODO: use ms instead to speed up the test. + private static final long[] DATA_STALL_RECOVERY_DELAYS_SEC = + {1L, 5L, 30L, 60L, 120L, 240L, 480L, 960L}; + /** + * Maximum attempts to perform MOBIKE when the network is bad. + */ + private static final int MAX_MOBIKE_RECOVERY_ATTEMPT = 2; /** * The initial token value of IKE session. */ @@ -392,7 +398,6 @@ public class Vpn { private final UserManager mUserManager; private final VpnProfileStore mVpnProfileStore; - protected boolean mDataStallSuspected = false; @VisibleForTesting VpnProfileStore getVpnProfileStore() { @@ -685,14 +690,14 @@ public class Vpn { } /** - * Get the length of time to wait before resetting the ike session when a data stall is - * suspected. + * Get the length of time to wait before perform data stall recovery when the validation + * result is bad. */ - public long getDataStallResetSessionSeconds(int count) { - if (count >= DATA_STALL_RESET_DELAYS_SEC.length) { - return DATA_STALL_RESET_DELAYS_SEC[DATA_STALL_RESET_DELAYS_SEC.length - 1]; + public long getValidationFailRecoverySeconds(int count) { + if (count >= DATA_STALL_RECOVERY_DELAYS_SEC.length) { + return DATA_STALL_RECOVERY_DELAYS_SEC[DATA_STALL_RECOVERY_DELAYS_SEC.length - 1]; } else { - return DATA_STALL_RESET_DELAYS_SEC[count]; + return DATA_STALL_RECOVERY_DELAYS_SEC[count]; } } @@ -3044,7 +3049,6 @@ public class Vpn { @Nullable private IkeSessionWrapper mSession; @Nullable private IkeSessionConnectionInfo mIkeConnectionInfo; - @Nullable private VpnConnectivityDiagnosticsCallback mDiagnosticsCallback; // mMobikeEnabled can only be updated after IKE AUTH is finished. private boolean mMobikeEnabled = false; @@ -3055,7 +3059,7 @@ public class Vpn { * <p>This variable controls the retry delay, and is reset when the VPN pass network * validation. */ - private int mDataStallRetryCount = 0; + private int mValidationFailRetryCount = 0; /** * The number of attempts since the last successful connection. @@ -3136,15 +3140,6 @@ public class Vpn { mConnectivityManager.registerSystemDefaultNetworkCallback(mNetworkCallback, new Handler(mLooper)); } - - // DiagnosticsCallback may return more than one alive VPNs, but VPN will filter based on - // Network object. - final NetworkRequest diagRequest = new NetworkRequest.Builder() - .addTransportType(TRANSPORT_VPN) - .removeCapability(NET_CAPABILITY_NOT_VPN).build(); - mDiagnosticsCallback = new VpnConnectivityDiagnosticsCallback(); - mConnectivityDiagnosticsManager.registerConnectivityDiagnosticsCallback( - diagRequest, mExecutor, mDiagnosticsCallback); } private boolean isActiveNetwork(@Nullable Network network) { @@ -3875,39 +3870,12 @@ public class Vpn { } } - class VpnConnectivityDiagnosticsCallback - extends ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback { - // The callback runs in the executor thread. - @Override - public void onDataStallSuspected( - ConnectivityDiagnosticsManager.DataStallReport report) { - synchronized (Vpn.this) { - // Ignore stale runner. - if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return; - - // Handle the report only for current VPN network. If data stall is already - // reported, ignoring the other reports. It means that the stall is not - // recovered by MOBIKE and should be on the way to reset the ike session. - if (mNetworkAgent != null - && mNetworkAgent.getNetwork().equals(report.getNetwork()) - && !mDataStallSuspected) { - Log.d(TAG, "Data stall suspected"); - - // Trigger MOBIKE. - maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); - mDataStallSuspected = true; - } - } - } - } - public void onValidationStatus(int status) { mEventChanges.log("[Validation] validation status " + status); if (status == NetworkAgent.VALIDATION_STATUS_VALID) { // No data stall now. Reset it. mExecutor.execute(() -> { - mDataStallSuspected = false; - mDataStallRetryCount = 0; + mValidationFailRetryCount = 0; if (mScheduledHandleDataStallFuture != null) { Log.d(TAG, "Recovered from stall. Cancel pending reset action."); mScheduledHandleDataStallFuture.cancel(false /* mayInterruptIfRunning */); @@ -3918,8 +3886,21 @@ public class Vpn { // Skip other invalid status if the scheduled recovery exists. if (mScheduledHandleDataStallFuture != null) return; + if (mValidationFailRetryCount < MAX_MOBIKE_RECOVERY_ATTEMPT) { + Log.d(TAG, "Validation failed"); + + // Trigger MOBIKE to recover first. + mExecutor.schedule(() -> { + maybeMigrateIkeSessionAndUpdateVpnTransportInfo(mActiveNetwork); + }, mDeps.getValidationFailRecoverySeconds(mValidationFailRetryCount++), + TimeUnit.SECONDS); + return; + } + + // Data stall is not recovered by MOBIKE. Try to reset session to recover it. mScheduledHandleDataStallFuture = mExecutor.schedule(() -> { - if (mDataStallSuspected) { + // Only perform the recovery when the network is still bad. + if (mValidationFailRetryCount > 0) { Log.d(TAG, "Reset session to recover stalled network"); // This will reset old state if it exists. startIkeSession(mActiveNetwork); @@ -3928,7 +3909,9 @@ public class Vpn { // Reset mScheduledHandleDataStallFuture since it's already run on executor // thread. mScheduledHandleDataStallFuture = null; - }, mDeps.getDataStallResetSessionSeconds(mDataStallRetryCount++), TimeUnit.SECONDS); + // TODO: compute the delay based on the last recovery timestamp + }, mDeps.getValidationFailRecoverySeconds(mValidationFailRetryCount++), + TimeUnit.SECONDS); } } @@ -4231,8 +4214,6 @@ public class Vpn { mCarrierConfigManager.unregisterCarrierConfigChangeListener( mCarrierConfigChangeListener); mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); - mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback( - mDiagnosticsCallback); clearVpnNetworkPreference(mSessionKey); mExecutor.shutdown(); @@ -5216,7 +5197,7 @@ public class Vpn { pw.println("MOBIKE " + (runner.mMobikeEnabled ? "enabled" : "disabled")); pw.println("Profile: " + runner.mProfile); pw.println("Token: " + runner.mCurrentToken); - if (mDataStallSuspected) pw.println("Data stall suspected"); + pw.println("Validation failed retry count:" + runner.mValidationFailRetryCount); if (runner.mScheduledHandleDataStallFuture != null) { pw.println("Reset session scheduled"); } |