summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chiachang Wang <chiachangwang@google.com> 2022-10-12 14:34:59 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2022-10-12 14:34:59 +0000
commitbf20b85b3130cff17e82ab8de96022ae4f4ac699 (patch)
tree0d4b07c28024f5ede50304e929c749265c79ecfe
parent172e2c5a3160e0ed1d9676b98b3d28a8eae6d964 (diff)
parent97db242349add4293520db6e73259a6422a1e309 (diff)
Merge "Perform MOBIKE when data stall is suspected" am: 97db242349
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2171149 Change-Id: I5490b3e29c79e4ef83ff8229a7be084433873d90 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.java73
1 files changed, 59 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 6a53978175af..6795b6b4158d 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -21,6 +21,7 @@ import static android.Manifest.permission.CONTROL_VPN;
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_VPN;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
@@ -51,6 +52,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
+import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.DnsResolver;
import android.net.INetd;
@@ -234,6 +236,7 @@ public class Vpn {
private final Context mContext;
private final ConnectivityManager mConnectivityManager;
private final AppOpsManager mAppOpsManager;
+ private final ConnectivityDiagnosticsManager mConnectivityDiagnosticsManager;
// The context is for specific user which is created from mUserId
private final Context mUserIdContext;
@VisibleForTesting final Dependencies mDeps;
@@ -549,6 +552,8 @@ public class Vpn {
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
+ mConnectivityDiagnosticsManager =
+ mContext.getSystemService(ConnectivityDiagnosticsManager.class);
mDeps = deps;
mNms = netService;
mNetd = netd;
@@ -2739,6 +2744,7 @@ 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;
@@ -2797,6 +2803,15 @@ 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) {
@@ -3066,22 +3081,28 @@ public class Vpn {
return;
}
- try {
- if (mSession != null && mMobikeEnabled) {
- // IKE session can schedule a migration event only when IKE AUTH is finished
- // and mMobikeEnabled is true.
- Log.d(
- TAG,
- "Migrate IKE Session with token "
- + mCurrentToken
- + " to network "
- + underlyingNetwork);
- mSession.setNetwork(underlyingNetwork);
- return;
- }
+ if (maybeMigrateIkeSession(underlyingNetwork)) return;
+
+ startIkeSession(underlyingNetwork);
+ }
- Log.d(TAG, "Start new IKE session on network " + underlyingNetwork);
+ boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
+ if (mSession == null || !mMobikeEnabled) return false;
+ // IKE session can schedule a migration event only when IKE AUTH is finished
+ // and mMobikeEnabled is true.
+ Log.d(TAG, "Migrate IKE Session with token "
+ + mCurrentToken
+ + " to network "
+ + underlyingNetwork);
+ mSession.setNetwork(underlyingNetwork);
+ return true;
+ }
+
+ private void startIkeSession(@NonNull Network underlyingNetwork) {
+ Log.d(TAG, "Start new IKE session on network " + underlyingNetwork);
+
+ try {
// Clear mInterface to prevent Ikev2VpnRunner being cleared when
// interfaceRemoved() is called.
synchronized (Vpn.this) {
@@ -3169,6 +3190,28 @@ public class Vpn {
mUnderlyingLinkProperties = lp;
}
+ 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 (mNetworkAgent != null
+ && mNetworkAgent.getNetwork().equals(report.getNetwork())) {
+ Log.d(TAG, "Data stall suspected");
+
+ // Trigger MOBIKE.
+ maybeMigrateIkeSession(mActiveNetwork);
+ }
+ }
+ }
+ }
+
/**
* Handles loss of the default underlying network
*
@@ -3463,6 +3506,8 @@ public class Vpn {
resetIkeState();
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+ mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback(
+ mDiagnosticsCallback);
mExecutor.shutdown();
}