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

Commit a967fb80 authored by chiachangwang's avatar chiachangwang
Browse files

Add dump for Vpn

Adding additional logging and dump information to help VPN debug.

Sample dump result(adb shell dumpsys vpn_management)

VPNs:
  0: com.vpn.test
    Active package name: com.vpn.test
    Active vpn type: 2
    NetworkCapabilities: [ Transports: VPN Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VCN_MANAGED TransportInfo: <VpnTransportInfo{type=2, sessionId=null}> Uids: <{0-99999}> OwnerUid: 10106 AdminUids: [10106] UnderlyingNetworks: [107]]
    Token: 8876c2c4-df5f-46b8-82c7-8f124178254a
    MOBIKE enabled
    mUnderlyNetworkChanges (most recent first):
      2022-10-31T17:42:31.039068 - Switch to 107
      2022-10-31T17:42:29.510574 - Agent connect. Switch to 105
      2022-10-31T17:41:57.590691 - Agent connect. Switch to 103
      2022-10-31T17:41:31.269923 - Switch to 103
      2022-10-31T17:41:20.145050 - Switch to 102
      2022-10-31T17:41:14.480618 - Agent connect. Switch to 100
    mVpnManagerEvent (most recent first):
      2022-10-31T17:42:11.641201 - Event class=ERROR_CLASS_RECOVERABLE, err=ERROR_CODE_NETWORK_LOST for com.vpn.test on session 8876c2c4-df5f-46b8-82c7-8f124178254a
      2022-10-31T17:41:34.921219 - com.vpn.test stopped

Test: atest FrameworksNetTests
Test: adb shell dumpsys vpn_management
Bug: 238696406
Change-Id: I05b66ddb4a2b7a73707db39c6b89bf497aed1266
parent 92e34479
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -186,6 +186,10 @@ public class VpnManagerService extends IVpnManager.Stub {
        synchronized (mVpns) {
            for (int i = 0; i < mVpns.size(); i++) {
                pw.println(mVpns.keyAt(i) + ": " + mVpns.valueAt(i).getPackage());
                pw.increaseIndent();
                mVpns.valueAt(i).dump(pw);
                pw.decreaseIndent();
                pw.println();
            }
            pw.decreaseIndent();
        }
+72 −1
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ import android.system.keystore2.KeyDescriptor;
import android.system.keystore2.KeyPermission;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Log;
import android.util.Range;

@@ -289,6 +291,10 @@ public class Vpn {
        return mVpnProfileStore;
    }

    private static final int MAX_EVENTS_LOGS = 20;
    private final LocalLog mUnderlyNetworkChanges = new LocalLog(MAX_EVENTS_LOGS);
    private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS);

    /**
     * Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
     * only applies to {@link VpnService} connections.
@@ -816,6 +822,9 @@ public class Vpn {
            int errorCode, @NonNull final String packageName, @Nullable final String sessionKey,
            @NonNull final VpnProfileState profileState, @Nullable final Network underlyingNetwork,
            @Nullable final NetworkCapabilities nc, @Nullable final LinkProperties lp) {
        mVpnManagerEvents.log("Event class=" + getVpnManagerEventClassName(errorClass)
                + ", err=" + getVpnManagerEventErrorName(errorCode) + " for " + packageName
                + " on session " + sessionKey);
        final Intent intent = buildVpnManagerEventIntent(category, errorClass, errorCode,
                packageName, sessionKey, profileState, underlyingNetwork, nc, lp);
        return sendEventToVpnManagerApp(intent, packageName);
@@ -1539,6 +1548,7 @@ public class Vpn {
                ? Arrays.asList(mConfig.underlyingNetworks) : null);

        mNetworkCapabilities = capsBuilder.build();
        logUnderlyNetworkChanges(mNetworkCapabilities.getUnderlyingNetworks());
        mNetworkAgent = mDeps.newNetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
                mNetworkCapabilities, lp,
                new NetworkScore.Builder().setLegacyInt(VPN_DEFAULT_SCORE).build(),
@@ -1566,6 +1576,11 @@ public class Vpn {
        }
    }

    private void logUnderlyNetworkChanges(List<Network> networks) {
        mUnderlyNetworkChanges.log("Switch to "
                + ((networks != null) ? TextUtils.join(", ", networks) : "null"));
    }

    private void agentDisconnect(NetworkAgent networkAgent) {
        if (networkAgent != null) {
            networkAgent.unregister();
@@ -4231,6 +4246,7 @@ public class Vpn {
        // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from
        //  ConnectivityServiceTest.
        if (SdkLevel.isAtLeastT()) {
            mVpnManagerEvents.log(packageName + " stopped");
            sendEventToVpnManagerApp(intent, packageName);
        }
    }
@@ -4398,8 +4414,10 @@ public class Vpn {
    /** Proxy to allow different testing setups */
    // TODO: b/240492694 Remove VpnNetworkAgentWrapper and this method when
    // NetworkAgent#setUnderlyingNetworks can be un-finalized.
    private static void doSetUnderlyingNetworks(
    private void doSetUnderlyingNetworks(
            @NonNull NetworkAgent agent, @NonNull List<Network> networks) {
        logUnderlyNetworkChanges(networks);

        if (agent instanceof VpnNetworkAgentWrapper) {
            ((VpnNetworkAgentWrapper) agent).doSetUnderlyingNetworks(networks);
        } else {
@@ -4518,4 +4536,57 @@ public class Vpn {
    static Range<Integer> createUidRangeForUser(int userId) {
        return new Range<Integer>(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
    }

    private String getVpnManagerEventClassName(int code) {
        switch (code) {
            case VpnManager.ERROR_CLASS_NOT_RECOVERABLE:
                return "ERROR_CLASS_NOT_RECOVERABLE";
            case VpnManager.ERROR_CLASS_RECOVERABLE:
                return "ERROR_CLASS_RECOVERABLE";
            default:
                return "UNKNOWN_CLASS";
        }
    }

    private String getVpnManagerEventErrorName(int code) {
        switch (code) {
            case VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST:
                return "ERROR_CODE_NETWORK_UNKNOWN_HOST";
            case VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT:
                return "ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT";
            case VpnManager.ERROR_CODE_NETWORK_IO:
                return "ERROR_CODE_NETWORK_IO";
            case VpnManager.ERROR_CODE_NETWORK_LOST:
                return "ERROR_CODE_NETWORK_LOST";
            default:
                return "UNKNOWN_ERROR";
        }
    }

    /** Dumps VPN state. */
    public void dump(IndentingPrintWriter pw) {
        synchronized (Vpn.this) {
            pw.println("Active package name: " + mPackage);
            pw.println("Active vpn type: " + getActiveVpnType());
            pw.println("NetworkCapabilities: " + mNetworkCapabilities);
            if (isIkev2VpnRunner()) {
                final IkeV2VpnRunner runner = ((IkeV2VpnRunner) mVpnRunner);
                pw.println("Token: " + runner.mSessionKey);
                pw.println("MOBIKE " + (runner.mMobikeEnabled ? "enabled" : "disabled"));
                if (mDataStallSuspected) pw.println("Data stall suspected");
                if (runner.mScheduledHandleDataStallFuture != null) {
                    pw.println("Reset session scheduled");
                }
            }
            pw.println("mUnderlyNetworkChanges (most recent first):");
            pw.increaseIndent();
            mUnderlyNetworkChanges.reverseDump(pw);
            pw.decreaseIndent();

            pw.println("mVpnManagerEvent (most recent first):");
            pw.increaseIndent();
            mVpnManagerEvents.reverseDump(pw);
            pw.decreaseIndent();
        }
    }
}