/** @file\r
Interface function of the Socket.\r
\r
- Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2018, 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
IN OUT SOCKET *Sock\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ TCP_PROTO_DATA *ProtoData;\r
+ TCP_CB *Tcb;\r
+ EFI_GUID *IpProtocolGuid;\r
+ EFI_GUID *TcpProtocolGuid;\r
+ VOID *SockProtocol;\r
\r
ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));\r
\r
\r
Sock->InDestroy = TRUE;\r
\r
+ if (Sock->IpVersion == IP_VERSION_4) {\r
+ IpProtocolGuid = &gEfiIp4ProtocolGuid;\r
+ TcpProtocolGuid = &gEfiTcp4ProtocolGuid;\r
+ } else {\r
+ IpProtocolGuid = &gEfiIp6ProtocolGuid;\r
+ TcpProtocolGuid = &gEfiTcp6ProtocolGuid;\r
+ }\r
+ ProtoData = (TCP_PROTO_DATA *) Sock->ProtoReserved;\r
+ Tcb = ProtoData->TcpPcb;\r
+\r
+ ASSERT (Tcb != NULL);\r
+\r
+ //\r
+ // Close the IP protocol.\r
+ //\r
+ gBS->CloseProtocol (\r
+ Tcb->IpInfo->ChildHandle,\r
+ IpProtocolGuid,\r
+ ProtoData->TcpService->IpIo->Image,\r
+ Sock->SockHandle\r
+ );\r
+\r
+ if (Sock->DestroyCallback != NULL) {\r
+ Sock->DestroyCallback (Sock, Sock->Context);\r
+ }\r
+\r
+ //\r
+ // Retrieve the protocol installed on this sock\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Sock->SockHandle,\r
+ TcpProtocolGuid,\r
+ &SockProtocol,\r
+ Sock->DriverBinding,\r
+ Sock->SockHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+\r
+ DEBUG (\r
+ (EFI_D_ERROR,\r
+ "SockDestroyChild: Open protocol installed on socket failed with %r\n",\r
+ Status)\r
+ );\r
+ }\r
+\r
+ //\r
+ // Uninstall the protocol installed on this sock\r
+ //\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Sock->SockHandle,\r
+ TcpProtocolGuid,\r
+ SockProtocol,\r
+ NULL\r
+ );\r
+\r
+\r
Status = EfiAcquireLockOrFail (&(Sock->Lock));\r
if (EFI_ERROR (Status)) {\r
\r
{\r
SOCKET *Sock;\r
EFI_STATUS Status;\r
+ VOID *SockProtocol;\r
+ EFI_GUID *TcpProtocolGuid;\r
\r
//\r
// create a new socket\r
"SockCreateChild: Get the lock to access socket failed with %r\n",\r
Status)\r
);\r
-\r
- SockDestroy (Sock);\r
- return NULL;\r
+ goto ERROR;\r
}\r
//\r
// inform the protocol layer to attach the socket\r
"SockCreateChild: Protocol failed to attach a socket with %r\n",\r
Status)\r
);\r
-\r
- SockDestroy (Sock);\r
- Sock = NULL;\r
+ goto ERROR;\r
}\r
\r
return Sock;\r
+\r
+ERROR:\r
+\r
+ if (Sock->DestroyCallback != NULL) {\r
+ Sock->DestroyCallback (Sock, Sock->Context);\r
+ }\r
+\r
+ if (Sock->IpVersion == IP_VERSION_4) {\r
+ TcpProtocolGuid = &gEfiTcp4ProtocolGuid;\r
+ } else {\r
+ TcpProtocolGuid = &gEfiTcp6ProtocolGuid;\r
+ }\r
+\r
+ gBS->OpenProtocol (\r
+ Sock->SockHandle,\r
+ TcpProtocolGuid,\r
+ &SockProtocol,\r
+ Sock->DriverBinding,\r
+ Sock->SockHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ //\r
+ // Uninstall the protocol installed on this sock\r
+ //\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Sock->SockHandle,\r
+ TcpProtocolGuid,\r
+ SockProtocol,\r
+ NULL\r
+ );\r
+ SockDestroy (Sock);\r
+ return NULL;\r
}\r
\r
/**\r
Socket->Parent->ConnCnt--;\r
\r
DEBUG (\r
- (EFI_D_INFO,\r
+ (EFI_D_NET,\r
"SockAccept: Accept a socket, now conncount is %d",\r
Socket->Parent->ConnCnt)\r
);\r
}\r
\r
if (RcvdBytes != 0) {\r
- Status = SockProcessRcvToken (Sock, RcvToken);\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto Exit;\r
- }\r
+ SockProcessRcvToken (Sock, RcvToken);\r
\r
Status = Sock->ProtoHandler (Sock, SOCK_CONSUMED, NULL);\r
} else {\r
}\r
\r
/**\r
- Get the mode data of the low layer protocol.\r
+ Abort the socket associated connection, listen, transmission or receive request.\r
\r
- @param[in] Sock Pointer to the socket to get mode data from.\r
- @param[in, out] Mode Pointer to the data to store the low layer mode\r
- information.\r
-\r
- @retval EFI_SUCCESS The mode data was obtained successfully.\r
- @retval EFI_NOT_STARTED The socket is not configured.\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
-SockGetMode (\r
- IN SOCKET *Sock,\r
- IN OUT VOID *Mode\r
+SockCancel (\r
+ IN OUT SOCKET *Sock,\r
+ IN VOID *Token\r
)\r
{\r
- return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);\r
-}\r
-\r
-/**\r
- Configure the low level protocol to join a multicast group for\r
- this socket's connection.\r
+ EFI_STATUS Status;\r
\r
- @param[in] Sock Pointer to the socket of the connection to join the\r
- specific multicast group.\r
- @param[in] GroupInfo Pointer to the multicast group info.\r
+ Status = EFI_SUCCESS;\r
\r
- @retval EFI_SUCCESS The configuration completed successfully.\r
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.\r
- @retval EFI_NOT_STARTED The socket is not configured.\r
-\r
-**/\r
-EFI_STATUS\r
-SockGroup (\r
- IN SOCKET *Sock,\r
- IN VOID *GroupInfo\r
- )\r
-{\r
- EFI_STATUS Status;\r
+ ASSERT (SockStream == Sock->Type);\r
\r
Status = EfiAcquireLockOrFail (&(Sock->Lock));\r
-\r
if (EFI_ERROR (Status)) {\r
-\r
DEBUG (\r
(EFI_D_ERROR,\r
- "SockGroup: Get the access for socket failed with %r",\r
+ "SockCancel: Get the access for socket failed with %r",\r
Status)\r
);\r
\r
goto Exit;\r
}\r
\r
- Status = Sock->ProtoHandler (Sock, SOCK_GROUP, GroupInfo);\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
+ @param[in] Sock Pointer to the socket to get mode data from.\r
+ @param[in, out] Mode Pointer to the data to store the low layer mode\r
+ information.\r
+\r
+ @retval EFI_SUCCESS The mode data was obtained successfully.\r
+ @retval EFI_NOT_STARTED The socket is not configured.\r
+\r
+**/\r
+EFI_STATUS\r
+SockGetMode (\r
+ IN SOCKET *Sock,\r
+ IN OUT VOID *Mode\r
+ )\r
+{\r
+ return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);\r
+}\r
+\r
/**\r
Add or remove route information in IP route table associated\r
with this socket.\r