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:
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user