aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan Yan <evitayan@google.com>2020-05-19 19:50:49 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2020-05-19 19:50:49 +0000
commita854e9f375d28b2a917e6de16c7219d1341958d9 (patch)
tree4b0b983dfc75e695183e2519ca46166f23074ffd
parent73506b587efde77cb502d9f166a0d453d5666e42 (diff)
parentc1ed950ddad2bd565c4bb2e3109c2240959d1852 (diff)
downloadike-a854e9f375d28b2a917e6de16c7219d1341958d9.tar.gz
Merge "Release IPsec SPI if not receiving Create Child Response"
-rw-r--r--src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java34
-rw-r--r--src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java4
-rw-r--r--src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java15
3 files changed, 50 insertions, 3 deletions
diff --git a/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java
index 2b2ffee9..fd500b8f 100644
--- a/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java
+++ b/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java
@@ -885,19 +885,21 @@ public class ChildSessionStateMachine extends AbstractSessionStateMachine {
/** Initial state of ChildSessionStateMachine. */
class Initial extends CreateChildLocalCreateBase {
+ List<IkePayload> mRequestPayloads;
+
@Override
public boolean processStateMessage(Message message) {
switch (message.what) {
case CMD_HANDLE_FIRST_CHILD_EXCHANGE:
FirstChildNegotiationData childNegotiationData =
(FirstChildNegotiationData) message.obj;
- List<IkePayload> reqPayloads = childNegotiationData.requestPayloads;
+ mRequestPayloads = childNegotiationData.requestPayloads;
List<IkePayload> respPayloads = childNegotiationData.responsePayloads;
// Negotiate Child SA. The exchangeType has been validated in
// IkeSessionStateMachine. Won't validate it again here.
validateAndBuildChild(
- reqPayloads,
+ mRequestPayloads,
respPayloads,
EXCHANGE_TYPE_IKE_AUTH,
EXCHANGE_TYPE_IKE_AUTH,
@@ -922,6 +924,11 @@ public class ChildSessionStateMachine extends AbstractSessionStateMachine {
return NOT_HANDLED;
}
}
+
+ @Override
+ public void exitState() {
+ CreateChildSaHelper.releaseSpiResources(mRequestPayloads);
+ }
}
/**
@@ -977,6 +984,11 @@ public class ChildSessionStateMachine extends AbstractSessionStateMachine {
return NOT_HANDLED;
}
}
+
+ @Override
+ public void exitState() {
+ CreateChildSaHelper.releaseSpiResources(mRequestPayloads);
+ }
}
/**
@@ -1402,6 +1414,11 @@ public class ChildSessionStateMachine extends AbstractSessionStateMachine {
}
handleChildFatalError(exception);
}
+
+ @Override
+ public void exitState() {
+ CreateChildSaHelper.releaseSpiResources(mRequestPayloads);
+ }
}
private ChildSaProposal addDhGroupsFromChildSessionParamsIfAbsent() {
@@ -2054,6 +2071,19 @@ public class ChildSessionStateMachine extends AbstractSessionStateMachine {
return hasExpectedRekeyNotify;
}
+ public static void releaseSpiResources(List<IkePayload> reqPayloads) {
+ if (reqPayloads == null) {
+ return;
+ }
+
+ IkeSaPayload saPayload =
+ IkePayload.getPayloadForTypeInProvidedList(
+ IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, reqPayloads);
+ if (saPayload != null) {
+ saPayload.releaseChildSpiResourcesIfExists();
+ }
+ }
+
/** Validate the received payload list and negotiate Child SA. */
private static CreateChildResult validateAndNegotiateChild(
List<IkePayload> reqPayloads,
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 ea496f81..3429c8a0 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
+++ b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
@@ -947,6 +947,10 @@ public class IkeSessionStateMachine extends AbstractSessionStateMachine {
}
}
+ // Release IPsec SPIs if IKE Session is terminated before receiving the IKE AUTH response
+ // that contains the first child SA proposal
+ CreateChildSaHelper.releaseSpiResources(mFirstChildReqList);
+
if (mIkeNattKeepalive != null) {
mIkeNattKeepalive.stop();
}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
index d2dd3943..40eecf02 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
+++ b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
@@ -514,7 +514,20 @@ public final class IkeSaPayload extends IkePayload {
Transform[] decodeTransforms(int count, ByteBuffer inputBuffer) throws IkeProtocolException;
}
- // TODO: Add another constructor for building outbound message.
+ /**
+ * Release IPsec SPI resources in the outbound Create Child request
+ *
+ * <p>This method is usually called when an IKE library fails to receive a Create Child response
+ * before it is terminated. It is also safe to call after the Create Child exchange has
+ * succeeded because the newly created IpSecTransform pair will hold the IPsec SPI resource.
+ */
+ public void releaseChildSpiResourcesIfExists() {
+ for (Proposal proposal : proposalList) {
+ if (proposal instanceof ChildProposal) {
+ proposal.releaseSpiResourceIfExists();
+ }
+ }
+ }
/**
* This class represents the common information of an IKE Proposal and a Child Proposal.