]>
git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/TcpDxe/SockImpl.c
2 Implementation of the Socket.
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Get the first buffer block in the specific socket buffer.
15 @param[in] Sockbuf Pointer to the socket buffer.
17 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
22 IN SOCK_BUFFER
*Sockbuf
25 LIST_ENTRY
*NetbufList
;
27 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
29 if (IsListEmpty (NetbufList
)) {
33 return NET_LIST_HEAD (NetbufList
, NET_BUF
, List
);
37 Get the next buffer block in the specific socket buffer.
39 @param[in] Sockbuf Pointer to the socket buffer.
40 @param[in] SockEntry Pointer to the buffer block prior to the required one.
42 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is
43 the tail or head entry.
48 IN SOCK_BUFFER
*Sockbuf
,
52 LIST_ENTRY
*NetbufList
;
54 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
56 if ((SockEntry
->List
.ForwardLink
== NetbufList
) ||
57 (SockEntry
->List
.BackLink
== &SockEntry
->List
) ||
58 (SockEntry
->List
.ForwardLink
== &SockEntry
->List
)
64 return NET_LIST_USER_STRUCT (SockEntry
->List
.ForwardLink
, NET_BUF
, List
);
68 User provided callback function for NetbufFromExt.
70 @param[in] Arg The Arg parameter forwarded by NetbufFromExt(). Ignored.
83 Get the length of the data that can be retrieved from the socket
86 @param[in] SockBuffer Pointer to the socket receive buffer.
87 @param[out] IsUrg Pointer to a BOOLEAN variable.
88 If TRUE the data is OOB.
89 @param[in] BufLen The maximum length of the data buffer to
90 store the received data in the socket layer.
92 @return The length of the data can be retrieved.
97 IN SOCK_BUFFER
*SockBuffer
,
102 NET_BUF
*RcvBufEntry
;
104 TCP_RSV_DATA
*TcpRsvData
;
107 ASSERT ((SockBuffer
!= NULL
) && (IsUrg
!= NULL
) && (BufLen
> 0));
110 // Get the first socket receive buffer
112 RcvBufEntry
= SockBufFirst (SockBuffer
);
113 ASSERT (RcvBufEntry
!= NULL
);
115 TcpRsvData
= (TCP_RSV_DATA
*)RcvBufEntry
->ProtoData
;
118 // Check whether the receive data is out of bound. If yes, calculate the maximum
119 // allowed length of the urgent data and output it.
121 *IsUrg
= (BOOLEAN
)((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
123 if (*IsUrg
&& (TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
)) {
124 DataLen
= MIN (TcpRsvData
->UrgLen
, BufLen
);
126 if (DataLen
< TcpRsvData
->UrgLen
) {
127 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
129 TcpRsvData
->UrgLen
= 0;
136 // Process the next socket receive buffer to get the maximum allowed length
137 // of the received data.
139 DataLen
= RcvBufEntry
->TotalSize
;
141 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
143 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
144 TcpRsvData
= (TCP_RSV_DATA
*)RcvBufEntry
->ProtoData
;
146 Urg
= (BOOLEAN
)((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
152 if (*IsUrg
&& (TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
)) {
153 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
154 TcpRsvData
->UrgLen
= 0;
156 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
159 return MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
162 DataLen
+= RcvBufEntry
->TotalSize
;
164 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
167 DataLen
= MIN (BufLen
, DataLen
);
172 Copy data from socket buffer to an application provided receive buffer.
174 @param[in] Sock Pointer to the socket.
175 @param[in] TcpRxData Pointer to the application provided receive buffer.
176 @param[in] RcvdBytes The maximum length of the data can be copied.
177 @param[in] IsUrg If TRUE the data is Out of Bound, FALSE the data is normal.
191 EFI_TCP4_RECEIVE_DATA
*RxData
;
192 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
194 RxData
= (EFI_TCP4_RECEIVE_DATA
*)TcpRxData
;
198 ASSERT (RxData
->DataLength
>= RcvdBytes
);
200 RxData
->DataLength
= RcvdBytes
;
201 RxData
->UrgentFlag
= IsUrg
;
204 // Copy the CopyBytes data from socket receive buffer to RxData.
206 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
207 Fragment
= &RxData
->FragmentTable
[Index
];
208 CopyBytes
= MIN ((UINT32
)(Fragment
->FragmentLength
), RcvdBytes
);
211 Sock
->RcvBuffer
.DataQueue
,
214 Fragment
->FragmentBuffer
217 Fragment
->FragmentLength
= CopyBytes
;
218 RcvdBytes
-= CopyBytes
;
224 Process the send token.
226 @param[in, out] Sock Pointer to the socket.
230 SockProcessSndToken (
235 SOCK_TOKEN
*SockToken
;
237 SOCK_IO_TOKEN
*SndToken
;
238 EFI_TCP4_TRANSMIT_DATA
*TxData
;
241 ASSERT ((Sock
!= NULL
) && (SockStream
== Sock
->Type
));
243 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
246 // to determine if process a send token using
247 // socket layer flow control policy
249 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) && !IsListEmpty (&Sock
->SndTokenList
)) {
250 SockToken
= NET_LIST_HEAD (
251 &(Sock
->SndTokenList
),
257 // process this token
259 RemoveEntryList (&(SockToken
->TokenList
));
261 &(Sock
->ProcessingSndTokenList
),
262 &(SockToken
->TokenList
)
266 // Process it in the light of SockType
268 SndToken
= (SOCK_IO_TOKEN
*)SockToken
->Token
;
269 TxData
= SndToken
->Packet
.TxData
;
271 DataLen
= TxData
->DataLength
;
272 Status
= SockProcessTcpSndData (Sock
, TxData
);
274 if (EFI_ERROR (Status
)) {
278 if (DataLen
>= FreeSpace
) {
281 FreeSpace
-= DataLen
;
289 RemoveEntryList (&SockToken
->TokenList
);
290 SIGNAL_TOKEN (SockToken
->Token
, Status
);
291 FreePool (SockToken
);
295 Get received data from the socket layer to the receive token.
297 @param[in, out] Sock Pointer to the socket.
298 @param[in, out] RcvToken Pointer to the application provided receive token.
300 @return The length of data received in this token.
304 SockProcessRcvToken (
306 IN OUT SOCK_IO_TOKEN
*RcvToken
309 UINT32 TokenRcvdBytes
;
310 EFI_TCP4_RECEIVE_DATA
*RxData
;
313 ASSERT (Sock
!= NULL
);
315 ASSERT (SockStream
== Sock
->Type
);
317 RxData
= RcvToken
->Packet
.RxData
;
319 TokenRcvdBytes
= SockTcpDataToRcv (
326 // Copy data from RcvBuffer of socket to user
327 // provided RxData and set the fields in TCP RxData
329 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
331 NetbufQueTrim (Sock
->RcvBuffer
.DataQueue
, TokenRcvdBytes
);
332 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
334 return TokenRcvdBytes
;
338 Process the TCP send data, buffer the tcp txdata, and append
339 the buffer to socket send buffer, then try to send it.
341 @param[in] Sock Pointer to the socket.
342 @param[in] TcpTxData Pointer to the application provided send buffer.
344 @retval EFI_SUCCESS The operation completed successfully.
345 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
349 SockProcessTcpSndData (
356 EFI_TCP4_TRANSMIT_DATA
*TxData
;
358 TxData
= (EFI_TCP4_TRANSMIT_DATA
*)TcpTxData
;
361 // transform this TxData into a NET_BUFFER
362 // and insert it into Sock->SndBuffer
364 SndData
= NetbufFromExt (
365 (NET_FRAGMENT
*)TxData
->FragmentTable
,
366 TxData
->FragmentCount
,
373 if (NULL
== SndData
) {
376 "SockKProcessSndData: Failed to call NetBufferFromExt\n")
379 return EFI_OUT_OF_RESOURCES
;
382 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
385 // notify the low layer protocol to handle this send token
387 if (TxData
->Urgent
) {
388 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
390 if (EFI_ERROR (Status
)) {
396 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
398 if (EFI_ERROR (Status
)) {
404 // low layer protocol should really handle the sending
405 // process when catching SOCK_SND request
407 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
409 if (EFI_ERROR (Status
)) {
417 Flush the tokens in the specific token list.
419 @param[in] Sock Pointer to the socket.
420 @param[in, out] PendingTokenList Pointer to the token list to be flushed.
424 SockFlushPendingToken (
426 IN OUT LIST_ENTRY
*PendingTokenList
429 SOCK_TOKEN
*SockToken
;
430 SOCK_COMPLETION_TOKEN
*Token
;
432 ASSERT ((Sock
!= NULL
) && (PendingTokenList
!= NULL
));
434 while (!IsListEmpty (PendingTokenList
)) {
435 SockToken
= NET_LIST_HEAD (
441 Token
= SockToken
->Token
;
442 SIGNAL_TOKEN (Token
, Sock
->SockError
);
444 RemoveEntryList (&(SockToken
->TokenList
));
445 FreePool (SockToken
);
450 Wake up the connection token while the connection is successfully established,
451 then try to process any pending send token.
453 @param[in, out] Sock Pointer to the socket.
461 ASSERT (Sock
->ConnectionToken
!= NULL
);
463 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
464 Sock
->ConnectionToken
= NULL
;
467 // check to see if some pending send token existed?
469 SockProcessSndToken (Sock
);
473 Wake up the listen token while the connection is established successfully.
475 @param[in, out] Sock Pointer to the socket.
479 SockWakeListenToken (
484 SOCK_TOKEN
*SockToken
;
485 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
487 Parent
= Sock
->Parent
;
489 ASSERT ((Parent
!= NULL
) && SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
491 if (!IsListEmpty (&Parent
->ListenTokenList
)) {
492 SockToken
= NET_LIST_HEAD (
493 &Parent
->ListenTokenList
,
498 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*)SockToken
->Token
;
499 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
501 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
503 RemoveEntryList (&SockToken
->TokenList
);
504 FreePool (SockToken
);
506 RemoveEntryList (&Sock
->ConnectionList
);
511 "SockWakeListenToken: accept a socket, now conncnt is %d",
520 Wake up the receive token while some data is received.
522 @param[in, out] Sock Pointer to the socket.
531 UINT32 TokenRcvdBytes
;
532 SOCK_TOKEN
*SockToken
;
533 SOCK_IO_TOKEN
*RcvToken
;
535 ASSERT (Sock
->RcvBuffer
.DataQueue
!= NULL
);
537 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
539 ASSERT (RcvdBytes
> 0);
541 while (RcvdBytes
> 0 && !IsListEmpty (&Sock
->RcvTokenList
)) {
542 SockToken
= NET_LIST_HEAD (
548 RcvToken
= (SOCK_IO_TOKEN
*)SockToken
->Token
;
549 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
551 if (0 == TokenRcvdBytes
) {
555 RemoveEntryList (&(SockToken
->TokenList
));
556 FreePool (SockToken
);
557 RcvdBytes
-= TokenRcvdBytes
;
562 Cancel the tokens in the specific token list.
564 @param[in] Token Pointer to the Token. If NULL, all tokens
565 in SpecifiedTokenList will be canceled.
566 @param[in, out] SpecifiedTokenList Pointer to the token list to be checked.
568 @retval EFI_SUCCESS Cancel the tokens in the specific token listsuccessfully.
569 @retval EFI_NOT_FOUND The Token is not found in SpecifiedTokenList.
574 IN SOCK_COMPLETION_TOKEN
*Token
,
575 IN OUT LIST_ENTRY
*SpecifiedTokenList
580 SOCK_TOKEN
*SockToken
;
582 Status
= EFI_SUCCESS
;
586 if (IsListEmpty (SpecifiedTokenList
) && (Token
!= NULL
)) {
587 return EFI_NOT_FOUND
;
591 // Iterate through the SpecifiedTokenList.
593 Entry
= SpecifiedTokenList
->ForwardLink
;
594 while (Entry
!= SpecifiedTokenList
) {
595 SockToken
= NET_LIST_USER_STRUCT (Entry
, SOCK_TOKEN
, TokenList
);
598 SIGNAL_TOKEN (SockToken
->Token
, EFI_ABORTED
);
599 RemoveEntryList (&SockToken
->TokenList
);
600 FreePool (SockToken
);
602 Entry
= SpecifiedTokenList
->ForwardLink
;
603 Status
= EFI_SUCCESS
;
605 if (Token
== (VOID
*)SockToken
->Token
) {
606 SIGNAL_TOKEN (Token
, EFI_ABORTED
);
607 RemoveEntryList (&(SockToken
->TokenList
));
608 FreePool (SockToken
);
613 Status
= EFI_NOT_FOUND
;
615 Entry
= Entry
->ForwardLink
;
619 ASSERT (IsListEmpty (SpecifiedTokenList
) || Token
!= NULL
);
625 Create a socket with initial data SockInitData.
627 @param[in] SockInitData Pointer to the initial data of the socket.
629 @return Pointer to the newly created socket, return NULL when an exception occurs.
634 IN SOCK_INIT_DATA
*SockInitData
640 EFI_GUID
*TcpProtocolGuid
;
641 UINTN ProtocolLength
;
643 ASSERT ((SockInitData
!= NULL
) && (SockInitData
->ProtoHandler
!= NULL
));
644 ASSERT (SockInitData
->Type
== SockStream
);
645 ASSERT ((SockInitData
->ProtoData
!= NULL
) && (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
647 if (SockInitData
->IpVersion
== IP_VERSION_4
) {
648 TcpProtocolGuid
= &gEfiTcp4ProtocolGuid
;
649 ProtocolLength
= sizeof (EFI_TCP4_PROTOCOL
);
651 TcpProtocolGuid
= &gEfiTcp6ProtocolGuid
;
652 ProtocolLength
= sizeof (EFI_TCP6_PROTOCOL
);
655 Parent
= SockInitData
->Parent
;
657 if ((Parent
!= NULL
) && (Parent
->ConnCnt
== Parent
->BackLog
)) {
660 "SockCreate: Socket parent has reached its connection limit with %d ConnCnt and %d BackLog\n",
668 Sock
= AllocateZeroPool (sizeof (SOCKET
));
670 DEBUG ((DEBUG_ERROR
, "SockCreate: No resource to create a new socket\n"));
674 InitializeListHead (&Sock
->Link
);
675 InitializeListHead (&Sock
->ConnectionList
);
676 InitializeListHead (&Sock
->ListenTokenList
);
677 InitializeListHead (&Sock
->RcvTokenList
);
678 InitializeListHead (&Sock
->SndTokenList
);
679 InitializeListHead (&Sock
->ProcessingSndTokenList
);
681 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
683 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
684 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
687 "SockCreate: No resource to allocate SndBuffer for new socket\n")
693 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
694 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
697 "SockCreate: No resource to allocate RcvBuffer for new socket\n")
703 Sock
->Signature
= SOCK_SIGNATURE
;
705 Sock
->Parent
= Parent
;
706 Sock
->BackLog
= SockInitData
->BackLog
;
707 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
708 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
709 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
710 Sock
->Type
= SockInitData
->Type
;
711 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
712 Sock
->State
= SockInitData
->State
;
713 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
714 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
715 Sock
->Context
= SockInitData
->Context
;
717 Sock
->SockError
= EFI_ABORTED
;
718 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
719 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
721 Sock
->IpVersion
= SockInitData
->IpVersion
;
724 // Install protocol on Sock->SockHandle
726 CopyMem (&Sock
->NetProtocol
, SockInitData
->Protocol
, ProtocolLength
);
729 // copy the protodata into socket
731 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
733 Status
= gBS
->InstallMultipleProtocolInterfaces (
740 if (EFI_ERROR (Status
)) {
743 "SockCreate: Install TCP protocol in socket failed with %r\n",
750 if (Parent
!= NULL
) {
751 ASSERT (Parent
->BackLog
> 0);
752 ASSERT (SOCK_IS_LISTENING (Parent
));
755 // need to add it into Parent->ConnectionList
756 // if the Parent->ConnCnt < Parent->BackLog
762 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
766 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
769 if (Sock
->CreateCallback
!= NULL
) {
770 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
771 if (EFI_ERROR (Status
)) {
780 if (Sock
->SockHandle
!= NULL
) {
781 gBS
->UninstallMultipleProtocolInterfaces (
789 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
790 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
793 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
794 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
805 @param[in, out] Sock Pointer to the socket.
813 ASSERT (SockStream
== Sock
->Type
);
816 // Flush the completion token buffered
817 // by sock and rcv, snd buffer
819 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
820 SockConnFlush (Sock
);
821 SockSetState (Sock
, SO_CLOSED
);
822 Sock
->ConfigureState
= SO_UNCONFIGURED
;
826 // Destroy the RcvBuffer Queue and SendBuffer Queue
828 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
829 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
832 // Remove it from parent connection list if needed
834 if (Sock
->Parent
!= NULL
) {
835 RemoveEntryList (&(Sock
->ConnectionList
));
836 (Sock
->Parent
->ConnCnt
)--;
840 "SockDestroy: Delete a unaccepted socket from parent now conncnt is %d\n",
841 Sock
->Parent
->ConnCnt
)
851 Flush the sndBuffer and rcvBuffer of socket.
853 @param[in, out] Sock Pointer to the socket.
863 ASSERT (Sock
!= NULL
);
866 // Clear the flag in this socket
871 // Flush the SndBuffer and RcvBuffer of Sock
873 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
874 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
877 // Signal the pending token
879 if (Sock
->ConnectionToken
!= NULL
) {
880 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
881 Sock
->ConnectionToken
= NULL
;
884 if (Sock
->CloseToken
!= NULL
) {
885 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
886 Sock
->CloseToken
= NULL
;
889 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
890 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
891 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
892 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
895 // Destroy the pending connection, if it is a listening socket
897 if (SOCK_IS_LISTENING (Sock
)) {
898 while (!IsListEmpty (&Sock
->ConnectionList
)) {
899 Child
= NET_LIST_HEAD (
900 &Sock
->ConnectionList
,
905 SockDestroyChild (Child
);
913 Set the state of the socket.
915 @param[in, out] Sock Pointer to the socket.
916 @param[in] State The new socket state to be set.
929 Clone a new socket, including its associated protocol control block.
931 @param[in] Sock Pointer to the socket to be cloned.
933 @return Pointer to the newly cloned socket. If NULL, an error condition occurred.
942 SOCK_INIT_DATA InitData
;
944 InitData
.BackLog
= Sock
->BackLog
;
945 InitData
.Parent
= Sock
;
946 InitData
.State
= Sock
->State
;
947 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
948 InitData
.Type
= Sock
->Type
;
949 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
950 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
951 InitData
.DriverBinding
= Sock
->DriverBinding
;
952 InitData
.IpVersion
= Sock
->IpVersion
;
953 InitData
.Protocol
= &(Sock
->NetProtocol
);
954 InitData
.CreateCallback
= Sock
->CreateCallback
;
955 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
956 InitData
.Context
= Sock
->Context
;
957 InitData
.ProtoData
= Sock
->ProtoReserved
;
958 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
960 ClonedSock
= SockCreate (&InitData
);
962 if (NULL
== ClonedSock
) {
963 DEBUG ((DEBUG_ERROR
, "SockClone: no resource to create a cloned sock\n"));
967 SockSetState (ClonedSock
, SO_CONNECTING
);
968 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
974 Called by the low layer protocol to indicate the socket a connection is
977 This function just changes the socket's state to SO_CONNECTED
978 and signals the token used for connection establishment.
980 @param[in, out] Sock Pointer to the socket associated with the
981 established connection.
985 SockConnEstablished (
989 ASSERT (SO_CONNECTING
== Sock
->State
);
991 SockSetState (Sock
, SO_CONNECTED
);
993 if (NULL
== Sock
->Parent
) {
994 SockWakeConnToken (Sock
);
996 SockWakeListenToken (Sock
);
1001 Called by the low layer protocol to indicate the connection is closed.
1003 This function flushes the socket, sets the state to SO_CLOSED, and signals
1006 @param[in, out] Sock Pointer to the socket associated with the closed
1015 if (Sock
->CloseToken
!= NULL
) {
1016 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
1017 Sock
->CloseToken
= NULL
;
1020 SockConnFlush (Sock
);
1021 SockSetState (Sock
, SO_CLOSED
);
1023 if (Sock
->Parent
!= NULL
) {
1024 SockDestroyChild (Sock
);
1029 Called by low layer protocol to indicate that some data was sent or processed.
1031 This function trims the sent data in the socket send buffer, and signals the data
1034 @param[in, out] Sock Pointer to the socket.
1035 @param[in] Count The length of the data processed or sent, in bytes.
1040 IN OUT SOCKET
*Sock
,
1044 SOCK_TOKEN
*SockToken
;
1045 SOCK_COMPLETION_TOKEN
*SndToken
;
1047 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1048 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1050 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1053 // To check if we can signal some snd token in this socket
1056 SockToken
= NET_LIST_HEAD (
1057 &(Sock
->ProcessingSndTokenList
),
1062 SndToken
= SockToken
->Token
;
1064 if (SockToken
->RemainDataLen
<= Count
) {
1065 RemoveEntryList (&(SockToken
->TokenList
));
1066 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1067 Count
-= SockToken
->RemainDataLen
;
1068 FreePool (SockToken
);
1070 SockToken
->RemainDataLen
-= Count
;
1076 // to judge if we can process some send token in
1077 // Sock->SndTokenList, if so process those send token
1079 SockProcessSndToken (Sock
);
1083 Called by the low layer protocol to copy some data in the socket send
1084 buffer starting from the specific offset to a buffer provided by
1087 @param[in] Sock Pointer to the socket.
1088 @param[in] Offset The start point of the data to be copied.
1089 @param[in] Len The length of the data to be copied.
1090 @param[out] Dest Pointer to the destination to copy the data.
1092 @return The data size copied.
1103 ASSERT ((Sock
!= NULL
) && SockStream
== Sock
->Type
);
1105 return NetbufQueCopy (
1106 Sock
->SndBuffer
.DataQueue
,
1114 Called by the low layer protocol to deliver received data to socket layer.
1116 This function will append the data to the socket receive buffer, set the
1117 urgent data length, and then check if any receive token can be signaled.
1119 @param[in, out] Sock Pointer to the socket.
1120 @param[in, out] NetBuffer Pointer to the buffer that contains the received data.
1121 @param[in] UrgLen The length of the urgent data in the received data.
1126 IN OUT SOCKET
*Sock
,
1127 IN OUT NET_BUF
*NetBuffer
,
1132 (Sock
!= NULL
) && (Sock
->RcvBuffer
.DataQueue
!= NULL
) &&
1133 UrgLen
<= NetBuffer
->TotalSize
1136 NET_GET_REF (NetBuffer
);
1138 ((TCP_RSV_DATA
*)(NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1140 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1142 SockWakeRcvToken (Sock
);
1146 Get the length of the free space of the specific socket buffer.
1148 @param[in] Sock Pointer to the socket.
1149 @param[in] Which Flag to indicate which socket buffer to check:
1150 either send buffer or receive buffer.
1152 @return The length of the free space, in bytes.
1162 SOCK_BUFFER
*SockBuffer
;
1164 ASSERT (Sock
!= NULL
&& ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1166 if (SOCK_SND_BUF
== Which
) {
1167 SockBuffer
= &(Sock
->SndBuffer
);
1169 SockBuffer
= &(Sock
->RcvBuffer
);
1172 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1174 if (BufferCC
>= SockBuffer
->HighWater
) {
1178 return SockBuffer
->HighWater
- BufferCC
;
1182 Called by the low layer protocol to indicate that there will be no more data
1183 from the communication peer.
1185 This function sets the socket's state to SO_NO_MORE_DATA and signals all queued
1186 IO tokens with the error status EFI_CONNECTION_FIN.
1188 @param[in, out] Sock Pointer to the socket.
1198 SOCK_NO_MORE_DATA (Sock
);
1200 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1201 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1203 Err
= Sock
->SockError
;
1205 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1207 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1209 SOCK_ERROR (Sock
, Err
);