Merge changes from topics "kpFromCarrier", "noNetCapNoMigration"
* changes: Prevent migrating the session from using the wrong value Read NAT keepalive value from carrier config
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.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;
|
||||
@@ -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.os.PowerWhitelistManager.REASON_VPN;
|
||||
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.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
|
||||
@@ -79,7 +81,9 @@ import android.net.NetworkInfo.DetailedState;
|
||||
import android.net.NetworkProvider;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.NetworkScore;
|
||||
import android.net.NetworkSpecifier;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.TelephonyNetworkSpecifier;
|
||||
import android.net.UidRangeParcel;
|
||||
import android.net.UnderlyingNetworkInfo;
|
||||
import android.net.Uri;
|
||||
@@ -127,12 +131,16 @@ import android.security.keystore.KeyProperties;
|
||||
import android.system.keystore2.Domain;
|
||||
import android.system.keystore2.KeyDescriptor;
|
||||
import android.system.keystore2.KeyPermission;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.LocalLog;
|
||||
import android.util.Log;
|
||||
import android.util.Range;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -268,6 +276,10 @@ public class Vpn {
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final AppOpsManager mAppOpsManager;
|
||||
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
|
||||
private final Context mUserIdContext;
|
||||
@VisibleForTesting final Dependencies mDeps;
|
||||
@@ -313,6 +325,14 @@ public class Vpn {
|
||||
private final LocalLog mUnderlyNetworkChanges = 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
|
||||
* only applies to {@link VpnService} connections.
|
||||
@@ -626,6 +646,10 @@ public class Vpn {
|
||||
mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
|
||||
mConnectivityDiagnosticsManager =
|
||||
mContext.getSystemService(ConnectivityDiagnosticsManager.class);
|
||||
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
|
||||
mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
|
||||
mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
|
||||
|
||||
mDeps = deps;
|
||||
mNms = netService;
|
||||
mNetd = netd;
|
||||
@@ -2893,6 +2917,24 @@ public class Vpn {
|
||||
*/
|
||||
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(
|
||||
@NonNull Ikev2VpnProfile profile, @NonNull ScheduledThreadPoolExecutor executor) {
|
||||
super(TAG);
|
||||
@@ -2918,6 +2960,9 @@ public class Vpn {
|
||||
setVpnNetworkPreference(mSessionKey,
|
||||
createUserAndRestrictedProfilesRanges(mUserId,
|
||||
mConfig.allowedApplications, mConfig.disallowedApplications));
|
||||
|
||||
mCarrierConfigManager.registerCarrierConfigChangeListener(mExecutor,
|
||||
mCarrierConfigChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3257,8 +3302,6 @@ public class Vpn {
|
||||
mUnderlyingLinkProperties = null;
|
||||
mUnderlyingNetworkCapabilities = null;
|
||||
mRetryCount = 0;
|
||||
|
||||
startOrMigrateIkeSession(network);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -3356,9 +3399,36 @@ public class Vpn {
|
||||
}
|
||||
|
||||
private int guessNattKeepaliveTimerForNetwork() {
|
||||
// TODO : guess the keepalive delay based on carrier if auto keepalive timer is
|
||||
// enabled
|
||||
return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
|
||||
final int subId = getCellSubIdForNetworkCapabilities(mUnderlyingNetworkCapabilities);
|
||||
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
Log.d(TAG, "Underlying network is not a cellular network");
|
||||
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) {
|
||||
@@ -3456,7 +3526,15 @@ public class Vpn {
|
||||
|
||||
/** Called when the NetworkCapabilities of underlying network is changed */
|
||||
public void onDefaultNetworkCapabilitiesChanged(@NonNull NetworkCapabilities nc) {
|
||||
final NetworkCapabilities oldNc = mUnderlyingNetworkCapabilities;
|
||||
mUnderlyingNetworkCapabilities = nc;
|
||||
if (oldNc == null) {
|
||||
// A new default network is available.
|
||||
startOrMigrateIkeSession(mActiveNetwork);
|
||||
} else if (!nc.getSubscriptionIds().equals(oldNc.getSubscriptionIds())) {
|
||||
// Renew carrierConfig values.
|
||||
maybeMigrateIkeSession(mActiveNetwork);
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when the LinkProperties of underlying network is changed */
|
||||
@@ -3812,6 +3890,8 @@ public class Vpn {
|
||||
|
||||
resetIkeState();
|
||||
|
||||
mCarrierConfigManager.unregisterCarrierConfigChangeListener(
|
||||
mCarrierConfigChangeListener);
|
||||
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
|
||||
mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback(
|
||||
mDiagnosticsCallback);
|
||||
@@ -4804,6 +4884,8 @@ public class Vpn {
|
||||
pw.println("Reset session scheduled");
|
||||
}
|
||||
}
|
||||
pw.println("mCachedKeepalivePerSubId=" + mCachedKeepalivePerSubId);
|
||||
|
||||
pw.println("mUnderlyNetworkChanges (most recent first):");
|
||||
pw.increaseIndent();
|
||||
mUnderlyNetworkChanges.reverseDump(pw);
|
||||
@@ -4815,4 +4897,19 @@ public class Vpn {
|
||||
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