12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082 |
- /** @file
- Interface function of the Socket.
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "SockImpl.h"
- /**
- Check whether the Event is in the List.
- @param[in] List Pointer to the token list to be searched.
- @param[in] Event The event to be checked.
- @retval TRUE The specific Event exists in the List.
- @retval FALSE The specific Event is not in the List.
- **/
- BOOLEAN
- SockTokenExistedInList (
- IN LIST_ENTRY *List,
- IN EFI_EVENT Event
- )
- {
- LIST_ENTRY *ListEntry;
- SOCK_TOKEN *SockToken;
- NET_LIST_FOR_EACH (ListEntry, List) {
- SockToken = NET_LIST_USER_STRUCT (
- ListEntry,
- SOCK_TOKEN,
- TokenList
- );
- if (Event == SockToken->Token->Event) {
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- Call SockTokenExistedInList() to check whether the Event is
- in the related socket's lists.
- @param[in] Sock Pointer to the instance's socket.
- @param[in] Event The event to be checked.
- @retval TRUE The Event exists in related socket's lists.
- @retval FALSE The Event is not in related socket's lists.
- **/
- BOOLEAN
- SockTokenExisted (
- IN SOCKET *Sock,
- IN EFI_EVENT Event
- )
- {
- if (SockTokenExistedInList (&Sock->SndTokenList, Event) ||
- SockTokenExistedInList (&Sock->ProcessingSndTokenList, Event) ||
- SockTokenExistedInList (&Sock->RcvTokenList, Event) ||
- SockTokenExistedInList (&Sock->ListenTokenList, Event)
- )
- {
- return TRUE;
- }
- if ((Sock->ConnectionToken != NULL) && (Sock->ConnectionToken->Event == Event)) {
- return TRUE;
- }
- if ((Sock->CloseToken != NULL) && (Sock->CloseToken->Event == Event)) {
- return TRUE;
- }
- return FALSE;
- }
- /**
- Buffer a token into the specific list of the socket Sock.
- @param[in] Sock Pointer to the instance's socket.
- @param[in] List Pointer to the list to store the token.
- @param[in] Token Pointer to the token to be buffered.
- @param[in] DataLen The data length of the buffer contained in Token.
- @return Pointer to the token that wraps Token. If NULL, an error condition occurred.
- **/
- SOCK_TOKEN *
- SockBufferToken (
- IN SOCKET *Sock,
- IN LIST_ENTRY *List,
- IN VOID *Token,
- IN UINT32 DataLen
- )
- {
- SOCK_TOKEN *SockToken;
- SockToken = AllocateZeroPool (sizeof (SOCK_TOKEN));
- if (NULL == SockToken) {
- DEBUG (
- (DEBUG_ERROR,
- "SockBufferIOToken: No Memory to allocate SockToken\n")
- );
- return NULL;
- }
- SockToken->Sock = Sock;
- SockToken->Token = (SOCK_COMPLETION_TOKEN *)Token;
- SockToken->RemainDataLen = DataLen;
- InsertTailList (List, &SockToken->TokenList);
- return SockToken;
- }
- /**
- Destroy the socket Sock and its associated protocol control block.
- @param[in, out] Sock The socket to be destroyed.
- @retval EFI_SUCCESS The socket Sock was destroyed successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
- **/
- EFI_STATUS
- SockDestroyChild (
- IN OUT SOCKET *Sock
- )
- {
- EFI_STATUS Status;
- TCP_PROTO_DATA *ProtoData;
- TCP_CB *Tcb;
- EFI_GUID *IpProtocolGuid;
- EFI_GUID *TcpProtocolGuid;
- VOID *SockProtocol;
- ASSERT ((Sock != NULL) && (Sock->ProtoHandler != NULL));
- if (Sock->InDestroy) {
- return EFI_SUCCESS;
- }
- Sock->InDestroy = TRUE;
- if (Sock->IpVersion == IP_VERSION_4) {
- IpProtocolGuid = &gEfiIp4ProtocolGuid;
- TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
- } else {
- IpProtocolGuid = &gEfiIp6ProtocolGuid;
- TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
- }
- ProtoData = (TCP_PROTO_DATA *)Sock->ProtoReserved;
- Tcb = ProtoData->TcpPcb;
- ASSERT (Tcb != NULL);
- //
- // Close the IP protocol.
- //
- gBS->CloseProtocol (
- Tcb->IpInfo->ChildHandle,
- IpProtocolGuid,
- ProtoData->TcpService->IpIo->Image,
- Sock->SockHandle
- );
- if (Sock->DestroyCallback != NULL) {
- Sock->DestroyCallback (Sock, Sock->Context);
- }
- //
- // Retrieve the protocol installed on this sock
- //
- Status = gBS->OpenProtocol (
- Sock->SockHandle,
- TcpProtocolGuid,
- &SockProtocol,
- Sock->DriverBinding,
- Sock->SockHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockDestroyChild: Open protocol installed on socket failed with %r\n",
- Status)
- );
- }
- //
- // Uninstall the protocol installed on this sock
- //
- gBS->UninstallMultipleProtocolInterfaces (
- Sock->SockHandle,
- TcpProtocolGuid,
- SockProtocol,
- NULL
- );
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockDestroyChild: Get the lock to access socket failed with %r\n",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- //
- // force protocol layer to detach the PCB
- //
- Status = Sock->ProtoHandler (Sock, SOCK_DETACH, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockDestroyChild: Protocol detach socket failed with %r\n",
- Status)
- );
- Sock->InDestroy = FALSE;
- } else if (SOCK_IS_CONFIGURED (Sock)) {
- SockConnFlush (Sock);
- SockSetState (Sock, SO_CLOSED);
- Sock->ConfigureState = SO_UNCONFIGURED;
- }
- EfiReleaseLock (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- return Status;
- }
- SockDestroy (Sock);
- return EFI_SUCCESS;
- }
- /**
- Create a socket and its associated protocol control block
- with the initial data SockInitData and protocol specific
- data ProtoData.
- @param[in] SockInitData Initial data to setting the socket.
- @return Pointer to the newly created socket. If NULL, an error condition occurred.
- **/
- SOCKET *
- SockCreateChild (
- IN SOCK_INIT_DATA *SockInitData
- )
- {
- SOCKET *Sock;
- EFI_STATUS Status;
- VOID *SockProtocol;
- EFI_GUID *TcpProtocolGuid;
- //
- // create a new socket
- //
- Sock = SockCreate (SockInitData);
- if (NULL == Sock) {
- DEBUG (
- (DEBUG_ERROR,
- "SockCreateChild: No resource to create a new socket\n")
- );
- return NULL;
- }
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockCreateChild: Get the lock to access socket failed with %r\n",
- Status)
- );
- goto ERROR;
- }
- //
- // inform the protocol layer to attach the socket
- // with a new protocol control block
- //
- Status = Sock->ProtoHandler (Sock, SOCK_ATTACH, NULL);
- EfiReleaseLock (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockCreateChild: Protocol failed to attach a socket with %r\n",
- Status)
- );
- goto ERROR;
- }
- return Sock;
- ERROR:
- if (Sock->DestroyCallback != NULL) {
- Sock->DestroyCallback (Sock, Sock->Context);
- }
- if (Sock->IpVersion == IP_VERSION_4) {
- TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
- } else {
- TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
- }
- gBS->OpenProtocol (
- Sock->SockHandle,
- TcpProtocolGuid,
- &SockProtocol,
- Sock->DriverBinding,
- Sock->SockHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- //
- // Uninstall the protocol installed on this sock
- //
- gBS->UninstallMultipleProtocolInterfaces (
- Sock->SockHandle,
- TcpProtocolGuid,
- SockProtocol,
- NULL
- );
- SockDestroy (Sock);
- return NULL;
- }
- /**
- Configure the specific socket Sock using configuration data ConfigData.
- @param[in] Sock Pointer to the socket to be configured.
- @param[in] ConfigData Pointer to the configuration data.
- @retval EFI_SUCCESS The socket configured successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
- socket is already configured.
- **/
- EFI_STATUS
- SockConfigure (
- IN SOCKET *Sock,
- IN VOID *ConfigData
- )
- {
- EFI_STATUS Status;
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockConfigure: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_CONFIGURED (Sock)) {
- Status = EFI_ACCESS_DENIED;
- goto OnExit;
- }
- ASSERT (Sock->State == SO_CLOSED);
- Status = Sock->ProtoHandler (Sock, SOCK_CONFIGURE, ConfigData);
- OnExit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
- /**
- Initiate a connection establishment process.
- @param[in] Sock Pointer to the socket to initiate the
- connection.
- @param[in] Token Pointer to the token used for the connection
- operation.
- @retval EFI_SUCCESS The connection initialized successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
- socket is closed, or the socket is not configured to
- be an active one, or the token is already in one of
- this socket's lists.
- @retval EFI_NO_MAPPING The IP address configuration operation is not
- finished.
- @retval EFI_NOT_STARTED The socket is not configured.
- **/
- EFI_STATUS
- SockConnect (
- IN SOCKET *Sock,
- IN VOID *Token
- )
- {
- EFI_STATUS Status;
- EFI_EVENT Event;
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockConnect: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_NO_MAPPING (Sock)) {
- Status = EFI_NO_MAPPING;
- goto OnExit;
- }
- if (SOCK_IS_UNCONFIGURED (Sock)) {
- Status = EFI_NOT_STARTED;
- goto OnExit;
- }
- if (!SOCK_IS_CLOSED (Sock) || !SOCK_IS_CONFIGURED_ACTIVE (Sock)) {
- Status = EFI_ACCESS_DENIED;
- goto OnExit;
- }
- Event = ((SOCK_COMPLETION_TOKEN *)Token)->Event;
- if (SockTokenExisted (Sock, Event)) {
- Status = EFI_ACCESS_DENIED;
- goto OnExit;
- }
- Sock->ConnectionToken = (SOCK_COMPLETION_TOKEN *)Token;
- SockSetState (Sock, SO_CONNECTING);
- Status = Sock->ProtoHandler (Sock, SOCK_CONNECT, NULL);
- OnExit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
- /**
- Issue a listen token to get an existed connected network instance
- or wait for a connection if there is none.
- @param[in] Sock Pointer to the socket to accept connections.
- @param[in] Token The token to accept a connection.
- @retval EFI_SUCCESS Either a connection is accepted or the Token is
- buffered for further acception.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
- socket is closed, or the socket is not configured to
- be a passive one, or the token is already in one of
- this socket's lists.
- @retval EFI_NO_MAPPING The IP address configuration operation is not
- finished.
- @retval EFI_NOT_STARTED The socket is not configured.
- @retval EFI_OUT_OF_RESOURCE Failed to buffer the Token due to memory limits.
- **/
- EFI_STATUS
- SockAccept (
- IN SOCKET *Sock,
- IN VOID *Token
- )
- {
- EFI_TCP4_LISTEN_TOKEN *ListenToken;
- LIST_ENTRY *ListEntry;
- EFI_STATUS Status;
- SOCKET *Socket;
- EFI_EVENT Event;
- ASSERT (SockStream == Sock->Type);
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockAccept: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_NO_MAPPING (Sock)) {
- Status = EFI_NO_MAPPING;
- goto Exit;
- }
- if (SOCK_IS_UNCONFIGURED (Sock)) {
- Status = EFI_NOT_STARTED;
- goto Exit;
- }
- if (!SOCK_IS_LISTENING (Sock)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- Event = ((SOCK_COMPLETION_TOKEN *)Token)->Event;
- if (SockTokenExisted (Sock, Event)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- ListenToken = (EFI_TCP4_LISTEN_TOKEN *)Token;
- //
- // Check if a connection has already in this Sock->ConnectionList
- //
- NET_LIST_FOR_EACH (ListEntry, &Sock->ConnectionList) {
- Socket = NET_LIST_USER_STRUCT (ListEntry, SOCKET, ConnectionList);
- if (SOCK_IS_CONNECTED (Socket)) {
- ListenToken->NewChildHandle = Socket->SockHandle;
- SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
- RemoveEntryList (ListEntry);
- ASSERT (Socket->Parent != NULL);
- Socket->Parent->ConnCnt--;
- DEBUG (
- (DEBUG_NET,
- "SockAccept: Accept a socket, now conncount is %d",
- Socket->Parent->ConnCnt)
- );
- Socket->Parent = NULL;
- goto Exit;
- }
- }
- //
- // Buffer this token for latter incoming connection request
- //
- if (NULL == SockBufferToken (Sock, &(Sock->ListenTokenList), Token, 0)) {
- Status = EFI_OUT_OF_RESOURCES;
- }
- Exit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
- /**
- Issue a token with data to the socket to send out.
- @param[in] Sock Pointer to the socket to process the token with
- data.
- @param[in] Token The token with data that needs to send out.
- @retval EFI_SUCCESS The token processed successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
- socket is closed, or the socket is not in a
- synchronized state , or the token is already in one
- of this socket's lists.
- @retval EFI_NO_MAPPING The IP address configuration operation is not
- finished.
- @retval EFI_NOT_STARTED The socket is not configured.
- @retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limits.
- **/
- EFI_STATUS
- SockSend (
- IN SOCKET *Sock,
- IN VOID *Token
- )
- {
- SOCK_IO_TOKEN *SndToken;
- EFI_EVENT Event;
- UINT32 FreeSpace;
- EFI_TCP4_TRANSMIT_DATA *TxData;
- EFI_STATUS Status;
- SOCK_TOKEN *SockToken;
- UINT32 DataLen;
- ASSERT (SockStream == Sock->Type);
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockSend: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_NO_MAPPING (Sock)) {
- Status = EFI_NO_MAPPING;
- goto Exit;
- }
- SndToken = (SOCK_IO_TOKEN *)Token;
- TxData = (EFI_TCP4_TRANSMIT_DATA *)SndToken->Packet.TxData;
- if (SOCK_IS_UNCONFIGURED (Sock)) {
- Status = EFI_NOT_STARTED;
- goto Exit;
- }
- if (!(SOCK_IS_CONNECTING (Sock) || SOCK_IS_CONNECTED (Sock))) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- //
- // check if a token is already in the token buffer
- //
- Event = SndToken->Token.Event;
- if (SockTokenExisted (Sock, Event)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- DataLen = TxData->DataLength;
- //
- // process this sending token now or buffer it only?
- //
- FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
- if ((FreeSpace < Sock->SndBuffer.LowWater) || !SOCK_IS_CONNECTED (Sock)) {
- SockToken = SockBufferToken (
- Sock,
- &Sock->SndTokenList,
- SndToken,
- DataLen
- );
- if (NULL == SockToken) {
- Status = EFI_OUT_OF_RESOURCES;
- }
- } else {
- SockToken = SockBufferToken (
- Sock,
- &Sock->ProcessingSndTokenList,
- SndToken,
- DataLen
- );
- if (NULL == SockToken) {
- DEBUG ((DEBUG_ERROR, "SockSend: Failed to buffer IO token into socket processing SndToken List\n"));
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
- Status = SockProcessTcpSndData (Sock, TxData);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "SockSend: Failed to process Snd Data\n"));
- RemoveEntryList (&(SockToken->TokenList));
- FreePool (SockToken);
- }
- }
- Exit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
- /**
- Issue a token to get data from the socket.
- @param[in] Sock Pointer to the socket to get data from.
- @param[in] Token The token to store the received data from the
- socket.
- @retval EFI_SUCCESS The token processed successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
- socket is closed, or the socket is not in a
- synchronized state , or the token is already in one
- of this socket's lists.
- @retval EFI_NO_MAPPING The IP address configuration operation is not
- finished.
- @retval EFI_NOT_STARTED The socket is not configured.
- @retval EFI_CONNECTION_FIN The connection is closed and there is no more data.
- @retval EFI_OUT_OF_RESOURCE Failed to buffer the token due to memory limit.
- **/
- EFI_STATUS
- SockRcv (
- IN SOCKET *Sock,
- IN VOID *Token
- )
- {
- SOCK_IO_TOKEN *RcvToken;
- UINT32 RcvdBytes;
- EFI_STATUS Status;
- EFI_EVENT Event;
- ASSERT (SockStream == Sock->Type);
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockRcv: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_NO_MAPPING (Sock)) {
- Status = EFI_NO_MAPPING;
- goto Exit;
- }
- if (SOCK_IS_UNCONFIGURED (Sock)) {
- Status = EFI_NOT_STARTED;
- goto Exit;
- }
- if (!(SOCK_IS_CONNECTED (Sock) || SOCK_IS_CONNECTING (Sock))) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- RcvToken = (SOCK_IO_TOKEN *)Token;
- //
- // check if a token is already in the token buffer of this socket
- //
- Event = RcvToken->Token.Event;
- if (SockTokenExisted (Sock, Event)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- RcvToken = (SOCK_IO_TOKEN *)Token;
- RcvdBytes = GET_RCV_DATASIZE (Sock);
- //
- // check whether an error has happened before
- //
- if (EFI_ABORTED != Sock->SockError) {
- SIGNAL_TOKEN (&(RcvToken->Token), Sock->SockError);
- Sock->SockError = EFI_ABORTED;
- goto Exit;
- }
- //
- // check whether can not receive and there is no any
- // data buffered in Sock->RcvBuffer
- //
- if (SOCK_IS_NO_MORE_DATA (Sock) && (0 == RcvdBytes)) {
- Status = EFI_CONNECTION_FIN;
- goto Exit;
- }
- if (RcvdBytes != 0) {
- SockProcessRcvToken (Sock, RcvToken);
- Status = Sock->ProtoHandler (Sock, SOCK_CONSUMED, NULL);
- } else {
- if (NULL == SockBufferToken (Sock, &Sock->RcvTokenList, RcvToken, 0)) {
- Status = EFI_OUT_OF_RESOURCES;
- }
- }
- Exit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
- /**
- Reset the socket and its associated protocol control block.
- @param[in, out] Sock Pointer to the socket to be flushed.
- @retval EFI_SUCCESS The socket is flushed successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
- **/
- EFI_STATUS
- SockFlush (
- IN OUT SOCKET *Sock
- )
- {
- EFI_STATUS Status;
- ASSERT (SockStream == Sock->Type);
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockFlush: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (!SOCK_IS_CONFIGURED (Sock)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- Status = Sock->ProtoHandler (Sock, SOCK_FLUSH, NULL);
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockFlush: Protocol failed handling SOCK_FLUSH with %r",
- Status)
- );
- goto Exit;
- }
- SOCK_ERROR (Sock, EFI_ABORTED);
- SockConnFlush (Sock);
- SockSetState (Sock, SO_CLOSED);
- Sock->ConfigureState = SO_UNCONFIGURED;
- Exit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
- /**
- Close or abort the socket associated connection.
- @param[in, out] Sock Pointer to the socket of the connection to close
- or abort.
- @param[in] Token The token for a close operation.
- @param[in] OnAbort TRUE for aborting the connection; FALSE to close it.
- @retval EFI_SUCCESS The close or abort operation initialized
- successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket, or the
- socket is closed, or the socket is not in a
- synchronized state , or the token is already in one
- of this socket's lists.
- @retval EFI_NO_MAPPING The IP address configuration operation is not
- finished.
- @retval EFI_NOT_STARTED The socket is not configured.
- **/
- EFI_STATUS
- SockClose (
- IN OUT SOCKET *Sock,
- IN VOID *Token,
- IN BOOLEAN OnAbort
- )
- {
- EFI_STATUS Status;
- EFI_EVENT Event;
- ASSERT (SockStream == Sock->Type);
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockClose: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_NO_MAPPING (Sock)) {
- Status = EFI_NO_MAPPING;
- goto Exit;
- }
- if (SOCK_IS_UNCONFIGURED (Sock)) {
- Status = EFI_NOT_STARTED;
- goto Exit;
- }
- if (SOCK_IS_DISCONNECTING (Sock)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- Event = ((SOCK_COMPLETION_TOKEN *)Token)->Event;
- if (SockTokenExisted (Sock, Event)) {
- Status = EFI_ACCESS_DENIED;
- goto Exit;
- }
- Sock->CloseToken = Token;
- SockSetState (Sock, SO_DISCONNECTING);
- if (OnAbort) {
- Status = Sock->ProtoHandler (Sock, SOCK_ABORT, NULL);
- } else {
- Status = Sock->ProtoHandler (Sock, SOCK_CLOSE, NULL);
- }
- Exit:
- EfiReleaseLock (&(Sock->Lock));
- 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 (
- (DEBUG_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.
- @param[in] Sock Pointer to the socket to get mode data from.
- @param[in, out] Mode Pointer to the data to store the low layer mode
- information.
- @retval EFI_SUCCESS The mode data was obtained successfully.
- @retval EFI_NOT_STARTED The socket is not configured.
- **/
- EFI_STATUS
- SockGetMode (
- IN SOCKET *Sock,
- IN OUT VOID *Mode
- )
- {
- return Sock->ProtoHandler (Sock, SOCK_MODE, Mode);
- }
- /**
- Add or remove route information in IP route table associated
- with this socket.
- @param[in] Sock Pointer to the socket associated with the IP route
- table to operate on.
- @param[in] RouteInfo Pointer to the route information to be processed.
- @retval EFI_SUCCESS The route table updated successfully.
- @retval EFI_ACCESS_DENIED Failed to get the lock to access the socket.
- @retval EFI_NO_MAPPING The IP address configuration operation is not
- finished.
- @retval EFI_NOT_STARTED The socket is not configured.
- **/
- EFI_STATUS
- SockRoute (
- IN SOCKET *Sock,
- IN VOID *RouteInfo
- )
- {
- EFI_STATUS Status;
- Status = EfiAcquireLockOrFail (&(Sock->Lock));
- if (EFI_ERROR (Status)) {
- DEBUG (
- (DEBUG_ERROR,
- "SockRoute: Get the access for socket failed with %r",
- Status)
- );
- return EFI_ACCESS_DENIED;
- }
- if (SOCK_IS_NO_MAPPING (Sock)) {
- Status = EFI_NO_MAPPING;
- goto Exit;
- }
- if (SOCK_IS_UNCONFIGURED (Sock)) {
- Status = EFI_NOT_STARTED;
- goto Exit;
- }
- Status = Sock->ProtoHandler (Sock, SOCK_ROUTE, RouteInfo);
- Exit:
- EfiReleaseLock (&(Sock->Lock));
- return Status;
- }
|