diff options
author | Yan Yan <evitayan@google.com> | 2020-05-19 19:50:49 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-05-19 19:50:49 +0000 |
commit | a854e9f375d28b2a917e6de16c7219d1341958d9 (patch) | |
tree | 4b0b983dfc75e695183e2519ca46166f23074ffd | |
parent | 73506b587efde77cb502d9f166a0d453d5666e42 (diff) | |
parent | c1ed950ddad2bd565c4bb2e3109c2240959d1852 (diff) | |
download | ike-a854e9f375d28b2a917e6de16c7219d1341958d9.tar.gz |
Merge "Release IPsec SPI if not receiving Create Child Response"
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. |