]>
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] Event The Event this notify function registered to, 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 retreived.
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
)) {
125 DataLen
= MIN (TcpRsvData
->UrgLen
, BufLen
);
127 if (DataLen
< TcpRsvData
->UrgLen
) {
128 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
130 TcpRsvData
->UrgLen
= 0;
138 // Process the next socket receive buffer to get the maximum allowed length
139 // of the received data.
141 DataLen
= RcvBufEntry
->TotalSize
;
143 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
145 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
147 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
149 Urg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
155 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
157 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
158 TcpRsvData
->UrgLen
= 0;
160 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
163 return MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
167 DataLen
+= RcvBufEntry
->TotalSize
;
169 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
172 DataLen
= MIN (BufLen
, DataLen
);
177 Copy data from socket buffer to an application provided receive buffer.
179 @param[in] Sock Pointer to the socket.
180 @param[in] TcpRxData Pointer to the application provided receive buffer.
181 @param[in] RcvdBytes The maximum length of the data can be copied.
182 @param[in] IsUrg If TRUE the data is Out of Bound, FALSE the data is normal.
196 EFI_TCP4_RECEIVE_DATA
*RxData
;
197 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
199 RxData
= (EFI_TCP4_RECEIVE_DATA
*) TcpRxData
;
203 ASSERT (RxData
->DataLength
>= RcvdBytes
);
205 RxData
->DataLength
= RcvdBytes
;
206 RxData
->UrgentFlag
= IsUrg
;
209 // Copy the CopyBytes data from socket receive buffer to RxData.
211 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
213 Fragment
= &RxData
->FragmentTable
[Index
];
214 CopyBytes
= MIN ((UINT32
) (Fragment
->FragmentLength
), RcvdBytes
);
217 Sock
->RcvBuffer
.DataQueue
,
220 Fragment
->FragmentBuffer
223 Fragment
->FragmentLength
= CopyBytes
;
224 RcvdBytes
-= CopyBytes
;
230 Process the send token.
232 @param[in, out] Sock Pointer to the socket.
236 SockProcessSndToken (
241 SOCK_TOKEN
*SockToken
;
243 SOCK_IO_TOKEN
*SndToken
;
244 EFI_TCP4_TRANSMIT_DATA
*TxData
;
247 ASSERT ((Sock
!= NULL
) && (SockStream
== Sock
->Type
));
249 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
252 // to determine if process a send token using
253 // socket layer flow control policy
255 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) && !IsListEmpty (&Sock
->SndTokenList
)) {
257 SockToken
= NET_LIST_HEAD (
258 &(Sock
->SndTokenList
),
264 // process this token
266 RemoveEntryList (&(SockToken
->TokenList
));
268 &(Sock
->ProcessingSndTokenList
),
269 &(SockToken
->TokenList
)
273 // Proceess it in the light of SockType
275 SndToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
276 TxData
= SndToken
->Packet
.TxData
;
278 DataLen
= TxData
->DataLength
;
279 Status
= SockProcessTcpSndData (Sock
, TxData
);
281 if (EFI_ERROR (Status
)) {
285 if (DataLen
>= FreeSpace
) {
289 FreeSpace
-= DataLen
;
298 RemoveEntryList (&SockToken
->TokenList
);
299 SIGNAL_TOKEN (SockToken
->Token
, Status
);
300 FreePool (SockToken
);
304 Get received data from the socket layer to the receive token.
306 @param[in, out] Sock Pointer to the socket.
307 @param[in, out] RcvToken Pointer to the application provided receive token.
309 @return The length of data received in this token.
313 SockProcessRcvToken (
315 IN OUT SOCK_IO_TOKEN
*RcvToken
318 UINT32 TokenRcvdBytes
;
319 EFI_TCP4_RECEIVE_DATA
*RxData
;
322 ASSERT (Sock
!= NULL
);
324 ASSERT (SockStream
== Sock
->Type
);
326 RxData
= RcvToken
->Packet
.RxData
;
328 TokenRcvdBytes
= SockTcpDataToRcv (
335 // Copy data from RcvBuffer of socket to user
336 // provided RxData and set the fields in TCP RxData
338 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
340 NetbufQueTrim (Sock
->RcvBuffer
.DataQueue
, TokenRcvdBytes
);
341 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
343 return TokenRcvdBytes
;
347 Process the TCP send data, buffer the tcp txdata, and append
348 the buffer to socket send buffer, then try to send it.
350 @param[in] Sock Pointer to the socket.
351 @param[in] TcpTxData Pointer to the application provided send buffer.
353 @retval EFI_SUCCESS The operation completed successfully.
354 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
358 SockProcessTcpSndData (
365 EFI_TCP4_TRANSMIT_DATA
*TxData
;
367 TxData
= (EFI_TCP4_TRANSMIT_DATA
*) TcpTxData
;
370 // transform this TxData into a NET_BUFFER
371 // and insert it into Sock->SndBuffer
373 SndData
= NetbufFromExt (
374 (NET_FRAGMENT
*) TxData
->FragmentTable
,
375 TxData
->FragmentCount
,
382 if (NULL
== SndData
) {
385 "SockKProcessSndData: Failed to call NetBufferFromExt\n")
388 return EFI_OUT_OF_RESOURCES
;
391 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
394 // notify the low layer protocol to handle this send token
396 if (TxData
->Urgent
) {
397 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
399 if (EFI_ERROR (Status
)) {
405 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
407 if (EFI_ERROR (Status
)) {
413 // low layer protocol should really handle the sending
414 // process when catching SOCK_SND request
416 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
418 if (EFI_ERROR (Status
)) {
426 Flush the tokens in the specific token list.
428 @param[in] Sock Pointer to the socket.
429 @param[in, out] PendingTokenList Pointer to the token list to be flushed.
433 SockFlushPendingToken (
435 IN OUT LIST_ENTRY
*PendingTokenList
438 SOCK_TOKEN
*SockToken
;
439 SOCK_COMPLETION_TOKEN
*Token
;
441 ASSERT ((Sock
!= NULL
) && (PendingTokenList
!= NULL
));
443 while (!IsListEmpty (PendingTokenList
)) {
444 SockToken
= NET_LIST_HEAD (
450 Token
= SockToken
->Token
;
451 SIGNAL_TOKEN (Token
, Sock
->SockError
);
453 RemoveEntryList (&(SockToken
->TokenList
));
454 FreePool (SockToken
);
459 Wake up the connection token while the connection is successfully established,
460 then try to process any pending send token.
462 @param[in, out] Sock Pointer to the socket.
470 ASSERT (Sock
->ConnectionToken
!= NULL
);
472 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
473 Sock
->ConnectionToken
= NULL
;
476 // check to see if some pending send token existed?
478 SockProcessSndToken (Sock
);
482 Wake up the listen token while the connection is established successfully.
484 @param[in, out] Sock Pointer to the socket.
488 SockWakeListenToken (
493 SOCK_TOKEN
*SockToken
;
494 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
496 Parent
= Sock
->Parent
;
498 ASSERT ((Parent
!= NULL
) && SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
500 if (!IsListEmpty (&Parent
->ListenTokenList
)) {
501 SockToken
= NET_LIST_HEAD (
502 &Parent
->ListenTokenList
,
507 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*) SockToken
->Token
;
508 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
510 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
512 RemoveEntryList (&SockToken
->TokenList
);
513 FreePool (SockToken
);
515 RemoveEntryList (&Sock
->ConnectionList
);
520 "SockWakeListenToken: accept a socket, now conncnt is %d",
529 Wake up the receive token while some data is received.
531 @param[in, out] Sock Pointer to the socket.
540 UINT32 TokenRcvdBytes
;
541 SOCK_TOKEN
*SockToken
;
542 SOCK_IO_TOKEN
*RcvToken
;
544 ASSERT (Sock
->RcvBuffer
.DataQueue
!= NULL
);
546 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
548 ASSERT (RcvdBytes
> 0);
550 while (RcvdBytes
> 0 && !IsListEmpty (&Sock
->RcvTokenList
)) {
552 SockToken
= NET_LIST_HEAD (
558 RcvToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
559 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
561 if (0 == TokenRcvdBytes
) {
565 RemoveEntryList (&(SockToken
->TokenList
));
566 FreePool (SockToken
);
567 RcvdBytes
-= TokenRcvdBytes
;
572 Cancel the tokens in the specific token list.
574 @param[in] Token Pointer to the Token. If NULL, all tokens
575 in SpecifiedTokenList will be canceled.
576 @param[in, out] SpecifiedTokenList Pointer to the token list to be checked.
578 @retval EFI_SUCCESS Cancel the tokens in the specific token listsuccessfully.
579 @retval EFI_NOT_FOUND The Token is not found in SpecifiedTokenList.
584 IN SOCK_COMPLETION_TOKEN
*Token
,
585 IN OUT LIST_ENTRY
*SpecifiedTokenList
590 SOCK_TOKEN
*SockToken
;
592 Status
= EFI_SUCCESS
;
596 if (IsListEmpty (SpecifiedTokenList
) && Token
!= NULL
) {
597 return EFI_NOT_FOUND
;
601 // Iterate through the SpecifiedTokenList.
603 Entry
= SpecifiedTokenList
->ForwardLink
;
604 while (Entry
!= SpecifiedTokenList
) {
605 SockToken
= NET_LIST_USER_STRUCT (Entry
, SOCK_TOKEN
, TokenList
);
608 SIGNAL_TOKEN (SockToken
->Token
, EFI_ABORTED
);
609 RemoveEntryList (&SockToken
->TokenList
);
610 FreePool (SockToken
);
612 Entry
= SpecifiedTokenList
->ForwardLink
;
613 Status
= EFI_SUCCESS
;
615 if (Token
== (VOID
*) SockToken
->Token
) {
616 SIGNAL_TOKEN (Token
, EFI_ABORTED
);
617 RemoveEntryList (&(SockToken
->TokenList
));
618 FreePool (SockToken
);
623 Status
= EFI_NOT_FOUND
;
625 Entry
= Entry
->ForwardLink
;
629 ASSERT (IsListEmpty (SpecifiedTokenList
) || Token
!= NULL
);
635 Create a socket with initial data SockInitData.
637 @param[in] SockInitData Pointer to the initial data of the socket.
639 @return Pointer to the newly created socket, return NULL when an exception occurs.
644 IN SOCK_INIT_DATA
*SockInitData
650 EFI_GUID
*TcpProtocolGuid
;
651 UINTN ProtocolLength
;
653 ASSERT ((SockInitData
!= NULL
) && (SockInitData
->ProtoHandler
!= NULL
));
654 ASSERT (SockInitData
->Type
== SockStream
);
655 ASSERT ((SockInitData
->ProtoData
!= NULL
) && (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
657 if (SockInitData
->IpVersion
== IP_VERSION_4
) {
658 TcpProtocolGuid
= &gEfiTcp4ProtocolGuid
;
659 ProtocolLength
= sizeof (EFI_TCP4_PROTOCOL
);
661 TcpProtocolGuid
= &gEfiTcp6ProtocolGuid
;
662 ProtocolLength
= sizeof (EFI_TCP6_PROTOCOL
);
666 Parent
= SockInitData
->Parent
;
668 if ((Parent
!= NULL
) && (Parent
->ConnCnt
== Parent
->BackLog
)) {
671 "SockCreate: Socket parent has reached its connection limit with %d ConnCnt and %d BackLog\n",
679 Sock
= AllocateZeroPool (sizeof (SOCKET
));
682 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to create a new socket\n"));
686 InitializeListHead (&Sock
->Link
);
687 InitializeListHead (&Sock
->ConnectionList
);
688 InitializeListHead (&Sock
->ListenTokenList
);
689 InitializeListHead (&Sock
->RcvTokenList
);
690 InitializeListHead (&Sock
->SndTokenList
);
691 InitializeListHead (&Sock
->ProcessingSndTokenList
);
693 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
695 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
696 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
699 "SockCreate: No resource to allocate SndBuffer for new socket\n")
705 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
706 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
709 "SockCreate: No resource to allocate RcvBuffer for new socket\n")
715 Sock
->Signature
= SOCK_SIGNATURE
;
717 Sock
->Parent
= Parent
;
718 Sock
->BackLog
= SockInitData
->BackLog
;
719 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
720 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
721 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
722 Sock
->Type
= SockInitData
->Type
;
723 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
724 Sock
->State
= SockInitData
->State
;
725 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
726 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
727 Sock
->Context
= SockInitData
->Context
;
729 Sock
->SockError
= EFI_ABORTED
;
730 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
731 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
733 Sock
->IpVersion
= SockInitData
->IpVersion
;
736 // Install protocol on Sock->SockHandle
738 CopyMem (&Sock
->NetProtocol
, SockInitData
->Protocol
, ProtocolLength
);
741 // copy the protodata into socket
743 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
745 Status
= gBS
->InstallMultipleProtocolInterfaces (
752 if (EFI_ERROR (Status
)) {
755 "SockCreate: Install TCP protocol in socket failed with %r\n",
762 if (Parent
!= NULL
) {
763 ASSERT (Parent
->BackLog
> 0);
764 ASSERT (SOCK_IS_LISTENING (Parent
));
767 // need to add it into Parent->ConnectionList
768 // if the Parent->ConnCnt < Parent->BackLog
774 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
778 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
781 if (Sock
->CreateCallback
!= NULL
) {
782 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
783 if (EFI_ERROR (Status
)) {
792 if (Sock
->SockHandle
!= NULL
) {
793 gBS
->UninstallMultipleProtocolInterfaces (
801 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
802 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
805 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
806 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
817 @param[in, out] Sock Pointer to the socket.
825 ASSERT (SockStream
== Sock
->Type
);
828 // Flush the completion token buffered
829 // by sock and rcv, snd buffer
831 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
833 SockConnFlush (Sock
);
834 SockSetState (Sock
, SO_CLOSED
);
835 Sock
->ConfigureState
= SO_UNCONFIGURED
;
839 // Destroy the RcvBuffer Queue and SendBuffer Queue
841 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
842 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
845 // Remove it from parent connection list if needed
847 if (Sock
->Parent
!= NULL
) {
849 RemoveEntryList (&(Sock
->ConnectionList
));
850 (Sock
->Parent
->ConnCnt
)--;
854 "SockDestroy: Delete a unaccepted socket from parent now conncnt is %d\n",
855 Sock
->Parent
->ConnCnt
)
865 Flush the sndBuffer and rcvBuffer of socket.
867 @param[in, out] Sock Pointer to the socket.
877 ASSERT (Sock
!= NULL
);
880 // Clear the flag in this socket
885 // Flush the SndBuffer and RcvBuffer of Sock
887 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
888 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
891 // Signal the pending token
893 if (Sock
->ConnectionToken
!= NULL
) {
894 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
895 Sock
->ConnectionToken
= NULL
;
898 if (Sock
->CloseToken
!= NULL
) {
899 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
900 Sock
->CloseToken
= NULL
;
903 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
904 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
905 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
906 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
909 // Destroy the pending connection, if it is a listening socket
911 if (SOCK_IS_LISTENING (Sock
)) {
912 while (!IsListEmpty (&Sock
->ConnectionList
)) {
913 Child
= NET_LIST_HEAD (
914 &Sock
->ConnectionList
,
919 SockDestroyChild (Child
);
928 Set the state of the socket.
930 @param[in, out] Sock Pointer to the socket.
931 @param[in] State The new socket state to be set.
944 Clone a new socket, including its associated protocol control block.
946 @param[in] Sock Pointer to the socket to be cloned.
948 @return Pointer to the newly cloned socket. If NULL, an error condition occurred.
957 SOCK_INIT_DATA InitData
;
959 InitData
.BackLog
= Sock
->BackLog
;
960 InitData
.Parent
= Sock
;
961 InitData
.State
= Sock
->State
;
962 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
963 InitData
.Type
= Sock
->Type
;
964 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
965 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
966 InitData
.DriverBinding
= Sock
->DriverBinding
;
967 InitData
.IpVersion
= Sock
->IpVersion
;
968 InitData
.Protocol
= &(Sock
->NetProtocol
);
969 InitData
.CreateCallback
= Sock
->CreateCallback
;
970 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
971 InitData
.Context
= Sock
->Context
;
972 InitData
.ProtoData
= Sock
->ProtoReserved
;
973 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
975 ClonedSock
= SockCreate (&InitData
);
977 if (NULL
== ClonedSock
) {
978 DEBUG ((EFI_D_ERROR
, "SockClone: no resource to create a cloned sock\n"));
982 SockSetState (ClonedSock
, SO_CONNECTING
);
983 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
989 Called by the low layer protocol to indicate the socket a connection is
992 This function just changes the socket's state to SO_CONNECTED
993 and signals the token used for connection establishment.
995 @param[in, out] Sock Pointer to the socket associated with the
996 established connection.
1000 SockConnEstablished (
1005 ASSERT (SO_CONNECTING
== Sock
->State
);
1007 SockSetState (Sock
, SO_CONNECTED
);
1009 if (NULL
== Sock
->Parent
) {
1010 SockWakeConnToken (Sock
);
1012 SockWakeListenToken (Sock
);
1018 Called by the low layer protocol to indicate the connection is closed.
1020 This function flushes the socket, sets the state to SO_CLOSED, and signals
1023 @param[in, out] Sock Pointer to the socket associated with the closed
1032 if (Sock
->CloseToken
!= NULL
) {
1033 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
1034 Sock
->CloseToken
= NULL
;
1037 SockConnFlush (Sock
);
1038 SockSetState (Sock
, SO_CLOSED
);
1040 if (Sock
->Parent
!= NULL
) {
1041 SockDestroyChild (Sock
);
1047 Called by low layer protocol to indicate that some data was sent or processed.
1049 This function trims the sent data in the socket send buffer, and signals the data
1052 @param[in, out] Sock Pointer to the socket.
1053 @param[in] Count The length of the data processed or sent, in bytes.
1058 IN OUT SOCKET
*Sock
,
1062 SOCK_TOKEN
*SockToken
;
1063 SOCK_COMPLETION_TOKEN
*SndToken
;
1065 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1066 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1068 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1071 // To check if we can signal some snd token in this socket
1074 SockToken
= NET_LIST_HEAD (
1075 &(Sock
->ProcessingSndTokenList
),
1080 SndToken
= SockToken
->Token
;
1082 if (SockToken
->RemainDataLen
<= Count
) {
1084 RemoveEntryList (&(SockToken
->TokenList
));
1085 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1086 Count
-= SockToken
->RemainDataLen
;
1087 FreePool (SockToken
);
1090 SockToken
->RemainDataLen
-= Count
;
1096 // to judge if we can process some send token in
1097 // Sock->SndTokenList, if so process those send token
1099 SockProcessSndToken (Sock
);
1103 Called by the low layer protocol to copy some data in the socket send
1104 buffer starting from the specific offset to a buffer provided by
1107 @param[in] Sock Pointer to the socket.
1108 @param[in] Offset The start point of the data to be copied.
1109 @param[in] Len The length of the data to be copied.
1110 @param[out] Dest Pointer to the destination to copy the data.
1112 @return The data size copied.
1123 ASSERT ((Sock
!= NULL
) && SockStream
== Sock
->Type
);
1125 return NetbufQueCopy (
1126 Sock
->SndBuffer
.DataQueue
,
1134 Called by the low layer protocol to deliver received data to socket layer.
1136 This function will append the data to the socket receive buffer, set the
1137 urgent data length, and then check if any receive token can be signaled.
1139 @param[in, out] Sock Pointer to the socket.
1140 @param[in, out] NetBuffer Pointer to the buffer that contains the received data.
1141 @param[in] UrgLen The length of the urgent data in the received data.
1146 IN OUT SOCKET
*Sock
,
1147 IN OUT NET_BUF
*NetBuffer
,
1151 ASSERT ((Sock
!= NULL
) && (Sock
->RcvBuffer
.DataQueue
!= NULL
) &&
1152 UrgLen
<= NetBuffer
->TotalSize
);
1154 NET_GET_REF (NetBuffer
);
1156 ((TCP_RSV_DATA
*) (NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1158 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1160 SockWakeRcvToken (Sock
);
1164 Get the length of the free space of the specific socket buffer.
1166 @param[in] Sock Pointer to the socket.
1167 @param[in] Which Flag to indicate which socket buffer to check:
1168 either send buffer or receive buffer.
1170 @return The length of the free space, in bytes.
1180 SOCK_BUFFER
*SockBuffer
;
1182 ASSERT (Sock
!= NULL
&& ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1184 if (SOCK_SND_BUF
== Which
) {
1185 SockBuffer
= &(Sock
->SndBuffer
);
1187 SockBuffer
= &(Sock
->RcvBuffer
);
1190 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1192 if (BufferCC
>= SockBuffer
->HighWater
) {
1197 return SockBuffer
->HighWater
- BufferCC
;
1201 Called by the low layer protocol to indicate that there will be no more data
1202 from the communication peer.
1204 This function sets the socket's state to SO_NO_MORE_DATA and signals all queued
1205 IO tokens with the error status EFI_CONNECTION_FIN.
1207 @param[in, out] Sock Pointer to the socket.
1217 SOCK_NO_MORE_DATA (Sock
);
1219 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1221 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1223 Err
= Sock
->SockError
;
1225 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1227 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1229 SOCK_ERROR (Sock
, Err
);