NetworkPkg: Support TCP Cancel function

This path is used to support TCP Cancel function to abort an
asynchronous connection, listen, transmission or receive request.

If any TCP CompletionToken is not signaled, it should not be closed
directly by calling CloseEvent (Still in the TCP TokenList). If not,
any exception behavior may be triggered. We should cancel it by calling
Tcp->Cancel() first. In such a case, TCP Cancel function is
necessary.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
Cc: Gary Lin <glin@suse.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Gary Lin <glin@suse.com>
Reviewed-by: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
Reviewed-by: Ye Ting <ting.ye@intel.com>
Tested-by: Gary Lin <glin@suse.com>
Tested-by: Hegde Nagaraj P <nagaraj-p.hegde@hpe.com>
This commit is contained in:
Jiaxin Wu
2016-05-31 22:17:26 +08:00
parent 3b5624b014
commit 5ffe214ae9
6 changed files with 269 additions and 29 deletions

View File

@@ -1,7 +1,7 @@
/** @file
Implementation of the Socket.
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -574,6 +574,71 @@ SockWakeRcvToken (
}
}
/**
Cancel the tokens in the specific token list.
@param[in] Token Pointer to the Token. If NULL, all tokens
in SpecifiedTokenList will be canceled.
@param[in, out] SpecifiedTokenList Pointer to the token list to be checked.
@retval EFI_SUCCESS Cancel the tokens in the specific token listsuccessfully.
@retval EFI_NOT_FOUND The Token is not found in SpecifiedTokenList.
**/
EFI_STATUS
SockCancelToken (
IN SOCK_COMPLETION_TOKEN *Token,
IN OUT LIST_ENTRY *SpecifiedTokenList
)
{
EFI_STATUS Status;
LIST_ENTRY *Entry;
LIST_ENTRY *Next;
SOCK_TOKEN *SockToken;
Status = EFI_SUCCESS;
Entry = NULL;
Next = NULL;
SockToken = NULL;
if (IsListEmpty (SpecifiedTokenList) && Token != NULL) {
return EFI_NOT_FOUND;
}
//
// Iterate through the SpecifiedTokenList.
//
Entry = SpecifiedTokenList->ForwardLink;
while (Entry != SpecifiedTokenList) {
SockToken = NET_LIST_USER_STRUCT (Entry, SOCK_TOKEN, TokenList);
if (Token == NULL) {
SIGNAL_TOKEN (SockToken->Token, EFI_ABORTED);
RemoveEntryList (&SockToken->TokenList);
FreePool (SockToken);
Entry = SpecifiedTokenList->ForwardLink;
Status = EFI_SUCCESS;
} else {
if (Token == (VOID *) SockToken->Token) {
SIGNAL_TOKEN (Token, EFI_ABORTED);
RemoveEntryList (&(SockToken->TokenList));
FreePool (SockToken);
return EFI_SUCCESS;
}
Status = EFI_NOT_FOUND;
Entry = Entry->ForwardLink;
}
}
ASSERT (IsListEmpty (SpecifiedTokenList) || Token != NULL);
return Status;
}
/**
Create a socket with initial data SockInitData.