Merge changes from topic "cherrypicker-L42100000956041116:N02800001288713842" into tm-qpr-dev

* changes:
  Tidy up VPN code
  Improve the code of handleSessionLost()
This commit is contained in:
Lucas Lin
2022-09-13 00:30:32 +00:00
committed by Android (Google) Code Review

View File

@@ -222,6 +222,11 @@ public class Vpn {
*/ */
private static final int VPN_DEFAULT_SCORE = 101; private static final int VPN_DEFAULT_SCORE = 101;
/**
* The initial token value of IKE session.
*/
private static final int STARTING_TOKEN = -1;
// TODO: create separate trackers for each unique VPN to support // TODO: create separate trackers for each unique VPN to support
// automated reconnection // automated reconnection
@@ -795,7 +800,7 @@ public class Vpn {
} }
} }
private boolean isVpnApp(String packageName) { private static boolean isVpnApp(String packageName) {
return packageName != null && !VpnConfig.LEGACY_VPN.equals(packageName); return packageName != null && !VpnConfig.LEGACY_VPN.equals(packageName);
} }
@@ -2593,7 +2598,7 @@ public class Vpn {
} }
@Nullable @Nullable
protected synchronized NetworkCapabilities getRedactedNetworkCapabilitiesOfUnderlyingNetwork( private synchronized NetworkCapabilities getRedactedNetworkCapabilities(
NetworkCapabilities nc) { NetworkCapabilities nc) {
if (nc == null) return null; if (nc == null) return null;
return mConnectivityManager.getRedactedNetworkCapabilitiesForPackage( return mConnectivityManager.getRedactedNetworkCapabilitiesForPackage(
@@ -2601,8 +2606,7 @@ public class Vpn {
} }
@Nullable @Nullable
protected synchronized LinkProperties getRedactedLinkPropertiesOfUnderlyingNetwork( private synchronized LinkProperties getRedactedLinkProperties(LinkProperties lp) {
LinkProperties lp) {
if (lp == null) return null; if (lp == null) return null;
return mConnectivityManager.getRedactedLinkPropertiesForPackage(lp, mOwnerUID, mPackage); return mConnectivityManager.getRedactedLinkPropertiesForPackage(lp, mOwnerUID, mPackage);
} }
@@ -2716,11 +2720,13 @@ public class Vpn {
private boolean mIsRunning = true; private boolean mIsRunning = true;
/** /**
* The token used by the primary/current/active IKE session. * The token that identifies the most recently created IKE session.
* *
* <p>This token MUST be updated when the VPN switches to use a new IKE session. * <p>This token is monotonically increasing and will never be reset in the lifetime of this
* Ikev2VpnRunner, but it does get reset across runs. It also MUST be accessed on the
* executor thread and updated when a new IKE session is created.
*/ */
private int mCurrentToken = -1; private int mCurrentToken = STARTING_TOKEN;
@Nullable private IpSecTunnelInterface mTunnelIface; @Nullable private IpSecTunnelInterface mTunnelIface;
@Nullable private Network mActiveNetwork; @Nullable private Network mActiveNetwork;
@@ -3223,7 +3229,7 @@ public class Vpn {
mExecutor.schedule( mExecutor.schedule(
() -> { () -> {
if (isActiveToken(token)) { if (isActiveToken(token)) {
handleSessionLost(null, network); handleSessionLost(null /* exception */, network);
} else { } else {
Log.d( Log.d(
TAG, TAG,
@@ -3240,7 +3246,7 @@ public class Vpn {
TimeUnit.MILLISECONDS); TimeUnit.MILLISECONDS);
} else { } else {
Log.d(TAG, "Call handleSessionLost for losing network " + network); Log.d(TAG, "Call handleSessionLost for losing network " + network);
handleSessionLost(null, network); handleSessionLost(null /* exception */, network);
} }
} }
@@ -3311,12 +3317,19 @@ public class Vpn {
// already terminated due to other failures. // already terminated due to other failures.
cancelHandleNetworkLostTimeout(); cancelHandleNetworkLostTimeout();
synchronized (Vpn.this) { String category = null;
// Ignore stale runner. int errorClass = -1;
if (mVpnRunner != this) return; int errorCode = -1;
if (exception instanceof IllegalArgumentException) {
// Failed to build IKE/ChildSessionParams; fatal profile configuration error
markFailedAndDisconnect(exception);
return;
}
if (exception instanceof IkeProtocolException) { if (exception instanceof IkeProtocolException) {
final IkeProtocolException ikeException = (IkeProtocolException) exception; final IkeProtocolException ikeException = (IkeProtocolException) exception;
category = VpnManager.CATEGORY_EVENT_IKE_ERROR;
errorCode = ikeException.getErrorType();
switch (ikeException.getErrorType()) { switch (ikeException.getErrorType()) {
case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough
@@ -3326,104 +3339,49 @@ public class Vpn {
case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough
case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE: case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE:
// All the above failures are configuration errors, and are terminal // All the above failures are configuration errors, and are terminal
// TODO(b/230548427): Remove SDK check once VPN related stuff are errorClass = VpnManager.ERROR_CLASS_NOT_RECOVERABLE;
// decoupled from ConnectivityServiceTest. break;
if (SdkLevel.isAtLeastT() && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_IKE_ERROR,
VpnManager.ERROR_CLASS_NOT_RECOVERABLE,
ikeException.getErrorType(),
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
network,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
mUnderlyingNetworkCapabilities),
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
}
markFailedAndDisconnect(exception);
return;
// All other cases possibly recoverable. // All other cases possibly recoverable.
default: default:
// All the above failures are configuration errors, and are terminal errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
// TODO(b/230548427): Remove SDK check once VPN related stuff are
// decoupled from ConnectivityServiceTest.
if (SdkLevel.isAtLeastT() && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_IKE_ERROR,
VpnManager.ERROR_CLASS_RECOVERABLE,
ikeException.getErrorType(),
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
network,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
mUnderlyingNetworkCapabilities),
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
} }
}
} else if (exception instanceof IllegalArgumentException) {
// Failed to build IKE/ChildSessionParams; fatal profile configuration error
markFailedAndDisconnect(exception);
return;
} else if (exception instanceof IkeNetworkLostException) { } else if (exception instanceof IkeNetworkLostException) {
// TODO(b/230548427): Remove SDK check once VPN related stuff are category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
// decoupled from ConnectivityServiceTest. errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
if (SdkLevel.isAtLeastT() && isVpnApp(mPackage)) { errorCode = VpnManager.ERROR_CODE_NETWORK_LOST;
sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
VpnManager.ERROR_CLASS_RECOVERABLE,
VpnManager.ERROR_CODE_NETWORK_LOST,
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
network,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
mUnderlyingNetworkCapabilities),
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
}
} else if (exception instanceof IkeNonProtocolException) { } else if (exception instanceof IkeNonProtocolException) {
category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
if (exception.getCause() instanceof UnknownHostException) { if (exception.getCause() instanceof UnknownHostException) {
// TODO(b/230548427): Remove SDK check once VPN related stuff are errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST;
// decoupled from ConnectivityServiceTest.
if (SdkLevel.isAtLeastT() && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
VpnManager.ERROR_CLASS_RECOVERABLE,
VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST,
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
network,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
mUnderlyingNetworkCapabilities),
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
}
} else if (exception.getCause() instanceof IkeTimeoutException) { } else if (exception.getCause() instanceof IkeTimeoutException) {
// TODO(b/230548427): Remove SDK check once VPN related stuff are errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT;
// decoupled from ConnectivityServiceTest.
if (SdkLevel.isAtLeastT() && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
VpnManager.ERROR_CLASS_RECOVERABLE,
VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT,
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
network,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
mUnderlyingNetworkCapabilities),
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
}
} else if (exception.getCause() instanceof IOException) { } else if (exception.getCause() instanceof IOException) {
// TODO(b/230548427): Remove SDK check once VPN related stuff are errorCode = VpnManager.ERROR_CODE_NETWORK_IO;
// decoupled from ConnectivityServiceTest.
if (SdkLevel.isAtLeastT() && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_NETWORK_ERROR,
VpnManager.ERROR_CLASS_RECOVERABLE,
VpnManager.ERROR_CODE_NETWORK_IO,
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
network,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork(
mUnderlyingNetworkCapabilities),
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
}
} }
} else if (exception != null) { } else if (exception != null) {
Log.wtf(TAG, "onSessionLost: exception = " + exception); Log.wtf(TAG, "onSessionLost: exception = " + exception);
} }
synchronized (Vpn.this) {
// Ignore stale runner.
if (mVpnRunner != this) return;
// TODO(b/230548427): Remove SDK check once VPN related stuff are
// decoupled from ConnectivityServiceTest.
if (SdkLevel.isAtLeastT() && category != null && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(category, errorClass, errorCode,
getPackage(), mSessionKey, makeVpnProfileStateLocked(),
mActiveNetwork,
getRedactedNetworkCapabilities(mUnderlyingNetworkCapabilities),
getRedactedLinkProperties(mUnderlyingLinkProperties));
}
}
if (errorClass == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) {
markFailedAndDisconnect(exception);
return;
} else {
scheduleRetryNewIkeSession(); scheduleRetryNewIkeSession();
} }