Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2137519e authored by chiachangwang's avatar chiachangwang Committed by Automerger Merge Worker
Browse files

Read NAT keepalive value from carrier config am: f0eb7b81 am: 4c60d9a4

parents 19ab48cf 4c60d9a4
Loading
Loading
Loading
Loading
+102 −3
Original line number Diff line number Diff line
@@ -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
@@ -3356,11 +3401,38 @@ public class Vpn {
        }

        private int guessNattKeepaliveTimerForNetwork() {
            // TODO : guess the keepalive delay based on carrier if auto keepalive timer is
            // enabled
            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) {
            if (mSession == null || !mMobikeEnabled) return false;

@@ -3456,7 +3528,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;
            // 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 */
@@ -3812,6 +3892,8 @@ public class Vpn {

            resetIkeState();

            mCarrierConfigManager.unregisterCarrierConfigChangeListener(
                    mCarrierConfigChangeListener);
            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
            mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback(
                    mDiagnosticsCallback);
@@ -4804,6 +4886,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 +4899,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;
    }
}