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