]> git.proxmox.com Git - mirror_edk2.git/commitdiff
NetworkPkg: Support TCP Cancel function
authorJiaxin Wu <jiaxin.wu@intel.com>
Tue, 31 May 2016 14:17:26 +0000 (22:17 +0800)
committerJiaxin Wu <jiaxin.wu@intel.com>
Mon, 13 Jun 2016 03:51:35 +0000 (11:51 +0800)
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>
NetworkPkg/TcpDxe/SockImpl.c
NetworkPkg/TcpDxe/SockImpl.h
NetworkPkg/TcpDxe/SockInterface.c
NetworkPkg/TcpDxe/Socket.h
NetworkPkg/TcpDxe/TcpMain.c
NetworkPkg/TcpDxe/TcpMain.h

index f94155640229fcced1441755c0e5665817b276dc..35e0f6a662d1b28a1fb96a4460f98228ca22e9e5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implementation of the Socket.\r
 \r
-  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -574,6 +574,71 @@ SockWakeRcvToken (
   }\r
 }\r
 \r
+/**\r
+  Cancel the tokens in the specific token list.\r
+\r
+  @param[in]       Token                 Pointer to the Token. If NULL, all tokens \r
+                                         in SpecifiedTokenList will be canceled.  \r
+  @param[in, out]  SpecifiedTokenList    Pointer to the token list to be checked.\r
+  \r
+  @retval EFI_SUCCESS          Cancel the tokens in the specific token listsuccessfully.\r
+  @retval EFI_NOT_FOUND        The Token is not found in SpecifiedTokenList.\r
+  \r
+**/\r
+EFI_STATUS\r
+SockCancelToken (\r
+  IN     SOCK_COMPLETION_TOKEN  *Token,\r
+  IN OUT LIST_ENTRY             *SpecifiedTokenList\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  LIST_ENTRY     *Entry;\r
+  LIST_ENTRY     *Next;\r
+  SOCK_TOKEN     *SockToken;\r
+\r
+  Status    = EFI_SUCCESS;\r
+  Entry     = NULL;\r
+  Next      = NULL;\r
+  SockToken = NULL;\r
+\r
+  if (IsListEmpty (SpecifiedTokenList) && Token != NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
+  //\r
+  // Iterate through the SpecifiedTokenList.\r
+  //\r
+  Entry = SpecifiedTokenList->ForwardLink;\r
+  while (Entry != SpecifiedTokenList) {\r
+    SockToken = NET_LIST_USER_STRUCT (Entry, SOCK_TOKEN, TokenList);\r
+    \r
+    if (Token == NULL) {\r
+      SIGNAL_TOKEN (SockToken->Token, EFI_ABORTED);\r
+      RemoveEntryList (&SockToken->TokenList);\r
+      FreePool (SockToken);\r
+      \r
+      Entry = SpecifiedTokenList->ForwardLink;\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+      if (Token == (VOID *) SockToken->Token) {\r
+        SIGNAL_TOKEN (Token, EFI_ABORTED);\r
+        RemoveEntryList (&(SockToken->TokenList));\r
+        FreePool (SockToken);\r
+        \r
+        return EFI_SUCCESS;\r
+      }\r
+\r
+      Status = EFI_NOT_FOUND;\r
+      \r
+      Entry = Entry->ForwardLink;\r
+    } \r
+  }\r
+\r
+  ASSERT (IsListEmpty (SpecifiedTokenList) || Token != NULL);\r
+  \r
+  return Status;\r
+}\r
+\r
 /**\r
   Create a socket with initial data SockInitData.\r
 \r
index bb4f6c2085e73907be07e1dd9d3b102387d7c04b..5a067deb41944697e6867c7c787a00052bd50c4e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The function declaration that provided for Socket Interface.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -76,6 +76,23 @@ SockConnFlush (
   IN OUT SOCKET *Sock\r
   );\r
 \r
+/**\r
+  Cancel the tokens in the specific token list.\r
+\r
+  @param[in]       Token                 Pointer to the Token. If NULL, all tokens \r
+                                         in SpecifiedTokenList will be canceled.  \r
+  @param[in, out]  SpecifiedTokenList    Pointer to the token list to be checked.\r
+  \r
+  @retval EFI_SUCCESS          Cancel the tokens in the specific token listsuccessfully.\r
+  @retval EFI_NOT_FOUND        The Token is not found in SpecifiedTokenList.\r
+  \r
+**/\r
+EFI_STATUS\r
+SockCancelToken (\r
+  IN     SOCK_COMPLETION_TOKEN  *Token,\r
+  IN OUT LIST_ENTRY             *SpecifiedTokenList\r
+  );\r
+\r
 /**\r
   Create a socket with initial data SockInitData.\r
 \r
index 1f3524bc1b6baa33e005f152510bdcd93cc6a33a..1ae0c64b108a0fe421ec28de194b8ee932c33e4b 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Interface function of the Socket.\r
 \r
-  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -876,6 +876,96 @@ Exit:
   return Status;\r
 }\r
 \r
+/**\r
+  Abort the socket associated connection, listen, transmission or receive request.\r
+\r
+  @param[in, out]  Sock        Pointer to the socket to abort.\r
+  @param[in]       Token       Pointer to a token that has been issued by\r
+                               Connect(), Accept(), Transmit() or Receive(). If\r
+                               NULL, all pending tokens issued by the four\r
+                               functions listed above will be aborted.\r
+\r
+  @retval EFI_UNSUPPORTED      The operation is not supported in the current\r
+                               implementation.\r
+**/\r
+EFI_STATUS\r
+SockCancel (\r
+  IN OUT SOCKET  *Sock,\r
+  IN     VOID    *Token\r
+  ) \r
+{\r
+  EFI_STATUS     Status;\r
+\r
+  Status    = EFI_SUCCESS;\r
+\r
+  ASSERT (SockStream == Sock->Type);\r
+\r
+  Status = EfiAcquireLockOrFail (&(Sock->Lock));\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG (\r
+      (EFI_D_ERROR,\r
+      "SockCancel: Get the access for socket failed with %r",\r
+      Status)\r
+      );\r
+\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+\r
+  if (SOCK_IS_UNCONFIGURED (Sock)) {\r
+    Status = EFI_NOT_STARTED;\r
+    goto Exit;\r
+  }\r
+  \r
+  //\r
+  // 1. Check ConnectionToken.\r
+  //\r
+  if (Token == NULL || (SOCK_COMPLETION_TOKEN *) Token == Sock->ConnectionToken) {\r
+    if (Sock->ConnectionToken != NULL) {\r
+      SIGNAL_TOKEN (Sock->ConnectionToken, EFI_ABORTED);\r
+      Sock->ConnectionToken = NULL;\r
+    }\r
+\r
+    if (Token != NULL) {\r
+      Status = EFI_SUCCESS;\r
+      goto Exit;\r
+    }\r
+  }\r
+\r
+  //\r
+  // 2. Check ListenTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->ListenTokenList);\r
+  if (Token != NULL && !EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // 3. Check RcvTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->RcvTokenList);\r
+  if (Token != NULL && !EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+  \r
+  //\r
+  // 4. Check SndTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->SndTokenList);\r
+  if (Token != NULL && !EFI_ERROR (Status)) {\r
+    goto Exit;\r
+  }\r
+\r
+  //\r
+  // 5. Check ProcessingSndTokenList.\r
+  //\r
+  Status = SockCancelToken (Token, &Sock->ProcessingSndTokenList);\r
+  \r
+Exit:\r
+  EfiReleaseLock (&(Sock->Lock));\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Get the mode data of the low layer protocol.\r
 \r
index 5a63047f905bb6eb4633d3d447f126ef16ec37b7..371e9abd8455851f562f41aba6a5aed6b60a6516 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common head file for TCP socket.\r
 \r
-  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -864,6 +864,24 @@ SockClose (
   IN     BOOLEAN OnAbort\r
   );\r
 \r
+/**\r
+  Abort the socket associated connection, listen, transmission or receive request.\r
+\r
+  @param[in, out]  Sock        Pointer to the socket to abort.\r
+  @param[in]       Token       Pointer to a token that has been issued by\r
+                               Connect(), Accept(), Transmit() or Receive(). If\r
+                               NULL, all pending tokens issued by the four\r
+                               functions listed above will be aborted.\r
+\r
+  @retval EFI_UNSUPPORTED      The operation is not supported in the current\r
+                               implementation.\r
+**/\r
+EFI_STATUS\r
+SockCancel (\r
+  IN OUT SOCKET  *Sock,\r
+  IN     VOID    *Token\r
+  );\r
+\r
 /**\r
   Get the mode data of the low layer protocol.\r
 \r
index f79db48af30b6b8be68fd53121e055887a20fe2a..96a295a7fe309529dfa66eda90912b07f2d3b6bf 100644 (file)
@@ -2,7 +2,7 @@
   Implementation of EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL.\r
 \r
   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
-  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -484,14 +484,25 @@ Tcp4Close (
 /**\r
   Abort an asynchronous connection, listen, transmission or receive request.\r
 \r
-  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.\r
-  @param[in]  Token                Pointer to a token that has been issued by\r
-                                   Connect(), Accept(), Transmit() or Receive(). If\r
-                                   NULL, all pending tokens issued by the four\r
-                                   functions listed above will be aborted.\r
-\r
-  @retval EFI_UNSUPPORTED          The operation is not supported in the current\r
-                                   implementation.\r
+  @param  This  The pointer to the EFI_TCP4_PROTOCOL instance.\r
+  @param  Token The pointer to a token that has been issued by\r
+                EFI_TCP4_PROTOCOL.Connect(),\r
+                EFI_TCP4_PROTOCOL.Accept(),\r
+                EFI_TCP4_PROTOCOL.Transmit() or\r
+                EFI_TCP4_PROTOCOL.Receive(). If NULL, all pending\r
+                tokens issued by above four functions will be aborted. Type\r
+                EFI_TCP4_COMPLETION_TOKEN is defined in\r
+                EFI_TCP4_PROTOCOL.Connect().\r
+\r
+  @retval  EFI_SUCCESS             The asynchronous I/O request is aborted and Token->Event\r
+                                   is signaled.\r
+  @retval  EFI_INVALID_PARAMETER   This is NULL.\r
+  @retval  EFI_NOT_STARTED         This instance hasn't been configured.\r
+  @retval  EFI_NO_MAPPING          When using the default address, configuration\r
+                                   (DHCP, BOOTP,RARP, etc.) hasn't finished yet.\r
+  @retval  EFI_NOT_FOUND           The asynchronous I/O request isn't found in the\r
+                                   transmission or receive queue. It has either\r
+                                   completed or wasn't issued by Transmit() and Receive().\r
 \r
 **/\r
 EFI_STATUS\r
@@ -501,7 +512,15 @@ Tcp4Cancel (
   IN EFI_TCP4_COMPLETION_TOKEN     *Token OPTIONAL\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  SOCKET  *Sock;\r
+\r
+  if (NULL == This) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Sock = SOCK_FROM_THIS (This);\r
+\r
+  return SockCancel (Sock, Token);\r
 }\r
 \r
 /**\r
@@ -998,20 +1017,20 @@ Tcp6Close (
 }\r
 \r
 /**\r
-  Abort an asynchronous connection, listen, transmission, or receive request.\r
+  Abort an asynchronous connection, listen, transmission or receive request.\r
 \r
-  The Cancel() function aborts a pending connection, listen, transmit, or\r
+  The Cancel() function aborts a pending connection, listen, transmit or\r
   receive request.\r
 \r
-  If Token is not NULL and the token is in the connection, listen, transmission,\r
+  If Token is not NULL and the token is in the connection, listen, transmission\r
   or receive queue when it is being cancelled, its Token->Status will be set\r
-  to EFI_ABORTED, and then Token->Event will be signaled.\r
+  to EFI_ABORTED and then Token->Event will be signaled.\r
 \r
   If the token is not in one of the queues, which usually means that the\r
   asynchronous operation has completed, EFI_NOT_FOUND is returned.\r
 \r
   If Token is NULL all asynchronous token issued by Connect(), Accept(),\r
-  Transmit(), and Receive() will be aborted.\r
+  Transmit() and Receive() will be aborted.\r
 \r
   @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.\r
   @param[in] Token               Pointer to a token that has been issued by\r
@@ -1023,7 +1042,13 @@ Tcp6Close (
                                  EFI_TCP6_COMPLETION_TOKEN is defined in\r
                                  EFI_TCP_PROTOCOL.Connect().\r
 \r
-  @retval EFI_UNSUPPORTED        The implementation does not support this function.\r
+  @retval EFI_SUCCESS            The asynchronous I/O request is aborted and Token->Event\r
+                                 is signaled.\r
+  @retval EFI_INVALID_PARAMETER  This is NULL.\r
+  @retval EFI_NOT_STARTED        This instance hasn't been configured.\r
+  @retval EFI_NOT_FOUND          The asynchronous I/O request isn't found in the transmission or\r
+                                 receive queue. It has either completed or wasn't issued by\r
+                                 Transmit() and Receive().\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1033,7 +1058,15 @@ Tcp6Cancel (
   IN EFI_TCP6_COMPLETION_TOKEN   *Token OPTIONAL\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  SOCKET  *Sock;\r
+\r
+  if (NULL == This) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Sock = SOCK_FROM_THIS (This);\r
+\r
+  return SockCancel (Sock, Token);\r
 }\r
 \r
 /**\r
index bd4434e26bea255ca2fb94e6f74ac3c9a827ae67..c10030174b85fe25c121eceb19154a2c22b115cf 100644 (file)
@@ -2,7 +2,7 @@
   Declaration of protocol interfaces in EFI_TCP4_PROTOCOL and EFI_TCP6_PROTOCOL.\r
   It is the common head file for all Tcp*.c in TCP driver.\r
 \r
-  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -359,14 +359,25 @@ Tcp4Close (
 /**\r
   Abort an asynchronous connection, listen, transmission or receive request.\r
 \r
-  @param[in]  This                 Pointer to the EFI_TCP4_PROTOCOL instance.\r
-  @param[in]  Token                Pointer to a token that has been issued by\r
-                                   Connect(), Accept(), Transmit() or Receive(). If\r
-                                   NULL, all pending tokens issued by the above four\r
-                                   functions will be aborted.\r
-\r
-  @retval EFI_UNSUPPORTED          The operation is not supported in the current\r
-                                   implementation.\r
+  @param  This  The pointer to the EFI_TCP4_PROTOCOL instance.\r
+  @param  Token The pointer to a token that has been issued by\r
+                EFI_TCP4_PROTOCOL.Connect(),\r
+                EFI_TCP4_PROTOCOL.Accept(),\r
+                EFI_TCP4_PROTOCOL.Transmit() or\r
+                EFI_TCP4_PROTOCOL.Receive(). If NULL, all pending\r
+                tokens issued by above four functions will be aborted. Type\r
+                EFI_TCP4_COMPLETION_TOKEN is defined in\r
+                EFI_TCP4_PROTOCOL.Connect().\r
+\r
+  @retval  EFI_SUCCESS             The asynchronous I/O request is aborted and Token->Event\r
+                                   is signaled.\r
+  @retval  EFI_INVALID_PARAMETER   This is NULL.\r
+  @retval  EFI_NOT_STARTED         This instance hasn't been configured.\r
+  @retval  EFI_NO_MAPPING          When using the default address, configuration\r
+                                   (DHCP, BOOTP,RARP, etc.) hasn't finished yet.\r
+  @retval  EFI_NOT_FOUND           The asynchronous I/O request isn't found in the\r
+                                   transmission or receive queue. It has either\r
+                                   completed or wasn't issued by Transmit() and Receive().\r
 \r
 **/\r
 EFI_STATUS\r
@@ -730,7 +741,13 @@ Tcp6Close (
                                  EFI_TCP6_COMPLETION_TOKEN is defined in\r
                                  EFI_TCP_PROTOCOL.Connect().\r
 \r
-  @retval EFI_UNSUPPORTED        The implementation does not support this function.\r
+  @retval EFI_SUCCESS            The asynchronous I/O request is aborted and Token->Event\r
+                                 is signaled.\r
+  @retval EFI_INVALID_PARAMETER  This is NULL.\r
+  @retval EFI_NOT_STARTED        This instance hasn't been configured.\r
+  @retval EFI_NOT_FOUND          The asynchronous I/O request isn't found in the transmission or\r
+                                 receive queue. It has either completed or wasn't issued by\r
+                                 Transmit() and Receive().\r
 \r
 **/\r
 EFI_STATUS\r