Read NAT keepalive value from carrier config

Read keepalive from carrier config for Ikev2 VPN.

Bug: 259000745
Bug: 269714970
Test: atest FrameworksNetTests
Change-Id: I242a2d033dbc9266fd083e7242233638dd475e3d
This commit is contained in:
chiachangwang
2023-02-22 13:08:32 +00:00
parent cb23451c56
commit f0eb7b8118

View File

@@ -21,6 +21,7 @@ import static android.Manifest.permission.CONTROL_VPN;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; 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_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; 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.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.RouteInfo.RTN_THROW; import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.RouteInfo.RTN_UNREACHABLE;
@@ -29,6 +30,7 @@ import static android.net.ipsec.ike.IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO; import static android.net.ipsec.ike.IkeSessionParams.ESP_IP_VERSION_AUTO;
import static android.os.PowerWhitelistManager.REASON_VPN; import static android.os.PowerWhitelistManager.REASON_VPN;
import static android.os.UserHandle.PER_USER_RANGE; import static android.os.UserHandle.PER_USER_RANGE;
import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU; import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER; import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
@@ -79,7 +81,9 @@ import android.net.NetworkInfo.DetailedState;
import android.net.NetworkProvider; import android.net.NetworkProvider;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.NetworkScore; import android.net.NetworkScore;
import android.net.NetworkSpecifier;
import android.net.RouteInfo; import android.net.RouteInfo;
import android.net.TelephonyNetworkSpecifier;
import android.net.UidRangeParcel; import android.net.UidRangeParcel;
import android.net.UnderlyingNetworkInfo; import android.net.UnderlyingNetworkInfo;
import android.net.Uri; import android.net.Uri;
@@ -127,12 +131,16 @@ import android.security.keystore.KeyProperties;
import android.system.keystore2.Domain; import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor; import android.system.keystore2.KeyDescriptor;
import android.system.keystore2.KeyPermission; import android.system.keystore2.KeyPermission;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.IndentingPrintWriter; import android.util.IndentingPrintWriter;
import android.util.LocalLog; import android.util.LocalLog;
import android.util.Log; import android.util.Log;
import android.util.Range; import android.util.Range;
import android.util.SparseArray;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
@@ -268,6 +276,10 @@ public class Vpn {
private final ConnectivityManager mConnectivityManager; private final ConnectivityManager mConnectivityManager;
private final AppOpsManager mAppOpsManager; private final AppOpsManager mAppOpsManager;
private final ConnectivityDiagnosticsManager mConnectivityDiagnosticsManager; private final ConnectivityDiagnosticsManager mConnectivityDiagnosticsManager;
private final TelephonyManager mTelephonyManager;
private final CarrierConfigManager mCarrierConfigManager;
private final SubscriptionManager mSubscriptionManager;
// The context is for specific user which is created from mUserId // The context is for specific user which is created from mUserId
private final Context mUserIdContext; private final Context mUserIdContext;
@VisibleForTesting final Dependencies mDeps; @VisibleForTesting final Dependencies mDeps;
@@ -313,6 +325,14 @@ public class Vpn {
private final LocalLog mUnderlyNetworkChanges = new LocalLog(MAX_EVENTS_LOGS); private final LocalLog mUnderlyNetworkChanges = new LocalLog(MAX_EVENTS_LOGS);
private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS); private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS);
/**
* Cached Map of <subscription ID, keepalive delay ms> since retrieving the PersistableBundle
* and the target value from CarrierConfigManager is somewhat expensive as it has hundreds of
* fields. This cache is cleared when the carrier config changes to ensure data freshness.
*/
@GuardedBy("this")
private final SparseArray<Integer> mCachedKeepalivePerSubId = new SparseArray<>();
/** /**
* Whether to keep the connection active after rebooting, or upgrading or reinstalling. This * Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
* only applies to {@link VpnService} connections. * only applies to {@link VpnService} connections.
@@ -626,6 +646,10 @@ public class Vpn {
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */); mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
mConnectivityDiagnosticsManager = mConnectivityDiagnosticsManager =
mContext.getSystemService(ConnectivityDiagnosticsManager.class); mContext.getSystemService(ConnectivityDiagnosticsManager.class);
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
mDeps = deps; mDeps = deps;
mNms = netService; mNms = netService;
mNetd = netd; mNetd = netd;
@@ -2893,6 +2917,24 @@ public class Vpn {
*/ */
private int mRetryCount = 0; private int mRetryCount = 0;
private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
new CarrierConfigManager.CarrierConfigChangeListener() {
@Override
public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
int specificCarrierId) {
synchronized (Vpn.this) {
mCachedKeepalivePerSubId.remove(subId);
// Ignore stale runner.
if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return;
maybeMigrateIkeSession(mActiveNetwork);
}
// TODO: update the longLivedTcpConnectionsExpensive value in the
// networkcapabilities of the VPN network.
}
};
IkeV2VpnRunner( IkeV2VpnRunner(
@NonNull Ikev2VpnProfile profile, @NonNull ScheduledThreadPoolExecutor executor) { @NonNull Ikev2VpnProfile profile, @NonNull ScheduledThreadPoolExecutor executor) {
super(TAG); super(TAG);
@@ -2918,6 +2960,9 @@ public class Vpn {
setVpnNetworkPreference(mSessionKey, setVpnNetworkPreference(mSessionKey,
createUserAndRestrictedProfilesRanges(mUserId, createUserAndRestrictedProfilesRanges(mUserId,
mConfig.allowedApplications, mConfig.disallowedApplications)); mConfig.allowedApplications, mConfig.disallowedApplications));
mCarrierConfigManager.registerCarrierConfigChangeListener(mExecutor,
mCarrierConfigChangeListener);
} }
@Override @Override
@@ -3356,11 +3401,38 @@ public class Vpn {
} }
private int guessNattKeepaliveTimerForNetwork() { private int guessNattKeepaliveTimerForNetwork() {
// TODO : guess the keepalive delay based on carrier if auto keepalive timer is final int subId = getCellSubIdForNetworkCapabilities(mUnderlyingNetworkCapabilities);
// enabled if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
Log.d(TAG, "Underlying network is not a cellular network");
return AUTOMATIC_KEEPALIVE_DELAY_SECONDS; return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
} }
synchronized (Vpn.this) {
if (mCachedKeepalivePerSubId.contains(subId)) {
Log.d(TAG, "Get cached keepalive config");
return mCachedKeepalivePerSubId.get(subId);
}
final TelephonyManager perSubTm = mTelephonyManager.createForSubscriptionId(subId);
if (perSubTm.getSimApplicationState() != TelephonyManager.SIM_STATE_LOADED) {
Log.d(TAG, "SIM card is not ready on sub " + subId);
return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
}
final PersistableBundle carrierConfig =
mCarrierConfigManager.getConfigForSubId(subId);
if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
}
final int natKeepalive =
carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
mCachedKeepalivePerSubId.put(subId, natKeepalive);
Log.d(TAG, "Get customized keepalive=" + natKeepalive);
return natKeepalive;
}
}
boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) { boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
if (mSession == null || !mMobikeEnabled) return false; if (mSession == null || !mMobikeEnabled) return false;
@@ -3456,7 +3528,15 @@ public class Vpn {
/** Called when the NetworkCapabilities of underlying network is changed */ /** Called when the NetworkCapabilities of underlying network is changed */
public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) { public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) {
final NetworkCapabilities oldNc = mUnderlyingNetworkCapabilities;
mUnderlyingNetworkCapabilities = nc; mUnderlyingNetworkCapabilities = nc;
// The oldNc may be null when it's not assigned yet.
final boolean subIdChanged =
(oldNc == null) || !nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds());
// Update carrierConfig.
if (subIdChanged) {
maybeMigrateIkeSession(mActiveNetwork);
}
} }
/** Called when the LinkProperties of underlying network is changed */ /** Called when the LinkProperties of underlying network is changed */
@@ -3812,6 +3892,8 @@ public class Vpn {
resetIkeState(); resetIkeState();
mCarrierConfigManager.unregisterCarrierConfigChangeListener(
mCarrierConfigChangeListener);
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback( mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback(
mDiagnosticsCallback); mDiagnosticsCallback);
@@ -4804,6 +4886,8 @@ public class Vpn {
pw.println("Reset session scheduled"); pw.println("Reset session scheduled");
} }
} }
pw.println("mCachedKeepalivePerSubId=" + mCachedKeepalivePerSubId);
pw.println("mUnderlyNetworkChanges (most recent first):"); pw.println("mUnderlyNetworkChanges (most recent first):");
pw.increaseIndent(); pw.increaseIndent();
mUnderlyNetworkChanges.reverseDump(pw); mUnderlyNetworkChanges.reverseDump(pw);
@@ -4815,4 +4899,19 @@ public class Vpn {
pw.decreaseIndent(); pw.decreaseIndent();
} }
} }
private static int getCellSubIdForNetworkCapabilities(@Nullable NetworkCapabilities nc) {
if (nc == null) return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
if (!nc.hasTransport(TRANSPORT_CELLULAR)) {
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
final NetworkSpecifier specifier = nc.getNetworkSpecifier();
if (specifier instanceof TelephonyNetworkSpecifier) {
return ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
}
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
} }