Merge "Tidy up VPN code"

This commit is contained in:
Lucas Lin
2022-08-02 07:58:50 +00:00
committed by Gerrit 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
@@ -785,7 +790,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);
} }
@@ -2589,7 +2594,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(
@@ -2597,8 +2602,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);
} }
@@ -2712,11 +2716,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;
@@ -3208,7 +3214,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,
@@ -3225,7 +3231,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);
} }
} }
@@ -3293,70 +3299,69 @@ public class Vpn {
// already terminated due to other failures. // already terminated due to other failures.
cancelHandleNetworkLostTimeout(); cancelHandleNetworkLostTimeout();
synchronized (Vpn.this) { String category = null;
String category = null; int errorClass = -1;
int errorClass = -1; int errorCode = -1;
int errorCode = -1; if (exception instanceof IllegalArgumentException) {
if (exception instanceof IkeProtocolException) { // Failed to build IKE/ChildSessionParams; fatal profile configuration error
final IkeProtocolException ikeException = (IkeProtocolException) exception; markFailedAndDisconnect(exception);
category = VpnManager.CATEGORY_EVENT_IKE_ERROR; return;
errorCode = ikeException.getErrorType(); }
switch (ikeException.getErrorType()) { if (exception instanceof IkeProtocolException) {
case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough final IkeProtocolException ikeException = (IkeProtocolException) exception;
case IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD: // Fallthrough category = VpnManager.CATEGORY_EVENT_IKE_ERROR;
case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED: // Fallthrough errorCode = ikeException.getErrorType();
case IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED: // Fallthrough
case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough switch (ikeException.getErrorType()) {
case IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE: case IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN: // Fallthrough
// All the above failures are configuration errors, and are terminal case IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD: // Fallthrough
errorClass = VpnManager.ERROR_CLASS_NOT_RECOVERABLE; case IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED: // Fallthrough
break; case IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED: // Fallthrough
// All other cases possibly recoverable. case IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED: // Fallthrough
default: 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
errorClass = VpnManager.ERROR_CLASS_RECOVERABLE; errorClass = VpnManager.ERROR_CLASS_NOT_RECOVERABLE;
} break;
} else if (exception instanceof IllegalArgumentException) { // All other cases possibly recoverable.
// Failed to build IKE/ChildSessionParams; fatal profile configuration error default:
markFailedAndDisconnect(exception); errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
return;
} else if (exception instanceof IkeNetworkLostException) {
category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
errorCode = VpnManager.ERROR_CODE_NETWORK_LOST;
} else if (exception instanceof IkeNonProtocolException) {
category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
if (exception.getCause() instanceof UnknownHostException) {
errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST;
} else if (exception.getCause() instanceof IkeTimeoutException) {
errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT;
} else if (exception.getCause() instanceof IOException) {
errorCode = VpnManager.ERROR_CODE_NETWORK_IO;
}
} else if (exception != null) {
Log.wtf(TAG, "onSessionLost: exception = " + exception);
} }
} else if (exception instanceof IkeNetworkLostException) {
category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
errorCode = VpnManager.ERROR_CODE_NETWORK_LOST;
} else if (exception instanceof IkeNonProtocolException) {
category = VpnManager.CATEGORY_EVENT_NETWORK_ERROR;
errorClass = VpnManager.ERROR_CLASS_RECOVERABLE;
if (exception.getCause() instanceof UnknownHostException) {
errorCode = VpnManager.ERROR_CODE_NETWORK_UNKNOWN_HOST;
} else if (exception.getCause() instanceof IkeTimeoutException) {
errorCode = VpnManager.ERROR_CODE_NETWORK_PROTOCOL_TIMEOUT;
} else if (exception.getCause() instanceof IOException) {
errorCode = VpnManager.ERROR_CODE_NETWORK_IO;
}
} else if (exception != null) {
Log.wtf(TAG, "onSessionLost: exception = " + exception);
}
synchronized (Vpn.this) {
// TODO(b/230548427): Remove SDK check once VPN related stuff are // TODO(b/230548427): Remove SDK check once VPN related stuff are
// decoupled from ConnectivityServiceTest. // decoupled from ConnectivityServiceTest.
if (SdkLevel.isAtLeastT() && category != null && isVpnApp(mPackage)) { if (SdkLevel.isAtLeastT() && category != null && isVpnApp(mPackage)) {
sendEventToVpnManagerApp(category, errorClass, errorCode, sendEventToVpnManagerApp(category, errorClass, errorCode,
getPackage(), mSessionKey, makeVpnProfileStateLocked(), getPackage(), mSessionKey, makeVpnProfileStateLocked(),
mActiveNetwork, mActiveNetwork,
getRedactedNetworkCapabilitiesOfUnderlyingNetwork( getRedactedNetworkCapabilities(mUnderlyingNetworkCapabilities),
mUnderlyingNetworkCapabilities), getRedactedLinkProperties(mUnderlyingLinkProperties));
getRedactedLinkPropertiesOfUnderlyingNetwork(
mUnderlyingLinkProperties));
} }
}
if (errorClass == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) { if (errorClass == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) {
markFailedAndDisconnect(exception); markFailedAndDisconnect(exception);
return; return;
} else { } else {
scheduleRetryNewIkeSession(); scheduleRetryNewIkeSession();
}
} }
mUnderlyingNetworkCapabilities = null; mUnderlyingNetworkCapabilities = null;