Store SPI in LocalRequest
Store SPI in LocalRequest to show which IKE/Child SA is related
to this request. This allows the IkeSessionStateMachine to figure
out if this request is scheduled for a deleted SA
Bug: 147831323
Test: atest FrameworksIkeTests
Change-Id: I30f43e2b7137688b6e68de1cbb6ceea43355dacc
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
index ebf368a..ed20e2f 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
@@ -15,6 +15,11 @@
*/
package com.android.internal.net.ipsec.ike;
+import static com.android.internal.net.ipsec.ike.AbstractSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_CHILD;
+import static com.android.internal.net.ipsec.ike.AbstractSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD;
+import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE;
+import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_DPD;
+
import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.ChildSessionParams;
@@ -27,6 +32,8 @@
* <p>LocalRequestScheduler is running on the IkeSessionStateMachine thread.
*/
public final class IkeLocalRequestScheduler {
+ public static int SPI_NOT_INCLUDED = 0;
+
private final LinkedList<LocalRequest> mRequestQueue = new LinkedList<>();
private final IProcedureConsumer mConsumer;
@@ -69,15 +76,15 @@
}
/**
- * This class represents a user requested or internally scheduled IKE procedure that will be
- * initiated locally.
+ * This class represents the common information of procedures that will be locally initiated.
*/
- public static class LocalRequest {
+ public abstract static class LocalRequest {
public final int procedureType;
- // TODO: Also store specific payloads for INFO exchange.
+
private boolean mIsCancelled;
LocalRequest(int type) {
+ validateTypeOrThrow(type);
procedureType = type;
mIsCancelled = false;
}
@@ -89,6 +96,40 @@
void cancel() {
mIsCancelled = true;
}
+
+ protected abstract void validateTypeOrThrow(int type);
+
+ protected abstract boolean isChildRequest();
+ }
+
+ /**
+ * This class represents a user requested or internally scheduled IKE procedure that will be
+ * initiated locally.
+ */
+ public static class IkeLocalRequest extends LocalRequest {
+ public long remoteSpi;
+
+ /** Schedule a request for the IKE Session */
+ IkeLocalRequest(int type) {
+ this(type, SPI_NOT_INCLUDED);
+ }
+
+ /** Schedule a request for an IKE SA that is identified by the remoteIkeSpi */
+ IkeLocalRequest(int type, long remoteIkeSpi) {
+ super(type);
+ remoteSpi = remoteIkeSpi;
+ }
+
+ @Override
+ protected void validateTypeOrThrow(int type) {
+ if (type >= CMD_LOCAL_REQUEST_CREATE_IKE && type <= CMD_LOCAL_REQUEST_DPD) return;
+ throw new IllegalArgumentException("Invalid IKE procedure type: " + type);
+ }
+
+ @Override
+ protected boolean isChildRequest() {
+ return false;
+ }
}
/**
@@ -96,14 +137,44 @@
* initiated locally.
*/
public static class ChildLocalRequest extends LocalRequest {
+ public int remoteSpi;
public final ChildSessionCallback childSessionCallback;
public final ChildSessionParams childSessionParams;
+ /** Schedule a request for a Child Session that is identified by the childCallback */
ChildLocalRequest(
int type, ChildSessionCallback childCallback, ChildSessionParams childParams) {
+ this(type, SPI_NOT_INCLUDED, childCallback, childParams);
+ }
+
+ /** Schedule a request for a Child SA that is identified by the remoteChildSpi */
+ ChildLocalRequest(int type, int remoteChildSpi, ChildSessionParams childParams) {
+ this(type, remoteChildSpi, null /*childCallback*/, childParams);
+ }
+
+ private ChildLocalRequest(
+ int type,
+ int remoteChildSpi,
+ ChildSessionCallback childCallback,
+ ChildSessionParams childParams) {
super(type);
childSessionParams = childParams;
childSessionCallback = childCallback;
+ remoteSpi = remoteChildSpi;
+ }
+
+ @Override
+ protected void validateTypeOrThrow(int type) {
+ if (type >= CMD_LOCAL_REQUEST_CREATE_CHILD && type <= CMD_LOCAL_REQUEST_REKEY_CHILD) {
+ return;
+ }
+
+ throw new IllegalArgumentException("Invalid Child procedure type: " + type);
+ }
+
+ @Override
+ protected boolean isChildRequest() {
+ return true;
}
}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
index 8ad60e9..47e12db 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
@@ -77,6 +77,7 @@
import com.android.internal.net.eap.IEapCallback;
import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.CreateChildSaHelper;
import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
+import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IkeLocalRequest;
import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord;
import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
@@ -191,8 +192,6 @@
@VisibleForTesting
static final long TEMP_FAILURE_RETRY_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5L);
- // TODO: Allow users to configure IKE lifetime
-
// Package private IKE exchange subtypes describe the specific function of a IKE
// request/response exchange. It helps IkeSessionStateMachine to do message validation according
// to the subtype specific rules.
@@ -549,7 +548,8 @@
/** Initiates IKE setup procedure. */
public void openSession() {
- sendMessage(CMD_LOCAL_REQUEST_CREATE_IKE, new LocalRequest(CMD_LOCAL_REQUEST_CREATE_IKE));
+ sendMessage(
+ CMD_LOCAL_REQUEST_CREATE_IKE, new IkeLocalRequest(CMD_LOCAL_REQUEST_CREATE_IKE));
}
/** Schedules a Create Child procedure. */
@@ -588,7 +588,8 @@
/** Initiates Delete IKE procedure. */
public void closeSession() {
- sendMessage(CMD_LOCAL_REQUEST_DELETE_IKE, new LocalRequest(CMD_LOCAL_REQUEST_DELETE_IKE));
+ sendMessage(
+ CMD_LOCAL_REQUEST_DELETE_IKE, new IkeLocalRequest(CMD_LOCAL_REQUEST_DELETE_IKE));
}
/** Forcibly close IKE Session. */
@@ -1104,6 +1105,12 @@
}
private void executeLocalRequest(LocalRequest req, Message message) {
+ if (!isRequestForCurrentSa(req)) {
+ logd("Request is for a deleted SA. Ignore it.");
+ mScheduler.readyForNextProcedure();
+ return;
+ }
+
switch (req.procedureType) {
case CMD_LOCAL_REQUEST_REKEY_IKE:
transitionTo(mRekeyIkeLocalCreate);
@@ -1123,6 +1130,26 @@
"Invalid local request procedure type: " + req.procedureType));
}
}
+
+ // When in Idle state, this IkeSessionStateMachine and all its ChildSessionStateMachines
+ // only have one alive IKE/Child SA respectively. Returns true if this local request is for
+ // the current IKE/Child SA, or false if the request is for a deleted SA.
+ private boolean isRequestForCurrentSa(LocalRequest localRequest) {
+ if (localRequest.isChildRequest()) {
+ ChildLocalRequest req = (ChildLocalRequest) localRequest;
+ if (req.remoteSpi == IkeLocalRequestScheduler.SPI_NOT_INCLUDED
+ || mRemoteSpiToChildSessionMap.get(req.remoteSpi) != null) {
+ return true;
+ }
+ } else {
+ IkeLocalRequest req = (IkeLocalRequest) localRequest;
+ if (req.remoteSpi == IkeLocalRequestScheduler.SPI_NOT_INCLUDED
+ || req.remoteSpi == mCurrentIkeSaRecord.getRemoteSpi()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
/**
@@ -2515,7 +2542,7 @@
mIkePrf,
mIkeIntegrity == null ? 0 : mIkeIntegrity.getKeyLength(),
mIkeCipher.getKeyLength(),
- new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
addIkeSaRecord(mCurrentIkeSaRecord);
ikeInitSuccess = true;
@@ -3672,7 +3699,7 @@
newIntegrity == null ? 0 : newIntegrity.getKeyLength(),
newCipher.getKeyLength(),
isLocalInit,
- new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
addIkeSaRecord(newSaRecord);
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java
index 3406d01..251f83d 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java
@@ -27,6 +27,7 @@
import static org.mockito.Mockito.verify;
import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IProcedureConsumer;
+import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IkeLocalRequest;
import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
import org.junit.Before;
@@ -109,10 +110,10 @@
@Test
public void testDoNotProcessCanceledRequest() {
- LocalRequest[] requestArray = new LocalRequest[4];
+ LocalRequest[] requestArray = new IkeLocalRequest[4];
for (int i = 0; i < requestArray.length; i++) {
- requestArray[i] = new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE);
+ requestArray[i] = new IkeLocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE);
mScheduler.addRequest(requestArray[i]);
}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
index f44e3a5..119cf2a 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
@@ -101,7 +101,7 @@
import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.ChildSessionFactoryHelper;
import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.IChildSessionFactoryHelper;
import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
+import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IkeLocalRequest;
import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex;
import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.ReceivedIkePacket;
import com.android.internal.net.ipsec.ike.SaRecord.ISaRecordHelper;
@@ -638,7 +638,7 @@
new byte[KEY_LEN_IKE_ENCR],
TestUtils.hexStringToByteArray(PRF_KEY_INIT_HEX_STRING),
TestUtils.hexStringToByteArray(PRF_KEY_RESP_HEX_STRING),
- new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
}
@Before
@@ -2776,7 +2776,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
assertTrue(
mIkeSessionStateMachine.getCurrentState()
@@ -2823,7 +2823,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
@@ -2856,7 +2856,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
resetMockIkeMessageHelper();
@@ -2887,7 +2887,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
// Mock receiving packet with NO_PROPOSAL_CHOSEN
@@ -2916,7 +2916,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
resetMockIkeMessageHelper();
@@ -2945,7 +2945,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
resetMockIkeMessageHelper();
@@ -2972,7 +2972,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
resetMockIkeMessageHelper();
@@ -3382,7 +3382,7 @@
// Send Rekey request on mSpyCurrentIkeSaRecord
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
// Receive Rekey request on mSpyCurrentIkeSaRecord
ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest();
@@ -3469,7 +3469,7 @@
// Send Rekey-Create request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
// Prepare "rekeyed" SA
@@ -3705,7 +3705,7 @@
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
@@ -3736,7 +3736,7 @@
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
@@ -3758,7 +3758,7 @@
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
resetMockIkeMessageHelper();
@@ -3787,7 +3787,7 @@
// Send delete request
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
mLooper.dispatchAll();
// Receive response with wrong exchange type
@@ -3810,7 +3810,7 @@
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
mLooper.dispatchAll();
verifyRetransmissionStarted();
@@ -3947,7 +3947,7 @@
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
// Verify that the command is executed, and the state machine transitions to the right state
@@ -3970,7 +3970,7 @@
// Queue a local request, and expect that it is not run (yet)
mIkeSessionStateMachine.sendMessage(
IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE,
- new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
+ new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
mLooper.dispatchAll();
// Verify that the state machine is still in the Receiving state