TianoCore EDK2 master
Loading...
Searching...
No Matches
SockImpl.c
Go to the documentation of this file.
1
10#include "SockImpl.h"
11
20NET_BUF *
22 IN SOCK_BUFFER *Sockbuf
23 )
24{
25 LIST_ENTRY *NetbufList;
26
27 NetbufList = &(Sockbuf->DataQueue->BufList);
28
29 if (IsListEmpty (NetbufList)) {
30 return NULL;
31 }
32
33 return NET_LIST_HEAD (NetbufList, NET_BUF, List);
34}
35
46NET_BUF *
48 IN SOCK_BUFFER *Sockbuf,
49 IN NET_BUF *SockEntry
50 )
51{
52 LIST_ENTRY *NetbufList;
53
54 NetbufList = &(Sockbuf->DataQueue->BufList);
55
56 if ((SockEntry->List.ForwardLink == NetbufList) ||
57 (SockEntry->List.BackLink == &SockEntry->List) ||
58 (SockEntry->List.ForwardLink == &SockEntry->List)
59 )
60 {
61 return NULL;
62 }
63
64 return NET_LIST_USER_STRUCT (SockEntry->List.ForwardLink, NET_BUF, List);
65}
66
73VOID
74EFIAPI
76 IN VOID *Arg
77 )
78{
79 return;
80}
81
95UINT32
97 IN SOCK_BUFFER *SockBuffer,
98 OUT BOOLEAN *IsUrg,
99 IN UINT32 BufLen
100 )
101{
102 NET_BUF *RcvBufEntry;
103 UINT32 DataLen;
104 TCP_RSV_DATA *TcpRsvData;
105 BOOLEAN Urg;
106
107 ASSERT ((SockBuffer != NULL) && (IsUrg != NULL) && (BufLen > 0));
108
109 //
110 // Get the first socket receive buffer
111 //
112 RcvBufEntry = SockBufFirst (SockBuffer);
113 ASSERT (RcvBufEntry != NULL);
114
115 TcpRsvData = (TCP_RSV_DATA *)RcvBufEntry->ProtoData;
116
117 //
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.
120 //
121 *IsUrg = (BOOLEAN)((TcpRsvData->UrgLen > 0) ? TRUE : FALSE);
122
123 if (*IsUrg && (TcpRsvData->UrgLen < RcvBufEntry->TotalSize)) {
124 DataLen = MIN (TcpRsvData->UrgLen, BufLen);
125
126 if (DataLen < TcpRsvData->UrgLen) {
127 TcpRsvData->UrgLen = TcpRsvData->UrgLen - DataLen;
128 } else {
129 TcpRsvData->UrgLen = 0;
130 }
131
132 return DataLen;
133 }
134
135 //
136 // Process the next socket receive buffer to get the maximum allowed length
137 // of the received data.
138 //
139 DataLen = RcvBufEntry->TotalSize;
140
141 RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry);
142
143 while ((BufLen > DataLen) && (RcvBufEntry != NULL)) {
144 TcpRsvData = (TCP_RSV_DATA *)RcvBufEntry->ProtoData;
145
146 Urg = (BOOLEAN)((TcpRsvData->UrgLen > 0) ? TRUE : FALSE);
147
148 if (*IsUrg != Urg) {
149 break;
150 }
151
152 if (*IsUrg && (TcpRsvData->UrgLen < RcvBufEntry->TotalSize)) {
153 if (TcpRsvData->UrgLen + DataLen < BufLen) {
154 TcpRsvData->UrgLen = 0;
155 } else {
156 TcpRsvData->UrgLen = TcpRsvData->UrgLen - (BufLen - DataLen);
157 }
158
159 return MIN (TcpRsvData->UrgLen + DataLen, BufLen);
160 }
161
162 DataLen += RcvBufEntry->TotalSize;
163
164 RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry);
165 }
166
167 DataLen = MIN (BufLen, DataLen);
168 return DataLen;
169}
170
180VOID
182 IN SOCKET *Sock,
183 IN VOID *TcpRxData,
184 IN UINT32 RcvdBytes,
185 IN BOOLEAN IsUrg
186 )
187{
188 UINT32 Index;
189 UINT32 CopyBytes;
190 UINT32 OffSet;
191 EFI_TCP4_RECEIVE_DATA *RxData;
192 EFI_TCP4_FRAGMENT_DATA *Fragment;
193
194 RxData = (EFI_TCP4_RECEIVE_DATA *)TcpRxData;
195
196 OffSet = 0;
197
198 ASSERT (RxData->DataLength >= RcvdBytes);
199
200 RxData->DataLength = RcvdBytes;
201 RxData->UrgentFlag = IsUrg;
202
203 //
204 // Copy the CopyBytes data from socket receive buffer to RxData.
205 //
206 for (Index = 0; (Index < RxData->FragmentCount) && (RcvdBytes > 0); Index++) {
207 Fragment = &RxData->FragmentTable[Index];
208 CopyBytes = MIN ((UINT32)(Fragment->FragmentLength), RcvdBytes);
209
211 Sock->RcvBuffer.DataQueue,
212 OffSet,
213 CopyBytes,
214 Fragment->FragmentBuffer
215 );
216
217 Fragment->FragmentLength = CopyBytes;
218 RcvdBytes -= CopyBytes;
219 OffSet += CopyBytes;
220 }
221}
222
229VOID
231 IN OUT SOCKET *Sock
232 )
233{
234 UINT32 FreeSpace;
235 SOCK_TOKEN *SockToken;
236 UINT32 DataLen;
237 SOCK_IO_TOKEN *SndToken;
239 EFI_STATUS Status;
240
241 ASSERT ((Sock != NULL) && (SockStream == Sock->Type));
242
243 FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
244
245 //
246 // to determine if process a send token using
247 // socket layer flow control policy
248 //
249 while ((FreeSpace >= Sock->SndBuffer.LowWater) && !IsListEmpty (&Sock->SndTokenList)) {
250 SockToken = NET_LIST_HEAD (
251 &(Sock->SndTokenList),
253 TokenList
254 );
255
256 //
257 // process this token
258 //
259 RemoveEntryList (&(SockToken->TokenList));
261 &(Sock->ProcessingSndTokenList),
262 &(SockToken->TokenList)
263 );
264
265 //
266 // Process it in the light of SockType
267 //
268 SndToken = (SOCK_IO_TOKEN *)SockToken->Token;
269 TxData = SndToken->Packet.TxData;
270
271 DataLen = TxData->DataLength;
272 Status = SockProcessTcpSndData (Sock, TxData);
273
274 if (EFI_ERROR (Status)) {
275 goto OnError;
276 }
277
278 if (DataLen >= FreeSpace) {
279 FreeSpace = 0;
280 } else {
281 FreeSpace -= DataLen;
282 }
283 }
284
285 return;
286
287OnError:
288
289 RemoveEntryList (&SockToken->TokenList);
290 SIGNAL_TOKEN (SockToken->Token, Status);
291 FreePool (SockToken);
292}
293
303UINT32
305 IN OUT SOCKET *Sock,
306 IN OUT SOCK_IO_TOKEN *RcvToken
307 )
308{
309 UINT32 TokenRcvdBytes;
310 EFI_TCP4_RECEIVE_DATA *RxData;
311 BOOLEAN IsUrg;
312
313 ASSERT (Sock != NULL);
314
315 ASSERT (SockStream == Sock->Type);
316
317 RxData = RcvToken->Packet.RxData;
318
319 TokenRcvdBytes = SockTcpDataToRcv (
320 &Sock->RcvBuffer,
321 &IsUrg,
322 RxData->DataLength
323 );
324
325 //
326 // Copy data from RcvBuffer of socket to user
327 // provided RxData and set the fields in TCP RxData
328 //
329 SockSetTcpRxData (Sock, RxData, TokenRcvdBytes, IsUrg);
330
331 NetbufQueTrim (Sock->RcvBuffer.DataQueue, TokenRcvdBytes);
332 SIGNAL_TOKEN (&(RcvToken->Token), EFI_SUCCESS);
333
334 return TokenRcvdBytes;
335}
336
350 IN SOCKET *Sock,
351 IN VOID *TcpTxData
352 )
353{
354 NET_BUF *SndData;
355 EFI_STATUS Status;
357
358 TxData = (EFI_TCP4_TRANSMIT_DATA *)TcpTxData;
359
360 //
361 // transform this TxData into a NET_BUFFER
362 // and insert it into Sock->SndBuffer
363 //
364 SndData = NetbufFromExt (
365 (NET_FRAGMENT *)TxData->FragmentTable,
366 TxData->FragmentCount,
367 0,
368 0,
370 NULL
371 );
372
373 if (NULL == SndData) {
374 DEBUG (
375 (DEBUG_ERROR,
376 "SockKProcessSndData: Failed to call NetBufferFromExt\n")
377 );
378
379 return EFI_OUT_OF_RESOURCES;
380 }
381
382 NetbufQueAppend (Sock->SndBuffer.DataQueue, SndData);
383
384 //
385 // notify the low layer protocol to handle this send token
386 //
387 if (TxData->Urgent) {
388 Status = Sock->ProtoHandler (Sock, SOCK_SNDURG, NULL);
389
390 if (EFI_ERROR (Status)) {
391 return Status;
392 }
393 }
394
395 if (TxData->Push) {
396 Status = Sock->ProtoHandler (Sock, SOCK_SNDPUSH, NULL);
397
398 if (EFI_ERROR (Status)) {
399 return Status;
400 }
401 }
402
403 //
404 // low layer protocol should really handle the sending
405 // process when catching SOCK_SND request
406 //
407 Status = Sock->ProtoHandler (Sock, SOCK_SND, NULL);
408
409 if (EFI_ERROR (Status)) {
410 return Status;
411 }
412
413 return EFI_SUCCESS;
414}
415
423VOID
425 IN SOCKET *Sock,
426 IN OUT LIST_ENTRY *PendingTokenList
427 )
428{
429 SOCK_TOKEN *SockToken;
431
432 ASSERT ((Sock != NULL) && (PendingTokenList != NULL));
433
434 while (!IsListEmpty (PendingTokenList)) {
435 SockToken = NET_LIST_HEAD (
436 PendingTokenList,
438 TokenList
439 );
440
441 Token = SockToken->Token;
442 SIGNAL_TOKEN (Token, Sock->SockError);
443
444 RemoveEntryList (&(SockToken->TokenList));
445 FreePool (SockToken);
446 }
447}
448
456VOID
458 IN OUT SOCKET *Sock
459 )
460{
461 ASSERT (Sock->ConnectionToken != NULL);
462
463 SIGNAL_TOKEN (Sock->ConnectionToken, EFI_SUCCESS);
464 Sock->ConnectionToken = NULL;
465
466 //
467 // check to see if some pending send token existed?
468 //
469 SockProcessSndToken (Sock);
470}
471
478VOID
480 IN OUT SOCKET *Sock
481 )
482{
483 SOCKET *Parent;
484 SOCK_TOKEN *SockToken;
485 EFI_TCP4_LISTEN_TOKEN *ListenToken;
486
487 Parent = Sock->Parent;
488
489 ASSERT ((Parent != NULL) && SOCK_IS_LISTENING (Parent) && SOCK_IS_CONNECTED (Sock));
490
491 if (!IsListEmpty (&Parent->ListenTokenList)) {
492 SockToken = NET_LIST_HEAD (
493 &Parent->ListenTokenList,
495 TokenList
496 );
497
498 ListenToken = (EFI_TCP4_LISTEN_TOKEN *)SockToken->Token;
499 ListenToken->NewChildHandle = Sock->SockHandle;
500
501 SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
502
503 RemoveEntryList (&SockToken->TokenList);
504 FreePool (SockToken);
505
506 RemoveEntryList (&Sock->ConnectionList);
507
508 Parent->ConnCnt--;
509 DEBUG (
510 (DEBUG_NET,
511 "SockWakeListenToken: accept a socket, now conncnt is %d",
512 Parent->ConnCnt)
513 );
514
515 Sock->Parent = NULL;
516 }
517}
518
525VOID
527 IN OUT SOCKET *Sock
528 )
529{
530 UINT32 RcvdBytes;
531 UINT32 TokenRcvdBytes;
532 SOCK_TOKEN *SockToken;
533 SOCK_IO_TOKEN *RcvToken;
534
535 ASSERT (Sock->RcvBuffer.DataQueue != NULL);
536
537 RcvdBytes = (Sock->RcvBuffer.DataQueue)->BufSize;
538
539 ASSERT (RcvdBytes > 0);
540
541 while (RcvdBytes > 0 && !IsListEmpty (&Sock->RcvTokenList)) {
542 SockToken = NET_LIST_HEAD (
543 &Sock->RcvTokenList,
545 TokenList
546 );
547
548 RcvToken = (SOCK_IO_TOKEN *)SockToken->Token;
549 TokenRcvdBytes = SockProcessRcvToken (Sock, RcvToken);
550
551 if (0 == TokenRcvdBytes) {
552 return;
553 }
554
555 RemoveEntryList (&(SockToken->TokenList));
556 FreePool (SockToken);
557 RcvdBytes -= TokenRcvdBytes;
558 }
559}
560
575 IN OUT LIST_ENTRY *SpecifiedTokenList
576 )
577{
578 EFI_STATUS Status;
579 LIST_ENTRY *Entry;
580 SOCK_TOKEN *SockToken;
581
582 Status = EFI_SUCCESS;
583 Entry = NULL;
584 SockToken = NULL;
585
586 if (IsListEmpty (SpecifiedTokenList) && (Token != NULL)) {
587 return EFI_NOT_FOUND;
588 }
589
590 //
591 // Iterate through the SpecifiedTokenList.
592 //
593 Entry = SpecifiedTokenList->ForwardLink;
594 while (Entry != SpecifiedTokenList) {
595 SockToken = NET_LIST_USER_STRUCT (Entry, SOCK_TOKEN, TokenList);
596
597 if (Token == NULL) {
598 SIGNAL_TOKEN (SockToken->Token, EFI_ABORTED);
599 RemoveEntryList (&SockToken->TokenList);
600 FreePool (SockToken);
601
602 Entry = SpecifiedTokenList->ForwardLink;
603 Status = EFI_SUCCESS;
604 } else {
605 if (Token == (VOID *)SockToken->Token) {
606 SIGNAL_TOKEN (Token, EFI_ABORTED);
607 RemoveEntryList (&(SockToken->TokenList));
608 FreePool (SockToken);
609
610 return EFI_SUCCESS;
611 }
612
613 Status = EFI_NOT_FOUND;
614
615 Entry = Entry->ForwardLink;
616 }
617 }
618
619 ASSERT (IsListEmpty (SpecifiedTokenList) || Token != NULL);
620
621 return Status;
622}
623
632SOCKET *
634 IN SOCK_INIT_DATA *SockInitData
635 )
636{
637 SOCKET *Sock;
638 SOCKET *Parent;
639 EFI_STATUS Status;
640 EFI_GUID *TcpProtocolGuid;
641 UINTN ProtocolLength;
642
643 ASSERT ((SockInitData != NULL) && (SockInitData->ProtoHandler != NULL));
644 ASSERT (SockInitData->Type == SockStream);
645 ASSERT ((SockInitData->ProtoData != NULL) && (SockInitData->DataSize <= PROTO_RESERVED_LEN));
646
647 if (SockInitData->IpVersion == IP_VERSION_4) {
648 TcpProtocolGuid = &gEfiTcp4ProtocolGuid;
649 ProtocolLength = sizeof (EFI_TCP4_PROTOCOL);
650 } else {
651 TcpProtocolGuid = &gEfiTcp6ProtocolGuid;
652 ProtocolLength = sizeof (EFI_TCP6_PROTOCOL);
653 }
654
655 Parent = SockInitData->Parent;
656
657 if ((Parent != NULL) && (Parent->ConnCnt == Parent->BackLog)) {
658 DEBUG (
659 (DEBUG_ERROR,
660 "SockCreate: Socket parent has reached its connection limit with %d ConnCnt and %d BackLog\n",
661 Parent->ConnCnt,
662 Parent->BackLog)
663 );
664
665 return NULL;
666 }
667
668 Sock = AllocateZeroPool (sizeof (SOCKET));
669 if (NULL == Sock) {
670 DEBUG ((DEBUG_ERROR, "SockCreate: No resource to create a new socket\n"));
671 return NULL;
672 }
673
674 InitializeListHead (&Sock->Link);
676 InitializeListHead (&Sock->ListenTokenList);
677 InitializeListHead (&Sock->RcvTokenList);
678 InitializeListHead (&Sock->SndTokenList);
679 InitializeListHead (&Sock->ProcessingSndTokenList);
680
681 EfiInitializeLock (&(Sock->Lock), TPL_CALLBACK);
682
684 if (NULL == Sock->SndBuffer.DataQueue) {
685 DEBUG (
686 (DEBUG_ERROR,
687 "SockCreate: No resource to allocate SndBuffer for new socket\n")
688 );
689
690 goto OnError;
691 }
692
694 if (NULL == Sock->RcvBuffer.DataQueue) {
695 DEBUG (
696 (DEBUG_ERROR,
697 "SockCreate: No resource to allocate RcvBuffer for new socket\n")
698 );
699
700 goto OnError;
701 }
702
703 Sock->Signature = SOCK_SIGNATURE;
704
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;
716
717 Sock->SockError = EFI_ABORTED;
718 Sock->SndBuffer.LowWater = SOCK_BUFF_LOW_WATER;
719 Sock->RcvBuffer.LowWater = SOCK_BUFF_LOW_WATER;
720
721 Sock->IpVersion = SockInitData->IpVersion;
722
723 //
724 // Install protocol on Sock->SockHandle
725 //
726 CopyMem (&Sock->NetProtocol, SockInitData->Protocol, ProtocolLength);
727
728 //
729 // copy the protodata into socket
730 //
731 CopyMem (Sock->ProtoReserved, SockInitData->ProtoData, SockInitData->DataSize);
732
733 Status = gBS->InstallMultipleProtocolInterfaces (
734 &Sock->SockHandle,
735 TcpProtocolGuid,
736 &Sock->NetProtocol,
737 NULL
738 );
739
740 if (EFI_ERROR (Status)) {
741 DEBUG (
742 (DEBUG_ERROR,
743 "SockCreate: Install TCP protocol in socket failed with %r\n",
744 Status)
745 );
746
747 goto OnError;
748 }
749
750 if (Parent != NULL) {
751 ASSERT (Parent->BackLog > 0);
752 ASSERT (SOCK_IS_LISTENING (Parent));
753
754 //
755 // need to add it into Parent->ConnectionList
756 // if the Parent->ConnCnt < Parent->BackLog
757 //
758 Parent->ConnCnt++;
759
760 DEBUG (
761 (DEBUG_NET,
762 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
763 Parent->ConnCnt)
764 );
765
767 }
768
769 if (Sock->CreateCallback != NULL) {
770 Status = Sock->CreateCallback (Sock, Sock->Context);
771 if (EFI_ERROR (Status)) {
772 goto OnError;
773 }
774 }
775
776 return Sock;
777
778OnError:
779
780 if (Sock->SockHandle != NULL) {
781 gBS->UninstallMultipleProtocolInterfaces (
782 Sock->SockHandle,
783 TcpProtocolGuid,
784 &Sock->NetProtocol,
785 NULL
786 );
787 }
788
789 if (NULL != Sock->SndBuffer.DataQueue) {
791 }
792
793 if (NULL != Sock->RcvBuffer.DataQueue) {
795 }
796
797 FreePool (Sock);
798
799 return NULL;
800}
801
808VOID
810 IN OUT SOCKET *Sock
811 )
812{
813 ASSERT (SockStream == Sock->Type);
814
815 //
816 // Flush the completion token buffered
817 // by sock and rcv, snd buffer
818 //
819 if (!SOCK_IS_UNCONFIGURED (Sock)) {
820 SockConnFlush (Sock);
821 SockSetState (Sock, SO_CLOSED);
822 Sock->ConfigureState = SO_UNCONFIGURED;
823 }
824
825 //
826 // Destroy the RcvBuffer Queue and SendBuffer Queue
827 //
828 NetbufQueFree (Sock->RcvBuffer.DataQueue);
829 NetbufQueFree (Sock->SndBuffer.DataQueue);
830
831 //
832 // Remove it from parent connection list if needed
833 //
834 if (Sock->Parent != NULL) {
835 RemoveEntryList (&(Sock->ConnectionList));
836 (Sock->Parent->ConnCnt)--;
837
838 DEBUG (
839 (DEBUG_WARN,
840 "SockDestroy: Delete a unaccepted socket from parent now conncnt is %d\n",
841 Sock->Parent->ConnCnt)
842 );
843
844 Sock->Parent = NULL;
845 }
846
847 FreePool (Sock);
848}
849
856VOID
858 IN OUT SOCKET *Sock
859 )
860{
861 SOCKET *Child;
862
863 ASSERT (Sock != NULL);
864
865 //
866 // Clear the flag in this socket
867 //
868 Sock->Flag = 0;
869
870 //
871 // Flush the SndBuffer and RcvBuffer of Sock
872 //
873 NetbufQueFlush (Sock->SndBuffer.DataQueue);
874 NetbufQueFlush (Sock->RcvBuffer.DataQueue);
875
876 //
877 // Signal the pending token
878 //
879 if (Sock->ConnectionToken != NULL) {
880 SIGNAL_TOKEN (Sock->ConnectionToken, Sock->SockError);
881 Sock->ConnectionToken = NULL;
882 }
883
884 if (Sock->CloseToken != NULL) {
885 SIGNAL_TOKEN (Sock->CloseToken, Sock->SockError);
886 Sock->CloseToken = NULL;
887 }
888
889 SockFlushPendingToken (Sock, &(Sock->ListenTokenList));
890 SockFlushPendingToken (Sock, &(Sock->RcvTokenList));
891 SockFlushPendingToken (Sock, &(Sock->SndTokenList));
892 SockFlushPendingToken (Sock, &(Sock->ProcessingSndTokenList));
893
894 //
895 // Destroy the pending connection, if it is a listening socket
896 //
897 if (SOCK_IS_LISTENING (Sock)) {
898 while (!IsListEmpty (&Sock->ConnectionList)) {
899 Child = NET_LIST_HEAD (
900 &Sock->ConnectionList,
901 SOCKET,
902 ConnectionList
903 );
904
906 }
907
908 Sock->ConnCnt = 0;
909 }
910}
911
919VOID
921 IN OUT SOCKET *Sock,
922 IN UINT8 State
923 )
924{
925 Sock->State = State;
926}
927
936SOCKET *
938 IN SOCKET *Sock
939 )
940{
941 SOCKET *ClonedSock;
942 SOCK_INIT_DATA InitData;
943
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);
959
960 ClonedSock = SockCreate (&InitData);
961
962 if (NULL == ClonedSock) {
963 DEBUG ((DEBUG_ERROR, "SockClone: no resource to create a cloned sock\n"));
964 return NULL;
965 }
966
967 SockSetState (ClonedSock, SO_CONNECTING);
968 ClonedSock->ConfigureState = Sock->ConfigureState;
969
970 return ClonedSock;
971}
972
984VOID
986 IN OUT SOCKET *Sock
987 )
988{
989 ASSERT (SO_CONNECTING == Sock->State);
990
991 SockSetState (Sock, SO_CONNECTED);
992
993 if (NULL == Sock->Parent) {
994 SockWakeConnToken (Sock);
995 } else {
996 SockWakeListenToken (Sock);
997 }
998}
999
1010VOID
1012 IN OUT SOCKET *Sock
1013 )
1014{
1015 if (Sock->CloseToken != NULL) {
1016 SIGNAL_TOKEN (Sock->CloseToken, EFI_SUCCESS);
1017 Sock->CloseToken = NULL;
1018 }
1019
1020 SockConnFlush (Sock);
1021 SockSetState (Sock, SO_CLOSED);
1022
1023 if (Sock->Parent != NULL) {
1024 SockDestroyChild (Sock);
1025 }
1026}
1027
1038VOID
1040 IN OUT SOCKET *Sock,
1041 IN UINT32 Count
1042 )
1043{
1044 SOCK_TOKEN *SockToken;
1045 SOCK_COMPLETION_TOKEN *SndToken;
1046
1047 ASSERT (!IsListEmpty (&Sock->ProcessingSndTokenList));
1048 ASSERT (Count <= (Sock->SndBuffer.DataQueue)->BufSize);
1049
1050 NetbufQueTrim (Sock->SndBuffer.DataQueue, Count);
1051
1052 //
1053 // To check if we can signal some snd token in this socket
1054 //
1055 while (Count > 0) {
1056 SockToken = NET_LIST_HEAD (
1057 &(Sock->ProcessingSndTokenList),
1058 SOCK_TOKEN,
1059 TokenList
1060 );
1061
1062 SndToken = SockToken->Token;
1063
1064 if (SockToken->RemainDataLen <= Count) {
1065 RemoveEntryList (&(SockToken->TokenList));
1066 SIGNAL_TOKEN (SndToken, EFI_SUCCESS);
1067 Count -= SockToken->RemainDataLen;
1068 FreePool (SockToken);
1069 } else {
1070 SockToken->RemainDataLen -= Count;
1071 Count = 0;
1072 }
1073 }
1074
1075 //
1076 // to judge if we can process some send token in
1077 // Sock->SndTokenList, if so process those send token
1078 //
1079 SockProcessSndToken (Sock);
1080}
1081
1095UINT32
1097 IN SOCKET *Sock,
1098 IN UINT32 Offset,
1099 IN UINT32 Len,
1100 OUT UINT8 *Dest
1101 )
1102{
1103 ASSERT ((Sock != NULL) && SockStream == Sock->Type);
1104
1105 return NetbufQueCopy (
1106 Sock->SndBuffer.DataQueue,
1107 Offset,
1108 Len,
1109 Dest
1110 );
1111}
1112
1124VOID
1126 IN OUT SOCKET *Sock,
1127 IN OUT NET_BUF *NetBuffer,
1128 IN UINT32 UrgLen
1129 )
1130{
1131 ASSERT (
1132 (Sock != NULL) && (Sock->RcvBuffer.DataQueue != NULL) &&
1133 UrgLen <= NetBuffer->TotalSize
1134 );
1135
1136 NET_GET_REF (NetBuffer);
1137
1138 ((TCP_RSV_DATA *)(NetBuffer->ProtoData))->UrgLen = UrgLen;
1139
1140 NetbufQueAppend (Sock->RcvBuffer.DataQueue, NetBuffer);
1141
1142 SockWakeRcvToken (Sock);
1143}
1144
1155UINT32
1157 IN SOCKET *Sock,
1158 IN UINT32 Which
1159 )
1160{
1161 UINT32 BufferCC;
1162 SOCK_BUFFER *SockBuffer;
1163
1164 ASSERT (Sock != NULL && ((SOCK_SND_BUF == Which) || (SOCK_RCV_BUF == Which)));
1165
1166 if (SOCK_SND_BUF == Which) {
1167 SockBuffer = &(Sock->SndBuffer);
1168 } else {
1169 SockBuffer = &(Sock->RcvBuffer);
1170 }
1171
1172 BufferCC = (SockBuffer->DataQueue)->BufSize;
1173
1174 if (BufferCC >= SockBuffer->HighWater) {
1175 return 0;
1176 }
1177
1178 return SockBuffer->HighWater - BufferCC;
1179}
1180
1191VOID
1193 IN OUT SOCKET *Sock
1194 )
1195{
1196 EFI_STATUS Err;
1197
1198 SOCK_NO_MORE_DATA (Sock);
1199
1200 if (!IsListEmpty (&Sock->RcvTokenList)) {
1201 ASSERT (0 == GET_RCV_DATASIZE (Sock));
1202
1203 Err = Sock->SockError;
1204
1206
1207 SockFlushPendingToken (Sock, &Sock->RcvTokenList);
1208
1209 SOCK_ERROR (Sock, Err);
1210 }
1211}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
Definition: Compress.c:265
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
UINT32 EFIAPI NetbufQueTrim(IN OUT NET_BUF_QUEUE *NbufQue, IN UINT32 Len)
Definition: NetBuffer.c:1537
UINT32 EFIAPI NetbufQueCopy(IN NET_BUF_QUEUE *NbufQue, IN UINT32 Offset, IN UINT32 Len, OUT UINT8 *Dest)
Definition: NetBuffer.c:1438
VOID EFIAPI NetbufQueFlush(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1592
NET_BUF_QUEUE *EFIAPI NetbufQueAlloc(VOID)
Definition: NetBuffer.c:1322
NET_BUF *EFIAPI NetbufFromExt(IN NET_FRAGMENT *ExtFragment, IN UINT32 ExtNum, IN UINT32 HeadSpace, IN UINT32 HeadLen, IN NET_VECTOR_EXT_FREE ExtFree, IN VOID *Arg OPTIONAL)
Definition: NetBuffer.c:693
VOID EFIAPI NetbufQueFree(IN NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1350
VOID EFIAPI NetbufQueAppend(IN OUT NET_BUF_QUEUE *NbufQue, IN OUT NET_BUF *Nbuf)
Definition: NetBuffer.c:1374
#define GET_RCV_DATASIZE(Sock)
Definition: Socket.h:255
#define SOCK_NO_MORE_DATA(Sock)
Definition: Socket.h:103
@ SockStream
This socket providing stream service.
Definition: Socket.h:350
#define SOCK_IS_UNCONFIGURED(Sock)
Definition: Socket.h:114
#define SOCK_IS_LISTENING(Sock)
Definition: Socket.h:182
#define SOCK_SND
Need protocol to send something.
Definition: Socket.h:85
#define SO_CLOSED
Definition: Socket.h:64
EFI_STATUS SockDestroyChild(IN OUT SOCKET *Sock)
#define SO_UNCONFIGURED
Definition: Socket.h:73
#define SOCK_IS_CONNECTED(Sock)
Definition: Socket.h:204
#define SOCK_SNDURG
Need protocol to send urgent data.
Definition: Socket.h:87
#define SOCK_ERROR(Sock, Error)
Definition: Socket.h:312
#define SOCK_SNDPUSH
Need protocol to send pushed data.
Definition: Socket.h:86
EFI_STATUS SockProcessTcpSndData(IN SOCKET *Sock, IN VOID *TcpTxData)
Definition: SockImpl.c:349
VOID SockDestroy(IN OUT SOCKET *Sock)
Definition: SockImpl.c:809
VOID SockDataRcvd(IN OUT SOCKET *Sock, IN OUT NET_BUF *NetBuffer, IN UINT32 UrgLen)
Definition: SockImpl.c:1125
VOID SockProcessSndToken(IN OUT SOCKET *Sock)
Definition: SockImpl.c:230
VOID SockFlushPendingToken(IN SOCKET *Sock, IN OUT LIST_ENTRY *PendingTokenList)
Definition: SockImpl.c:424
VOID SockWakeConnToken(IN OUT SOCKET *Sock)
Definition: SockImpl.c:457
SOCKET * SockCreate(IN SOCK_INIT_DATA *SockInitData)
Definition: SockImpl.c:633
UINT32 SockTcpDataToRcv(IN SOCK_BUFFER *SockBuffer, OUT BOOLEAN *IsUrg, IN UINT32 BufLen)
Definition: SockImpl.c:96
VOID SockConnFlush(IN OUT SOCKET *Sock)
Definition: SockImpl.c:857
NET_BUF * SockBufNext(IN SOCK_BUFFER *Sockbuf, IN NET_BUF *SockEntry)
Definition: SockImpl.c:47
UINT32 SockGetFreeSpace(IN SOCKET *Sock, IN UINT32 Which)
Definition: SockImpl.c:1156
VOID SockNoMoreData(IN OUT SOCKET *Sock)
Definition: SockImpl.c:1192
SOCKET * SockClone(IN SOCKET *Sock)
Definition: SockImpl.c:937
UINT32 SockGetDataToSend(IN SOCKET *Sock, IN UINT32 Offset, IN UINT32 Len, OUT UINT8 *Dest)
Definition: SockImpl.c:1096
VOID SockSetState(IN OUT SOCKET *Sock, IN UINT8 State)
Definition: SockImpl.c:920
VOID SockWakeRcvToken(IN OUT SOCKET *Sock)
Definition: SockImpl.c:526
UINT32 SockProcessRcvToken(IN OUT SOCKET *Sock, IN OUT SOCK_IO_TOKEN *RcvToken)
Definition: SockImpl.c:304
VOID SockWakeListenToken(IN OUT SOCKET *Sock)
Definition: SockImpl.c:479
EFI_STATUS SockCancelToken(IN SOCK_COMPLETION_TOKEN *Token, IN OUT LIST_ENTRY *SpecifiedTokenList)
Definition: SockImpl.c:573
VOID SockConnClosed(IN OUT SOCKET *Sock)
Definition: SockImpl.c:1011
VOID SockSetTcpRxData(IN SOCKET *Sock, IN VOID *TcpRxData, IN UINT32 RcvdBytes, IN BOOLEAN IsUrg)
Definition: SockImpl.c:181
NET_BUF * SockBufFirst(IN SOCK_BUFFER *Sockbuf)
Definition: SockImpl.c:21
VOID SockDataSent(IN OUT SOCKET *Sock, IN UINT32 Count)
Definition: SockImpl.c:1039
VOID EFIAPI SockFreeFoo(IN VOID *Arg)
Definition: SockImpl.c:75
VOID SockConnEstablished(IN OUT SOCKET *Sock)
Definition: SockImpl.c:985
#define SIGNAL_TOKEN(Token, TokenStatus)
Definition: SockImpl.h:23
#define EFI_CONNECTION_FIN
Definition: UefiBaseType.h:175
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
Definition: UefiLib.c:405
NET_BUF_QUEUE * DataQueue
The queue to buffer data.
Definition: Socket.h:359
UINT32 LowWater
The low water mark of sock_buffer.
Definition: Socket.h:358
UINT32 HighWater
The buffersize upper limit of sock_buffer.
Definition: Socket.h:357
UINT32 SndBufferSize
The high water mark of send buffer.
Definition: Socket.h:422
SOCK_PROTO_HANDLER ProtoHandler
The handler of protocol for socket request.
Definition: Socket.h:441
VOID * Protocol
Definition: Socket.h:425
SOCKET * Parent
The parent of this socket.
Definition: Socket.h:420
EFI_HANDLE DriverBinding
The driver binding handle.
Definition: Socket.h:443
VOID * Context
The context of the callback.
Definition: Socket.h:433
UINT32 BackLog
The connection limit for listening socket.
Definition: Socket.h:421
UINT32 RcvBufferSize
The high water mark of receive buffer.
Definition: Socket.h:423
SOCK_CREATE_CALLBACK CreateCallback
Callback after created.
Definition: Socket.h:431
SOCK_DESTROY_CALLBACK DestroyCallback
Callback before destroyed.
Definition: Socket.h:432
LIST_ENTRY TokenList
The entry to add in the token list.
Definition: Socket.h:512
SOCK_COMPLETION_TOKEN * Token
The application's token.
Definition: Socket.h:513
UINT32 RemainDataLen
Unprocessed data length.
Definition: Socket.h:514
SOCK_BUFFER RcvBuffer
Receive buffer of received data.
Definition: Socket.h:472
LIST_ENTRY ConnectionList
the connections maintained by this socket
Definition: Socket.h:482
UINT8 ProtoReserved[PROTO_RESERVED_LEN]
Data fields reserved for protocol.
Definition: Socket.h:497
SOCKET * Parent
listening parent that accept the connection
Definition: Socket.h:481
UINT32 Signature
Signature of the socket.
Definition: Socket.h:460
EFI_LOCK Lock
The lock of socket.
Definition: Socket.h:470
EFI_HANDLE SockHandle
The virtual handle of the socket.
Definition: Socket.h:461
EFI_STATUS SockError
The error returned by low layer protocol.
Definition: Socket.h:473
UINT32 BackLog
the limit of connection to this socket
Definition: Socket.h:479
SOCK_DESTROY_CALLBACK DestroyCallback
Callback before destroyed.
Definition: Socket.h:504
NET_PROTOCOL NetProtocol
TCP4 or TCP6 protocol socket used.
Definition: Socket.h:499
SOCK_PROTO_HANDLER ProtoHandler
The request handler of protocol.
Definition: Socket.h:496
EFI_HANDLE DriverBinding
Socket's driver binding protocol.
Definition: Socket.h:462
UINT32 ConnCnt
the current count of connections to it
Definition: Socket.h:480
SOCK_BUFFER SndBuffer
Send buffer of application's data.
Definition: Socket.h:471
SOCK_CREATE_CALLBACK CreateCallback
Callback after created.
Definition: Socket.h:503
VOID * Context
The context of the callback.
Definition: Socket.h:505
Definition: Base.h:213