Merge changes from topics "nonAutoIPSelection", "preferredIpProtocol"
* changes:
Honor IP protocol set by client in non-auto IP selection mode
Read preferred IKE protocol from carrier config
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 6d3f8fd..1e9352d1 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -31,6 +31,7 @@
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 android.telephony.CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT;
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
@@ -269,6 +270,42 @@
@VisibleForTesting
static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets.
+ *
+ * This is one of the possible customization values for
+ * CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_AUTO = 0;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV4} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_UDP} for ESP packets.
+ *
+ * This is one of the possible customization values for
+ * CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_IPV4_UDP = 40;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV6} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_UDP} for ESP packets.
+ *
+ * Do not use this value for production code. Its numeric value will change in future versions.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_IPV6_UDP = 60;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV6} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_NONE} for ESP packets.
+ *
+ * This is one of the possible customization values for
+ * CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_IPV6_ESP = 61;
+
// TODO: create separate trackers for each unique VPN to support
// automated reconnection
@@ -326,12 +363,13 @@
private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS);
/**
- * Cached Map of <subscription ID, keepalive delay ms> since retrieving the PersistableBundle
+ * Cached Map of <subscription ID, CarrierConfigInfo> 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<>();
+ private final SparseArray<CarrierConfigInfo> mCachedCarrierConfigInfoPerSubId =
+ new SparseArray<>();
/**
* Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
@@ -378,6 +416,28 @@
void checkInterruptAndDelay(boolean sleepLonger) throws InterruptedException;
}
+ private static class CarrierConfigInfo {
+ public final String mccMnc;
+ public final int keepaliveDelayMs;
+ public final int encapType;
+ public final int ipVersion;
+
+ CarrierConfigInfo(String mccMnc, int keepaliveDelayMs,
+ int encapType,
+ int ipVersion) {
+ this.mccMnc = mccMnc;
+ this.keepaliveDelayMs = keepaliveDelayMs;
+ this.encapType = encapType;
+ this.ipVersion = ipVersion;
+ }
+
+ @Override
+ public String toString() {
+ return "CarrierConfigInfo(" + mccMnc + ") [keepaliveDelayMs=" + keepaliveDelayMs
+ + ", encapType=" + encapType + ", ipVersion=" + ipVersion + "]";
+ }
+ }
+
@VisibleForTesting
public static class Dependencies {
public boolean isCallerSystem() {
@@ -2923,7 +2983,7 @@
public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
int specificCarrierId) {
synchronized (Vpn.this) {
- mCachedKeepalivePerSubId.remove(subId);
+ mCachedCarrierConfigInfoPerSubId.remove(subId);
// Ignore stale runner.
if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return;
@@ -3388,47 +3448,105 @@
}
private int guessEspIpVersionForNetwork() {
- // TODO : guess the IP version based on carrier if auto IP version selection is enabled
- return ESP_IP_VERSION_AUTO;
+ final CarrierConfigInfo carrierconfig = getCarrierConfig();
+ final int ipVersion = (carrierconfig != null)
+ ? carrierconfig.ipVersion : ESP_IP_VERSION_AUTO;
+ if (carrierconfig != null) {
+ Log.d(TAG, "Get customized IP version(" + ipVersion + ") on SIM("
+ + carrierconfig.mccMnc + ")");
+ }
+ return ipVersion;
}
private int guessEspEncapTypeForNetwork() {
- // TODO : guess the ESP encap type based on carrier if auto IP version selection is
- // enabled
- return ESP_ENCAP_TYPE_AUTO;
+ final CarrierConfigInfo carrierconfig = getCarrierConfig();
+ final int encapType = (carrierconfig != null)
+ ? carrierconfig.encapType : ESP_ENCAP_TYPE_AUTO;
+ if (carrierconfig != null) {
+ Log.d(TAG, "Get customized encap type(" + encapType + ") on SIM("
+ + carrierconfig.mccMnc + ")");
+ }
+ return encapType;
}
private int guessNattKeepaliveTimerForNetwork() {
+ final CarrierConfigInfo carrierconfig = getCarrierConfig();
+ final int natKeepalive = (carrierconfig != null)
+ ? carrierconfig.keepaliveDelayMs : AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
+ if (carrierconfig != null) {
+ Log.d(TAG, "Get customized keepalive(" + natKeepalive + ") on SIM("
+ + carrierconfig.mccMnc + ")");
+ }
+ return natKeepalive;
+ }
+
+ private CarrierConfigInfo getCarrierConfig() {
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;
+ return null;
}
synchronized (Vpn.this) {
- if (mCachedKeepalivePerSubId.contains(subId)) {
- Log.d(TAG, "Get cached keepalive config");
- return mCachedKeepalivePerSubId.get(subId);
+ if (mCachedCarrierConfigInfoPerSubId.contains(subId)) {
+ Log.d(TAG, "Get cached config");
+ return mCachedCarrierConfigInfoPerSubId.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;
}
+
+ 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 null;
+ }
+
+ final PersistableBundle carrierConfig =
+ mCarrierConfigManager.getConfigForSubId(subId);
+ if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
+ return null;
+ }
+
+ final int natKeepalive =
+ carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
+ final int preferredIpPortocol =
+ carrierConfig.getInt(KEY_PREFERRED_IKE_PROTOCOL_INT);
+ final String mccMnc = perSubTm.getSimOperator(subId);
+ final CarrierConfigInfo info =
+ buildCarrierConfigInfo(mccMnc, natKeepalive, preferredIpPortocol);
+ synchronized (Vpn.this) {
+ mCachedCarrierConfigInfoPerSubId.put(subId, info);
+ }
+
+ return info;
+ }
+
+ private CarrierConfigInfo buildCarrierConfigInfo(String mccMnc,
+ int natKeepalive, int preferredIpPortocol) {
+ final int ipVersion;
+ final int encapType;
+ switch (preferredIpPortocol) {
+ case PREFERRED_IKE_PROTOCOL_AUTO:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_AUTO;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+ break;
+ case PREFERRED_IKE_PROTOCOL_IPV4_UDP:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV4;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_UDP;
+ break;
+ case PREFERRED_IKE_PROTOCOL_IPV6_UDP:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV6;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_UDP;
+ break;
+ case PREFERRED_IKE_PROTOCOL_IPV6_ESP:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV6;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_NONE;
+ break;
+ default:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_AUTO;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+ break;
+ }
+ return new CarrierConfigInfo(mccMnc, natKeepalive, encapType, ipVersion);
}
boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
@@ -3440,10 +3558,22 @@
+ mCurrentToken
+ " to network "
+ underlyingNetwork);
- final int ipVersion = mProfile.isAutomaticIpVersionSelectionEnabled()
- ? guessEspIpVersionForNetwork() : ESP_IP_VERSION_AUTO;
- final int encapType = mProfile.isAutomaticIpVersionSelectionEnabled()
- ? guessEspEncapTypeForNetwork() : ESP_ENCAP_TYPE_AUTO;
+
+ final int ipVersion;
+ final int encapType;
+ if (mProfile.isAutomaticIpVersionSelectionEnabled()) {
+ ipVersion = guessEspIpVersionForNetwork();
+ encapType = guessEspEncapTypeForNetwork();
+ } else if (mProfile.getIkeTunnelConnectionParams() != null) {
+ ipVersion = mProfile.getIkeTunnelConnectionParams()
+ .getIkeSessionParams().getIpVersion();
+ encapType = mProfile.getIkeTunnelConnectionParams()
+ .getIkeSessionParams().getEncapType();
+ } else {
+ ipVersion = ESP_IP_VERSION_AUTO;
+ encapType = ESP_ENCAP_TYPE_AUTO;
+ }
+
final int keepaliveDelaySeconds;
if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) {
keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork();
@@ -4884,7 +5014,7 @@
pw.println("Reset session scheduled");
}
}
- pw.println("mCachedKeepalivePerSubId=" + mCachedKeepalivePerSubId);
+ pw.println("mCachedCarrierConfigInfoPerSubId=" + mCachedCarrierConfigInfoPerSubId);
pw.println("mUnderlyNetworkChanges (most recent first):");
pw.increaseIndent();