]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c
Import ArpDxe, Dhcp4Dxe, Ip4Dxe, Mtftp4Dxe, PxeBcDxe and PxeDhcp4Dxe.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / SockImpl.c
1 /** @file
2
3 Copyright (c) 2005 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 SockImpl.c
15
16 Abstract:
17
18
19 **/
20
21 #include "SockImpl.h"
22
23 STATIC
24 UINT32
25 SockTcpDataToRcv (
26 IN SOCK_BUFFER *SockBuffer,
27 OUT BOOLEAN *IsOOB,
28 IN UINT32 BufLen
29 );
30
31 STATIC
32 VOID
33 SockProcessSndToken (
34 IN SOCKET *Sock
35 );
36
37 VOID
38 SockFreeFoo (
39 IN EFI_EVENT Event
40 )
41 {
42 return ;
43 }
44
45
46 /**
47 Get the length of the data that can be retrieved from the socket
48 receive buffer.
49
50 @param SockBuffer Pointer to the socket receive buffer.
51 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
52 OOB.
53 @param BufLen The maximum length of the data buffer to store the
54 received data in socket layer.
55
56 @return The length of the data can be retreived.
57
58 **/
59 STATIC
60 UINT32
61 SockTcpDataToRcv (
62 IN SOCK_BUFFER *SockBuffer,
63 OUT BOOLEAN *IsUrg,
64 IN UINT32 BufLen
65 )
66 {
67 NET_BUF *RcvBufEntry;
68 UINT32 DataLen;
69 TCP_RSV_DATA *TcpRsvData;
70 BOOLEAN Urg;
71
72 ASSERT (SockBuffer && IsUrg && (BufLen > 0));
73
74 RcvBufEntry = SockBufFirst (SockBuffer);
75 ASSERT (RcvBufEntry);
76
77 TcpRsvData = (TCP_RSV_DATA *) RcvBufEntry->ProtoData;
78
79 *IsUrg = (BOOLEAN) ((TcpRsvData->UrgLen > 0) ? TRUE : FALSE);
80
81 if (*IsUrg && TcpRsvData->UrgLen < RcvBufEntry->TotalSize) {
82
83 DataLen = NET_MIN (TcpRsvData->UrgLen, BufLen);
84
85 if (DataLen < TcpRsvData->UrgLen) {
86 TcpRsvData->UrgLen = TcpRsvData->UrgLen - DataLen;
87 } else {
88 TcpRsvData->UrgLen = 0;
89 }
90
91 return DataLen;
92
93 }
94
95 DataLen = RcvBufEntry->TotalSize;
96
97 RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry);
98
99 while ((BufLen > DataLen) && (RcvBufEntry != NULL)) {
100
101 TcpRsvData = (TCP_RSV_DATA *) RcvBufEntry->ProtoData;
102
103 Urg = (BOOLEAN) ((TcpRsvData->UrgLen > 0) ? TRUE : FALSE);
104
105 if (*IsUrg != Urg) {
106 break;
107 }
108
109 if (*IsUrg && TcpRsvData->UrgLen < RcvBufEntry->TotalSize) {
110
111 if (TcpRsvData->UrgLen + DataLen < BufLen) {
112 TcpRsvData->UrgLen = 0;
113 } else {
114 TcpRsvData->UrgLen = TcpRsvData->UrgLen - (BufLen - DataLen);
115 }
116
117 return NET_MIN (TcpRsvData->UrgLen + DataLen, BufLen);
118
119 }
120
121 DataLen += RcvBufEntry->TotalSize;
122
123 RcvBufEntry = SockBufNext (SockBuffer, RcvBufEntry);
124 }
125
126 DataLen = NET_MIN (BufLen, DataLen);
127 return DataLen;
128 }
129
130
131 /**
132 Copy data from socket buffer to application provided receive buffer.
133
134 @param Sock Pointer to the socket.
135 @param TcpRxData Pointer to the application provided receive buffer.
136 @param RcvdBytes The maximum length of the data can be copied.
137 @param IsOOB If TURE the data is OOB, else the data is normal.
138
139 @return None.
140
141 **/
142 VOID
143 SockSetTcpRxData (
144 IN SOCKET *Sock,
145 IN VOID *TcpRxData,
146 IN UINT32 RcvdBytes,
147 IN BOOLEAN IsOOB
148 )
149 {
150 UINT32 Index;
151 UINT32 CopyBytes;
152 UINT32 OffSet;
153 EFI_TCP4_RECEIVE_DATA *RxData;
154 EFI_TCP4_FRAGMENT_DATA *Fragment;
155
156 RxData = (EFI_TCP4_RECEIVE_DATA *) TcpRxData;
157
158 OffSet = 0;
159
160 ASSERT (RxData->DataLength >= RcvdBytes);
161
162 RxData->DataLength = RcvdBytes;
163 RxData->UrgentFlag = IsOOB;
164
165 for (Index = 0; (Index < RxData->FragmentCount) && (RcvdBytes > 0); Index++) {
166
167 Fragment = &RxData->FragmentTable[Index];
168 CopyBytes = NET_MIN ((UINT32) (Fragment->FragmentLength), RcvdBytes);
169
170 NetbufQueCopy (
171 Sock->RcvBuffer.DataQueue,
172 OffSet,
173 CopyBytes,
174 Fragment->FragmentBuffer
175 );
176
177 Fragment->FragmentLength = CopyBytes;
178 RcvdBytes -= CopyBytes;
179 OffSet += CopyBytes;
180 }
181 }
182
183
184 /**
185 Get received data from the socket layer to the receive token.
186
187 @param Sock Pointer to the socket.
188 @param RcvToken Pointer to the application provided receive token.
189
190 @return The length of data received in this token.
191
192 **/
193 UINT32
194 SockProcessRcvToken (
195 IN SOCKET *Sock,
196 IN SOCK_IO_TOKEN *RcvToken
197 )
198 {
199 UINT32 TokenRcvdBytes;
200 EFI_TCP4_RECEIVE_DATA *RxData;
201 BOOLEAN IsUrg;
202
203 ASSERT (Sock);
204
205 ASSERT (SOCK_STREAM == Sock->Type);
206
207 RxData = RcvToken->Packet.RxData;
208
209 TokenRcvdBytes = SockTcpDataToRcv (
210 &Sock->RcvBuffer,
211 &IsUrg,
212 (UINT32) RxData->DataLength
213 );
214
215 //
216 // Copy data from RcvBuffer of socket to user
217 // provided RxData and set the fields in TCP RxData
218 //
219 SockSetTcpRxData (Sock, RxData, TokenRcvdBytes, IsUrg);
220
221 SOCK_TRIM_RCV_BUFF (Sock, TokenRcvdBytes);
222 SIGNAL_TOKEN (&(RcvToken->Token), EFI_SUCCESS);
223
224 return TokenRcvdBytes;
225 }
226
227
228 /**
229 Process the TCP send data, buffer the tcp txdata and append
230 the buffer to socket send buffer,then try to send it.
231
232 @param Sock Pointer to the socket.
233 @param TcpTxData Pointer to the tcp txdata.
234
235 @retval EFI_SUCCESS The operation is completed successfully.
236 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
237
238 **/
239 EFI_STATUS
240 SockProcessTcpSndData (
241 IN SOCKET *Sock,
242 IN VOID *TcpTxData
243 )
244 {
245 NET_BUF *SndData;
246 EFI_STATUS Status;
247 EFI_TCP4_TRANSMIT_DATA *TxData;
248
249 TxData = (EFI_TCP4_TRANSMIT_DATA *) TcpTxData;
250
251 //
252 // transform this TxData into a NET_BUFFER
253 // and insert it into Sock->SndBuffer
254 //
255 SndData = NetbufFromExt (
256 (NET_FRAGMENT *) TxData->FragmentTable,
257 (UINT32) TxData->FragmentCount,
258 0,
259 0,
260 SockFreeFoo,
261 NULL
262 );
263
264 if (NULL == SndData) {
265 SOCK_DEBUG_ERROR (("SockKProcessSndData: Failed to"
266 " call NetBufferFromExt\n"));
267
268 return EFI_OUT_OF_RESOURCES;
269 }
270
271 NetbufQueAppend (Sock->SndBuffer.DataQueue, SndData);
272
273 //
274 // notify the low layer protocol to handle this send token
275 //
276 if (TxData->Urgent) {
277 Status = Sock->ProtoHandler (Sock, SOCK_SNDURG, NULL);
278
279 if (EFI_ERROR (Status)) {
280 return Status;
281 }
282 }
283
284 if (TxData->Push) {
285 Status = Sock->ProtoHandler (Sock, SOCK_SNDPUSH, NULL);
286
287 if (EFI_ERROR (Status)) {
288 return Status;
289 }
290 }
291
292 //
293 // low layer protocol should really handle the sending
294 // process when catching SOCK_SND request
295 //
296 Status = Sock->ProtoHandler (Sock, SOCK_SND, NULL);
297
298 if (EFI_ERROR (Status)) {
299 return Status;
300 }
301
302 return EFI_SUCCESS;
303 }
304
305
306 /**
307 Flush the tokens in the specific token list.
308
309 @param Sock Pointer to the socket.
310 @param PendingTokenList Pointer to the token list to be flushed.
311
312 @return None.
313
314 **/
315 STATIC
316 VOID
317 SockFlushPendingToken (
318 IN SOCKET *Sock,
319 IN NET_LIST_ENTRY *PendingTokenList
320 )
321 {
322 SOCK_TOKEN *SockToken;
323 SOCK_COMPLETION_TOKEN *Token;
324
325 ASSERT (Sock && PendingTokenList);
326
327 while (!NetListIsEmpty (PendingTokenList)) {
328 SockToken = NET_LIST_HEAD (
329 PendingTokenList,
330 SOCK_TOKEN,
331 TokenList
332 );
333
334 Token = SockToken->Token;
335 SIGNAL_TOKEN (Token, Sock->SockError);
336
337 NetListRemoveEntry (&(SockToken->TokenList));
338 NetFreePool (SockToken);
339 }
340 }
341
342
343 /**
344 Wake up the connection token while the connection is
345 successfully established, then try to process any
346 pending send token.
347
348 @param Sock Pointer to the socket.
349
350 @return None.
351
352 **/
353 STATIC
354 VOID
355 SockWakeConnToken (
356 IN SOCKET *Sock
357 )
358 {
359 ASSERT (Sock->ConnectionToken != NULL);
360
361 SIGNAL_TOKEN (Sock->ConnectionToken, EFI_SUCCESS);
362 Sock->ConnectionToken = NULL;
363
364 //
365 // check to see if some pending send token existed?
366 //
367 SockProcessSndToken (Sock);
368 return ;
369 }
370
371
372 /**
373 Wake up the listen token while the connection is
374 established successfully.
375
376 @param Sock Pointer to the socket.
377
378 @return None.
379
380 **/
381 STATIC
382 VOID
383 SockWakeListenToken (
384 IN SOCKET *Sock
385 )
386 {
387 SOCKET *Parent;
388 SOCK_TOKEN *SockToken;
389 EFI_TCP4_LISTEN_TOKEN *ListenToken;
390
391 Parent = Sock->Parent;
392
393 ASSERT (Parent && SOCK_IS_LISTENING (Parent) && SOCK_IS_CONNECTED (Sock));
394
395 if (!NetListIsEmpty (&Parent->ListenTokenList)) {
396 SockToken = NET_LIST_HEAD (
397 &Parent->ListenTokenList,
398 SOCK_TOKEN,
399 TokenList
400 );
401
402 ListenToken = (EFI_TCP4_LISTEN_TOKEN *) SockToken->Token;
403 ListenToken->NewChildHandle = Sock->SockHandle;
404
405 SIGNAL_TOKEN (&(ListenToken->CompletionToken), EFI_SUCCESS);
406
407 NetListRemoveEntry (&SockToken->TokenList);
408 NetFreePool (SockToken);
409
410 NetListRemoveEntry (&Sock->ConnectionList);
411
412 Parent->ConnCnt--;
413 SOCK_DEBUG_WARN (("SockWakeListenToken: accept a socket,"
414 "now conncnt is %d", Parent->ConnCnt));
415
416 Sock->Parent = NULL;
417 }
418 }
419
420
421 /**
422 Wake up the receive token while some data is received.
423
424 @param Sock Pointer to the socket.
425
426 @return None.
427
428 **/
429 STATIC
430 VOID
431 SockWakeRcvToken (
432 IN SOCKET *Sock
433 )
434 {
435 UINT32 RcvdBytes;
436 UINT32 TokenRcvdBytes;
437 SOCK_TOKEN *SockToken;
438 SOCK_IO_TOKEN *RcvToken;
439
440 ASSERT (Sock->RcvBuffer.DataQueue);
441
442 RcvdBytes = (Sock->RcvBuffer.DataQueue)->BufSize;
443
444 ASSERT (RcvdBytes > 0);
445
446 while (RcvdBytes > 0 && !NetListIsEmpty (&Sock->RcvTokenList)) {
447
448 SockToken = NET_LIST_HEAD (
449 &Sock->RcvTokenList,
450 SOCK_TOKEN,
451 TokenList
452 );
453
454 RcvToken = (SOCK_IO_TOKEN *) SockToken->Token;
455 TokenRcvdBytes = SockProcessRcvToken (Sock, RcvToken);
456
457 if (0 == TokenRcvdBytes) {
458 return ;
459 }
460
461 NetListRemoveEntry (&(SockToken->TokenList));
462 NetFreePool (SockToken);
463 RcvdBytes -= TokenRcvdBytes;
464 }
465 }
466
467
468 /**
469 Process the send token.
470
471 @param Sock Pointer to the socket.
472
473 @return None.
474
475 **/
476 STATIC
477 VOID
478 SockProcessSndToken (
479 IN SOCKET *Sock
480 )
481 {
482 UINT32 FreeSpace;
483 SOCK_TOKEN *SockToken;
484 UINT32 DataLen;
485 SOCK_IO_TOKEN *SndToken;
486 EFI_TCP4_TRANSMIT_DATA *TxData;
487 EFI_STATUS Status;
488
489 ASSERT (Sock && (SOCK_STREAM == Sock->Type));
490
491 FreeSpace = SockGetFreeSpace (Sock, SOCK_SND_BUF);
492
493 //
494 // to determine if process a send token using
495 // socket layer flow control policy
496 //
497 while ((FreeSpace >= Sock->SndBuffer.LowWater) &&
498 !NetListIsEmpty (&Sock->SndTokenList)) {
499
500 SockToken = NET_LIST_HEAD (
501 &(Sock->SndTokenList),
502 SOCK_TOKEN,
503 TokenList
504 );
505
506 //
507 // process this token
508 //
509 NetListRemoveEntry (&(SockToken->TokenList));
510 NetListInsertTail (
511 &(Sock->ProcessingSndTokenList),
512 &(SockToken->TokenList)
513 );
514
515 //
516 // Proceess it in the light of SockType
517 //
518 SndToken = (SOCK_IO_TOKEN *) SockToken->Token;
519 TxData = SndToken->Packet.TxData;
520
521 DataLen = (UINT32) TxData->DataLength;
522 Status = SockProcessTcpSndData (Sock, TxData);
523
524 if (EFI_ERROR (Status)) {
525 goto OnError;
526 }
527
528 if (DataLen >= FreeSpace) {
529 FreeSpace = 0;
530
531 } else {
532 FreeSpace -= DataLen;
533
534 }
535 }
536
537 return ;
538
539 OnError:
540
541 NetListRemoveEntry (&SockToken->TokenList);
542 SIGNAL_TOKEN (SockToken->Token, Status);
543 NetFreePool (SockToken);
544 }
545
546
547 /**
548 Create a socket with initial data SockInitData.
549
550 @param SockInitData Pointer to the initial data of the socket.
551
552 @return Pointer to the newly created socket.
553
554 **/
555 SOCKET *
556 SockCreate (
557 IN SOCK_INIT_DATA *SockInitData
558 )
559 {
560 SOCKET *Sock;
561 SOCKET *Parent;
562 EFI_STATUS Status;
563
564 ASSERT (SockInitData && SockInitData->ProtoHandler);
565 ASSERT (SockInitData->Type == SOCK_STREAM);
566
567 Parent = SockInitData->Parent;
568
569 if (Parent && (Parent->ConnCnt == Parent->BackLog)) {
570 SOCK_DEBUG_ERROR (
571 ("SockCreate: Socket parent has "
572 "reached its connection limit with %d ConnCnt and %d BackLog\n",
573 Parent->ConnCnt,
574 Parent->BackLog)
575 );
576
577 return NULL;
578 }
579
580 Sock = NetAllocateZeroPool (sizeof (SOCKET));
581 if (NULL == Sock) {
582
583 SOCK_DEBUG_ERROR (("SockCreate: No resource to create a new socket\n"));
584 return NULL;
585 }
586
587 NetListInit (&Sock->ConnectionList);
588 NetListInit (&Sock->ListenTokenList);
589 NetListInit (&Sock->RcvTokenList);
590 NetListInit (&Sock->SndTokenList);
591 NetListInit (&Sock->ProcessingSndTokenList);
592
593 NET_LOCK_INIT (&(Sock->Lock));
594
595 Sock->SndBuffer.DataQueue = NetbufQueAlloc ();
596 if (NULL == Sock->SndBuffer.DataQueue) {
597 SOCK_DEBUG_ERROR (("SockCreate: No resource to allocate"
598 " SndBuffer for new socket\n"));
599
600 goto OnError;
601 }
602
603 Sock->RcvBuffer.DataQueue = NetbufQueAlloc ();
604 if (NULL == Sock->RcvBuffer.DataQueue) {
605 SOCK_DEBUG_ERROR (("SockCreate: No resource to allocate "
606 "RcvBuffer for new socket\n"));
607
608 goto OnError;
609 }
610
611 Sock->Signature = SOCK_SIGNATURE;
612
613 Sock->Parent = Parent;
614 Sock->BackLog = SockInitData->BackLog;
615 Sock->ProtoHandler = SockInitData->ProtoHandler;
616 Sock->SndBuffer.HighWater = SockInitData->SndBufferSize;
617 Sock->RcvBuffer.HighWater = SockInitData->RcvBufferSize;
618 Sock->Type = SockInitData->Type;
619 Sock->DriverBinding = SockInitData->DriverBinding;
620 Sock->State = SockInitData->State;
621
622 Sock->SockError = EFI_ABORTED;
623 Sock->SndBuffer.LowWater = SOCK_BUFF_LOW_WATER;
624 Sock->RcvBuffer.LowWater = SOCK_BUFF_LOW_WATER;
625
626 //
627 // Install protocol on Sock->SockHandle
628 //
629 NetCopyMem (
630 &(Sock->NetProtocol.TcpProtocol),
631 SockInitData->Protocol,
632 sizeof (EFI_TCP4_PROTOCOL)
633 );
634
635 Status = gBS->InstallMultipleProtocolInterfaces (
636 &Sock->SockHandle,
637 &gEfiTcp4ProtocolGuid,
638 &(Sock->NetProtocol.TcpProtocol),
639 NULL
640 );
641
642 if (EFI_ERROR (Status)) {
643 SOCK_DEBUG_ERROR (("SockCreate: Install TCP protocol in "
644 "socket failed with %r\n", Status));
645
646 goto OnError;
647 }
648
649 if (Parent != NULL) {
650 ASSERT (Parent->BackLog > 0);
651 ASSERT (SOCK_IS_LISTENING (Parent));
652
653 //
654 // need to add it into Parent->ConnectionList
655 // if the Parent->ConnCnt < Parent->BackLog
656 //
657 Parent->ConnCnt++;
658
659 SOCK_DEBUG_WARN (("SockCreate: Create a new socket and"
660 "add to parent, now conncnt is %d\n", Parent->ConnCnt));
661
662 NetListInsertTail (&Parent->ConnectionList, &Sock->ConnectionList);
663 }
664
665 return Sock;
666
667 OnError:
668 if (NULL != Sock) {
669
670 if (NULL != Sock->SndBuffer.DataQueue) {
671 NetbufQueFree (Sock->SndBuffer.DataQueue);
672 }
673
674 if (NULL != Sock->RcvBuffer.DataQueue) {
675 NetbufQueFree (Sock->RcvBuffer.DataQueue);
676 }
677
678 NetFreePool (Sock);
679 }
680
681 return NULL;
682 }
683
684
685 /**
686 Destroy a socket.
687
688 @param Sock Pointer to the socket.
689
690 @return None.
691
692 **/
693 VOID
694 SockDestroy (
695 IN SOCKET *Sock
696 )
697 {
698 VOID *SockProtocol;
699 EFI_GUID *ProtocolGuid;
700 EFI_STATUS Status;
701
702 ASSERT (SOCK_STREAM == Sock->Type);
703
704 //
705 // Flush the completion token buffered
706 // by sock and rcv, snd buffer
707 //
708 if (!SOCK_IS_UNCONFIGURED (Sock)) {
709
710 SockConnFlush (Sock);
711 SockSetState (Sock, SO_CLOSED);
712 Sock->ConfigureState = SO_UNCONFIGURED;
713
714 }
715 //
716 // Destory the RcvBuffer Queue and SendBuffer Queue
717 //
718 NetbufQueFree (Sock->RcvBuffer.DataQueue);
719 NetbufQueFree (Sock->SndBuffer.DataQueue);
720
721 //
722 // Remove it from parent connection list if needed
723 //
724 if (Sock->Parent) {
725
726 NetListRemoveEntry (&(Sock->ConnectionList));
727 (Sock->Parent->ConnCnt)--;
728
729 SOCK_DEBUG_WARN (("SockDestory: Delete a unaccepted socket from parent"
730 "now conncnt is %d\n", Sock->Parent->ConnCnt));
731
732 Sock->Parent = NULL;
733 }
734
735 //
736 // Set the protocol guid and driver binding handle
737 // in the light of Sock->SockType
738 //
739 ProtocolGuid = &gEfiTcp4ProtocolGuid;
740
741 //
742 // Retrieve the protocol installed on this sock
743 //
744 Status = gBS->OpenProtocol (
745 Sock->SockHandle,
746 ProtocolGuid,
747 &SockProtocol,
748 Sock->DriverBinding,
749 Sock->SockHandle,
750 EFI_OPEN_PROTOCOL_GET_PROTOCOL
751 );
752
753 if (EFI_ERROR (Status)) {
754
755 SOCK_DEBUG_ERROR (("SockDestroy: Open protocol installed "
756 "on socket failed with %r\n", Status));
757
758 goto FreeSock;
759 }
760
761 //
762 // Uninstall the protocol installed on this sock
763 // in the light of Sock->SockType
764 //
765 gBS->UninstallMultipleProtocolInterfaces (
766 Sock->SockHandle,
767 ProtocolGuid,
768 SockProtocol,
769 NULL
770 );
771
772 FreeSock:
773 NetFreePool (Sock);
774 return ;
775 }
776
777
778 /**
779 Flush the socket.
780
781 @param Sock Pointer to the socket.
782
783 @return None.
784
785 **/
786 VOID
787 SockConnFlush (
788 IN SOCKET *Sock
789 )
790 {
791 SOCKET *Child;
792
793 ASSERT (Sock);
794
795 //
796 // Clear the flag in this socket
797 //
798 Sock->Flag = 0;
799
800 //
801 // Flush the SndBuffer and RcvBuffer of Sock
802 //
803 NetbufQueFlush (Sock->SndBuffer.DataQueue);
804 NetbufQueFlush (Sock->RcvBuffer.DataQueue);
805
806 //
807 // Signal the pending token
808 //
809 if (Sock->ConnectionToken != NULL) {
810 SIGNAL_TOKEN (Sock->ConnectionToken, Sock->SockError);
811 Sock->ConnectionToken = NULL;
812 }
813
814 if (Sock->CloseToken != NULL) {
815 SIGNAL_TOKEN (Sock->CloseToken, Sock->SockError);
816 Sock->CloseToken = NULL;
817 }
818
819 SockFlushPendingToken (Sock, &(Sock->ListenTokenList));
820 SockFlushPendingToken (Sock, &(Sock->RcvTokenList));
821 SockFlushPendingToken (Sock, &(Sock->SndTokenList));
822 SockFlushPendingToken (Sock, &(Sock->ProcessingSndTokenList));
823
824 //
825 // Destroy the pending connection, if it is a listening socket
826 //
827 if (SOCK_IS_LISTENING (Sock)) {
828 while (!NetListIsEmpty (&Sock->ConnectionList)) {
829 Child = NET_LIST_HEAD (
830 &Sock->ConnectionList,
831 SOCKET,
832 ConnectionList
833 );
834
835 SockDestroyChild (Child);
836 }
837
838 Sock->ConnCnt = 0;
839 }
840
841 return ;
842 }
843
844
845 /**
846 Set the state of the socket.
847
848 @param Sock Pointer to the socket.
849 @param State The new state to be set.
850
851 @return None.
852
853 **/
854 VOID
855 SockSetState (
856 IN SOCKET *Sock,
857 IN SOCK_STATE State
858 )
859 {
860 Sock->State = State;
861 }
862
863
864 /**
865 Clone a new socket including its associated protocol control block.
866
867 @param Sock Pointer to the socket to be cloned.
868
869 @retval * Pointer to the newly cloned socket. If NULL, error
870 condition occurred.
871
872 **/
873 SOCKET *
874 SockClone (
875 IN SOCKET *Sock
876 )
877 {
878 SOCKET *ClonedSock;
879 SOCK_INIT_DATA InitData;
880
881 InitData.BackLog = Sock->BackLog;
882 InitData.Parent = Sock;
883 InitData.State = Sock->State;
884 InitData.ProtoHandler = Sock->ProtoHandler;
885 InitData.Type = Sock->Type;
886 InitData.RcvBufferSize = Sock->RcvBuffer.HighWater;
887 InitData.SndBufferSize = Sock->SndBuffer.HighWater;
888 InitData.DriverBinding = Sock->DriverBinding;
889 InitData.Protocol = &(Sock->NetProtocol);
890
891 ClonedSock = SockCreate (&InitData);
892
893 if (NULL == ClonedSock) {
894 SOCK_DEBUG_ERROR (("SockClone: no resource to create a cloned sock\n"));
895 return NULL;
896 }
897
898 NetCopyMem (
899 ClonedSock->ProtoReserved,
900 Sock->ProtoReserved,
901 PROTO_RESERVED_LEN
902 );
903
904 SockSetState (ClonedSock, SO_CONNECTING);
905 ClonedSock->ConfigureState = Sock->ConfigureState;
906
907 return ClonedSock;
908 }
909
910
911 /**
912 Called by the low layer protocol to indicate the socket
913 a connection is established. This function just changes
914 the socket's state to SO_CONNECTED and signals the token
915 used for connection establishment.
916
917 @param Sock Pointer to the socket associated with the
918 established connection.
919
920 @return None.
921
922 **/
923 VOID
924 SockConnEstablished (
925 IN SOCKET *Sock
926 )
927 {
928
929 ASSERT (SO_CONNECTING == Sock->State);
930
931 SockSetState (Sock, SO_CONNECTED);
932
933 if (NULL == Sock->Parent) {
934 SockWakeConnToken (Sock);
935 } else {
936 SockWakeListenToken (Sock);
937 }
938
939 return ;
940 }
941
942
943 /**
944 Called by the low layer protocol to indicate the connection
945 is closed. This function flushes the socket, sets the state
946 to SO_CLOSED and signals the close token.
947
948 @param Sock Pointer to the socket associated with the closed
949 connection.
950
951 @return None.
952
953 **/
954 VOID
955 SockConnClosed (
956 IN SOCKET *Sock
957 )
958 {
959 if (Sock->CloseToken) {
960 SIGNAL_TOKEN (Sock->CloseToken, EFI_SUCCESS);
961 Sock->CloseToken = NULL;
962 }
963
964 SockConnFlush (Sock);
965 SockSetState (Sock, SO_CLOSED);
966
967 if (Sock->Parent != NULL) {
968 SockDestroyChild (Sock);
969 }
970
971 }
972
973
974 /**
975 Called by low layer protocol to indicate that some
976 data is sent or processed. This function trims the
977 sent data in the socket send buffer, signals the
978 data token if proper
979
980 @param Sock Pointer to the socket.
981 @param Count The length of the data processed or sent, in bytes.
982
983 @return None.
984
985 **/
986 VOID
987 SockDataSent (
988 IN SOCKET *Sock,
989 IN UINT32 Count
990 )
991 {
992 SOCK_TOKEN *SockToken;
993 SOCK_COMPLETION_TOKEN *SndToken;
994
995 ASSERT (!NetListIsEmpty (&Sock->ProcessingSndTokenList));
996 ASSERT (Count <= (Sock->SndBuffer.DataQueue)->BufSize);
997
998 NetbufQueTrim (Sock->SndBuffer.DataQueue, Count);
999
1000 //
1001 // To check if we can signal some snd token in this socket
1002 //
1003 while (Count > 0) {
1004 SockToken = NET_LIST_HEAD (
1005 &(Sock->ProcessingSndTokenList),
1006 SOCK_TOKEN,
1007 TokenList
1008 );
1009
1010 SndToken = SockToken->Token;
1011
1012 if (SockToken->RemainDataLen <= Count) {
1013
1014 NetListRemoveEntry (&(SockToken->TokenList));
1015 SIGNAL_TOKEN (SndToken, EFI_SUCCESS);
1016 Count -= SockToken->RemainDataLen;
1017 NetFreePool (SockToken);
1018 } else {
1019
1020 SockToken->RemainDataLen -= Count;
1021 Count = 0;
1022 }
1023 }
1024
1025 //
1026 // to judge if we can process some send token in
1027 // Sock->SndTokenList, if so process those send token
1028 //
1029 SockProcessSndToken (Sock);
1030 return ;
1031 }
1032
1033
1034 /**
1035 Called by the low layer protocol to copy some data in socket send
1036 buffer starting from the specific offset to a buffer provided by
1037 the caller.
1038
1039 @param Sock Pointer to the socket.
1040 @param Offset The start point of the data to be copied.
1041 @param Len The length of the data to be copied.
1042 @param Dest Pointer to the destination to copy the data.
1043
1044 @return The data size copied.
1045
1046 **/
1047 UINT32
1048 SockGetDataToSend (
1049 IN SOCKET *Sock,
1050 IN UINT32 Offset,
1051 IN UINT32 Len,
1052 IN UINT8 *Dest
1053 )
1054 {
1055 ASSERT (Sock && SOCK_STREAM == Sock->Type);
1056
1057 return NetbufQueCopy (
1058 Sock->SndBuffer.DataQueue,
1059 Offset,
1060 Len,
1061 Dest
1062 );
1063 }
1064
1065
1066 /**
1067 Called by the low layer protocol to deliver received data
1068 to socket layer. This function will append the data to the
1069 socket receive buffer, set ther urgent data length and then
1070 check if any receive token can be signaled.
1071
1072 @param Sock Pointer to the socket.
1073 @param NetBuffer Pointer to the buffer that contains the received
1074 data.
1075 @param UrgLen The length of the urgent data in the received data.
1076
1077 @return None.
1078
1079 **/
1080 VOID
1081 SockDataRcvd (
1082 IN SOCKET *Sock,
1083 IN NET_BUF *NetBuffer,
1084 IN UINT32 UrgLen
1085 )
1086 {
1087 ASSERT (Sock && Sock->RcvBuffer.DataQueue &&
1088 UrgLen <= NetBuffer->TotalSize);
1089
1090 NET_GET_REF (NetBuffer);
1091
1092 ((TCP_RSV_DATA *) (NetBuffer->ProtoData))->UrgLen = UrgLen;
1093
1094 NetbufQueAppend (Sock->RcvBuffer.DataQueue, NetBuffer);
1095
1096 SockWakeRcvToken (Sock);
1097 return ;
1098 }
1099
1100
1101 /**
1102 Get the length of the free space of the specific socket buffer.
1103
1104 @param Sock Pointer to the socket.
1105 @param Which Flag to indicate which socket buffer to check,
1106 either send buffer or receive buffer.
1107
1108 @return The length of the free space, in bytes.
1109
1110 **/
1111 UINT32
1112 SockGetFreeSpace (
1113 IN SOCKET *Sock,
1114 IN UINT32 Which
1115 )
1116 {
1117 UINT32 BufferCC;
1118 SOCK_BUFFER *SockBuffer;
1119
1120 ASSERT (Sock && ((SOCK_SND_BUF == Which) || (SOCK_RCV_BUF == Which)));
1121
1122 if (SOCK_SND_BUF == Which) {
1123 SockBuffer = &(Sock->SndBuffer);
1124 } else {
1125 SockBuffer = &(Sock->RcvBuffer);
1126 }
1127
1128 BufferCC = (SockBuffer->DataQueue)->BufSize;
1129
1130 if (BufferCC >= SockBuffer->HighWater) {
1131
1132 return 0;
1133 }
1134
1135 return SockBuffer->HighWater - BufferCC;
1136 }
1137
1138
1139 /**
1140 Signal the receive token with the specific error or
1141 set socket error code after error is received.
1142
1143 @param Sock Pointer to the socket.
1144 @param Error The error code received.
1145
1146 @return None.
1147
1148 **/
1149 VOID
1150 SockRcvdErr (
1151 IN SOCKET *Sock,
1152 IN EFI_STATUS Error
1153 )
1154 {
1155 SOCK_TOKEN *SockToken;
1156
1157 if (!NetListIsEmpty (&Sock->RcvTokenList)) {
1158
1159 SockToken = NET_LIST_HEAD (
1160 &Sock->RcvTokenList,
1161 SOCK_TOKEN,
1162 TokenList
1163 );
1164
1165 NetListRemoveEntry (&SockToken->TokenList);
1166
1167 SIGNAL_TOKEN (SockToken->Token, Error);
1168
1169 NetFreePool (SockToken);
1170 } else {
1171
1172 SOCK_ERROR (Sock, Error);
1173 }
1174 }
1175
1176
1177 /**
1178 Called by the low layer protocol to indicate that there
1179 will be no more data from the communication peer. This
1180 function set the socket's state to SO_NO_MORE_DATA and
1181 signal all queued IO tokens with the error status
1182 EFI_CONNECTION_FIN.
1183
1184 @param Sock Pointer to the socket.
1185
1186 @return None.
1187
1188 **/
1189 VOID
1190 SockNoMoreData (
1191 IN SOCKET *Sock
1192 )
1193 {
1194 EFI_STATUS Err;
1195
1196 SOCK_NO_MORE_DATA (Sock);
1197
1198 if (!NetListIsEmpty (&Sock->RcvTokenList)) {
1199
1200 ASSERT (0 == GET_RCV_DATASIZE (Sock));
1201
1202 Err = Sock->SockError;
1203
1204 SOCK_ERROR (Sock, EFI_CONNECTION_FIN);
1205
1206 SockFlushPendingToken (Sock, &Sock->RcvTokenList);
1207
1208 SOCK_ERROR (Sock, Err);
1209
1210 }
1211
1212 }
1213
1214
1215 /**
1216 Get the first buffer block in the specific socket buffer.
1217
1218 @param Sockbuf Pointer to the socket buffer.
1219
1220 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
1221
1222 **/
1223 NET_BUF *
1224 SockBufFirst (
1225 IN SOCK_BUFFER *Sockbuf
1226 )
1227 {
1228 NET_LIST_ENTRY *NetbufList;
1229
1230 NetbufList = &(Sockbuf->DataQueue->BufList);
1231
1232 if (NetListIsEmpty (NetbufList)) {
1233 return NULL;
1234 }
1235
1236 return NET_LIST_HEAD (NetbufList, NET_BUF, List);
1237 }
1238
1239
1240 /**
1241 Get the next buffer block in the specific socket buffer.
1242
1243 @param Sockbuf Pointer to the socket buffer.
1244 @param SockEntry Pointer to the buffer block prior to the required
1245 one.
1246
1247 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is the tail or head entry.
1248
1249 **/
1250 NET_BUF *
1251 SockBufNext (
1252 IN SOCK_BUFFER *Sockbuf,
1253 IN NET_BUF *SockEntry
1254 )
1255 {
1256 NET_LIST_ENTRY *NetbufList;
1257
1258 NetbufList = &(Sockbuf->DataQueue->BufList);
1259
1260 if ((SockEntry->List.ForwardLink == NetbufList) ||
1261 (SockEntry->List.BackLink == &SockEntry->List) ||
1262 (SockEntry->List.ForwardLink == &SockEntry->List)
1263 ) {
1264
1265 return NULL;
1266 }
1267
1268 return NET_LIST_USER_STRUCT (SockEntry->List.ForwardLink, NET_BUF, List);
1269 }