TianoCore EDK2 master
Loading...
Searching...
No Matches
TcpDispatcher.c
Go to the documentation of this file.
1
11#include "TcpMain.h"
12
31 IN TCP_CB *Tcb,
32 IN TCP4_ROUTE_INFO *RouteInfo
33 )
34{
36
37 Ip = Tcb->IpInfo->Ip;
38
39 ASSERT (Ip.Ip4 != NULL);
40
41 return Ip.Ip4->Routes (
42 Ip.Ip4,
43 RouteInfo->DeleteRoute,
44 RouteInfo->SubnetAddress,
45 RouteInfo->SubnetMask,
46 RouteInfo->GatewayAddress
47 );
48}
49
64 IN TCP_CB *Tcb,
66 )
67{
68 SOCKET *Sock;
69 EFI_TCP4_CONFIG_DATA *ConfigData;
70 EFI_TCP4_ACCESS_POINT *AccessPoint;
71 EFI_TCP4_OPTION *Option;
73
74 Sock = Tcb->Sk;
75
76 if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) {
77 return EFI_NOT_STARTED;
78 }
79
80 if (Mode->Tcp4State != NULL) {
81 *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE)Tcb->State;
82 }
83
84 if (Mode->Tcp4ConfigData != NULL) {
85 ConfigData = Mode->Tcp4ConfigData;
86 AccessPoint = &(ConfigData->AccessPoint);
87 Option = ConfigData->ControlOption;
88
89 ConfigData->TypeOfService = Tcb->Tos;
90 ConfigData->TimeToLive = Tcb->Ttl;
91
92 AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;
93
94 IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);
95
96 IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask);
97 AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
98
99 IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);
100
101 AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
102 AccessPoint->ActiveFlag = (BOOLEAN)(Tcb->State != TCP_LISTEN);
103
104 if (Option != NULL) {
105 Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);
106 Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);
107 Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);
108
109 Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;
110 Option->DataRetries = Tcb->MaxRexmit;
111 Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;
112 Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;
113 Option->KeepAliveProbes = Tcb->MaxKeepAlive;
114 Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;
115 Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;
116
117 Option->EnableNagle = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));
118 Option->EnableTimeStamp = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));
119 Option->EnableWindowScaling = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));
120
121 Option->EnableSelectiveAck = FALSE;
122 Option->EnablePathMtuDiscovery = FALSE;
123 }
124 }
125
126 Ip = Tcb->IpInfo->Ip.Ip4;
127 ASSERT (Ip != NULL);
128
129 return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData);
130}
131
146 IN TCP_CB *Tcb,
147 IN OUT TCP6_MODE_DATA *Mode
148 )
149{
150 SOCKET *Sock;
151 EFI_TCP6_CONFIG_DATA *ConfigData;
152 EFI_TCP6_ACCESS_POINT *AccessPoint;
153 EFI_TCP6_OPTION *Option;
155
156 Sock = Tcb->Sk;
157
158 if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp6ConfigData != NULL)) {
159 return EFI_NOT_STARTED;
160 }
161
162 if (Mode->Tcp6State != NULL) {
163 *(Mode->Tcp6State) = (EFI_TCP6_CONNECTION_STATE)(Tcb->State);
164 }
165
166 if (Mode->Tcp6ConfigData != NULL) {
167 ConfigData = Mode->Tcp6ConfigData;
168 AccessPoint = &(ConfigData->AccessPoint);
169 Option = ConfigData->ControlOption;
170
171 ConfigData->TrafficClass = Tcb->Tos;
172 ConfigData->HopLimit = Tcb->Ttl;
173
174 AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);
175 AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);
176 AccessPoint->ActiveFlag = (BOOLEAN)(Tcb->State != TCP_LISTEN);
177
178 IP6_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);
179 IP6_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);
180
181 if (Option != NULL) {
182 Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);
183 Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);
184 Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);
185
186 Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;
187 Option->DataRetries = Tcb->MaxRexmit;
188 Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;
189 Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;
190 Option->KeepAliveProbes = Tcb->MaxKeepAlive;
191 Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;
192 Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;
193
194 Option->EnableNagle = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));
195 Option->EnableTimeStamp = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));
196 Option->EnableWindowScaling = (BOOLEAN)(!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));
197
198 Option->EnableSelectiveAck = FALSE;
200 }
201 }
202
203 Ip = Tcb->IpInfo->Ip.Ip6;
204 ASSERT (Ip != NULL);
205
206 return Ip->GetModeData (Ip, Mode->Ip6ModeData, Mode->MnpConfigData, Mode->SnpModeData);
207}
208
224 IN TCP_ACCESS_POINT *TcpAp,
225 IN UINT8 IpVersion
226 )
227{
228 BOOLEAN Cycle;
229 EFI_IP_ADDRESS Local;
230 UINT16 *Port;
231 UINT16 *RandomPort;
232
233 if (IpVersion == IP_VERSION_4) {
234 IP4_COPY_ADDRESS (&Local, &TcpAp->Tcp4Ap.StationAddress);
235 Port = &TcpAp->Tcp4Ap.StationPort;
236 RandomPort = &mTcp4RandomPort;
237 } else {
238 IP6_COPY_ADDRESS (&Local, &TcpAp->Tcp6Ap.StationAddress);
239 Port = &TcpAp->Tcp6Ap.StationPort;
240 RandomPort = &mTcp6RandomPort;
241 }
242
243 if (0 != *Port) {
244 //
245 // Check if a same endpoing is bound.
246 //
247 if (TcpFindTcbByPeer (&Local, *Port, IpVersion)) {
248 return EFI_INVALID_PARAMETER;
249 }
250 } else {
251 //
252 // generate a random port
253 //
254 Cycle = FALSE;
255
256 if (TCP_PORT_USER_RESERVED == *RandomPort) {
257 *RandomPort = TCP_PORT_KNOWN;
258 }
259
260 (*RandomPort)++;
261
262 while (TcpFindTcbByPeer (&Local, *RandomPort, IpVersion)) {
263 (*RandomPort)++;
264
265 if (*RandomPort <= TCP_PORT_KNOWN) {
266 if (Cycle) {
267 DEBUG (
268 (DEBUG_ERROR,
269 "TcpBind: no port can be allocated for this pcb\n")
270 );
271 return EFI_OUT_OF_RESOURCES;
272 }
273
274 *RandomPort = TCP_PORT_KNOWN + 1;
275
276 Cycle = TRUE;
277 }
278 }
279
280 *Port = *RandomPort;
281 }
282
283 return EFI_SUCCESS;
284}
285
292VOID
294 IN OUT TCP_CB *Tcb
295 )
296{
297 SOCKET *Sock;
298
299 IpIoConfigIp (Tcb->IpInfo, NULL);
300
301 Sock = Tcb->Sk;
302
303 if (SOCK_IS_CONFIGURED (Sock)) {
304 RemoveEntryList (&Tcb->List);
305
306 if (Sock->DevicePath != NULL) {
307 //
308 // Uninstall the device path protocol.
309 //
310 gBS->UninstallProtocolInterface (
311 Sock->SockHandle,
312 &gEfiDevicePathProtocolGuid,
313 Sock->DevicePath
314 );
315
316 FreePool (Sock->DevicePath);
317 Sock->DevicePath = NULL;
318 }
319 }
320
321 NetbufFreeList (&Tcb->SndQue);
322 NetbufFreeList (&Tcb->RcvQue);
323 Tcb->State = TCP_CLOSED;
324 Tcb->RemoteIpZero = FALSE;
325}
326
338 IN SOCKET *Sk
339 )
340{
341 TCP_CB *Tcb;
342 TCP_PROTO_DATA *ProtoData;
343 IP_IO *IpIo;
344 EFI_STATUS Status;
345 VOID *Ip;
346 EFI_GUID *IpProtocolGuid;
347
348 if (Sk->IpVersion == IP_VERSION_4) {
349 IpProtocolGuid = &gEfiIp4ProtocolGuid;
350 } else {
351 IpProtocolGuid = &gEfiIp6ProtocolGuid;
352 }
353
354 Tcb = AllocateZeroPool (sizeof (TCP_CB));
355
356 if (Tcb == NULL) {
357 DEBUG ((DEBUG_ERROR, "TcpConfigurePcb: failed to allocate a TCB\n"));
358
359 return EFI_OUT_OF_RESOURCES;
360 }
361
362 ProtoData = (TCP_PROTO_DATA *)Sk->ProtoReserved;
363 IpIo = ProtoData->TcpService->IpIo;
364
365 //
366 // Create an IpInfo for this Tcb.
367 //
368 Tcb->IpInfo = IpIoAddIp (IpIo);
369 if (Tcb->IpInfo == NULL) {
370 FreePool (Tcb);
371 return EFI_OUT_OF_RESOURCES;
372 }
373
374 //
375 // Open the new created IP instance BY_CHILD.
376 //
377 Status = gBS->OpenProtocol (
378 Tcb->IpInfo->ChildHandle,
379 IpProtocolGuid,
380 &Ip,
381 IpIo->Image,
382 Sk->SockHandle,
383 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
384 );
385 if (EFI_ERROR (Status)) {
386 IpIoRemoveIp (IpIo, Tcb->IpInfo);
387 FreePool (Tcb);
388 return Status;
389 }
390
391 InitializeListHead (&Tcb->List);
394
395 Tcb->State = TCP_CLOSED;
396 Tcb->Sk = Sk;
397 ProtoData->TcpPcb = Tcb;
398
399 return EFI_SUCCESS;
400}
401
408VOID
410 IN OUT SOCKET *Sk
411 )
412{
413 TCP_PROTO_DATA *ProtoData;
414 TCP_CB *Tcb;
415
416 ProtoData = (TCP_PROTO_DATA *)Sk->ProtoReserved;
417 Tcb = ProtoData->TcpPcb;
418
419 ASSERT (Tcb != NULL);
420
421 TcpFlushPcb (Tcb);
422
423 IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);
424
425 FreePool (Tcb);
426
427 ProtoData->TcpPcb = NULL;
428}
429
444 IN SOCKET *Sk,
445 IN TCP_CONFIG_DATA *CfgData
446 )
447{
448 IP_IO_IP_CONFIG_DATA IpCfgData;
449 EFI_STATUS Status;
450 EFI_TCP4_OPTION *Option;
451 TCP_PROTO_DATA *TcpProto;
452 TCP_CB *Tcb;
453 TCP_ACCESS_POINT *TcpAp;
454
455 ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));
456
457 TcpProto = (TCP_PROTO_DATA *)Sk->ProtoReserved;
458 Tcb = TcpProto->TcpPcb;
459
460 ASSERT (Tcb != NULL);
461
462 if (Sk->IpVersion == IP_VERSION_4) {
463 //
464 // Add Ip for send pkt to the peer
465 //
466 CopyMem (&IpCfgData.Ip4CfgData, &mIp4IoDefaultIpConfigData, sizeof (EFI_IP4_CONFIG_DATA));
467 IpCfgData.Ip4CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
468 IpCfgData.Ip4CfgData.TypeOfService = CfgData->Tcp4CfgData.TypeOfService;
469 IpCfgData.Ip4CfgData.TimeToLive = CfgData->Tcp4CfgData.TimeToLive;
470 IpCfgData.Ip4CfgData.UseDefaultAddress = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;
471 IP4_COPY_ADDRESS (
472 &IpCfgData.Ip4CfgData.SubnetMask,
473 &CfgData->Tcp4CfgData.AccessPoint.SubnetMask
474 );
475 IpCfgData.Ip4CfgData.ReceiveTimeout = (UINT32)(-1);
476 IP4_COPY_ADDRESS (
477 &IpCfgData.Ip4CfgData.StationAddress,
478 &CfgData->Tcp4CfgData.AccessPoint.StationAddress
479 );
480 } else {
481 ASSERT (Sk->IpVersion == IP_VERSION_6);
482
483 CopyMem (&IpCfgData.Ip6CfgData, &mIp6IoDefaultIpConfigData, sizeof (EFI_IP6_CONFIG_DATA));
484 IpCfgData.Ip6CfgData.DefaultProtocol = EFI_IP_PROTO_TCP;
485 IpCfgData.Ip6CfgData.TrafficClass = CfgData->Tcp6CfgData.TrafficClass;
486 IpCfgData.Ip6CfgData.HopLimit = CfgData->Tcp6CfgData.HopLimit;
487 IpCfgData.Ip6CfgData.ReceiveTimeout = (UINT32)(-1);
488 IP6_COPY_ADDRESS (
489 &IpCfgData.Ip6CfgData.StationAddress,
490 &CfgData->Tcp6CfgData.AccessPoint.StationAddress
491 );
492 IP6_COPY_ADDRESS (
493 &IpCfgData.Ip6CfgData.DestinationAddress,
494 &CfgData->Tcp6CfgData.AccessPoint.RemoteAddress
495 );
496 }
497
498 //
499 // Configure the IP instance this Tcb consumes.
500 //
501 Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);
502 if (EFI_ERROR (Status)) {
503 goto OnExit;
504 }
505
506 if (Sk->IpVersion == IP_VERSION_4) {
507 //
508 // Get the default address information if the instance is configured to use default address.
509 //
510 IP4_COPY_ADDRESS (
511 &CfgData->Tcp4CfgData.AccessPoint.StationAddress,
512 &IpCfgData.Ip4CfgData.StationAddress
513 );
514 IP4_COPY_ADDRESS (
515 &CfgData->Tcp4CfgData.AccessPoint.SubnetMask,
516 &IpCfgData.Ip4CfgData.SubnetMask
517 );
518
519 TcpAp = (TCP_ACCESS_POINT *)&CfgData->Tcp4CfgData.AccessPoint;
520 } else {
521 IP6_COPY_ADDRESS (
522 &CfgData->Tcp6CfgData.AccessPoint.StationAddress,
523 &IpCfgData.Ip6CfgData.StationAddress
524 );
525
526 TcpAp = (TCP_ACCESS_POINT *)&CfgData->Tcp6CfgData.AccessPoint;
527 }
528
529 //
530 // check if we can bind this endpoint in CfgData
531 //
532 Status = TcpBind (TcpAp, Sk->IpVersion);
533
534 if (EFI_ERROR (Status)) {
535 DEBUG (
536 (DEBUG_ERROR,
537 "TcpConfigurePcb: Bind endpoint failed with %r\n",
538 Status)
539 );
540
541 goto OnExit;
542 }
543
544 //
545 // Initialize the operating information in this Tcb
546 //
547 ASSERT (
548 Tcb->State == TCP_CLOSED &&
549 IsListEmpty (&Tcb->SndQue) &&
550 IsListEmpty (&Tcb->RcvQue)
551 );
552
553 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
554 Tcb->State = TCP_CLOSED;
555
556 Tcb->SndMss = 536;
557 Tcb->RcvMss = TcpGetRcvMss (Sk);
558
559 Tcb->SRtt = 0;
560 Tcb->Rto = 3 * TCP_TICK_HZ;
561
562 Tcb->CWnd = Tcb->SndMss;
563 Tcb->Ssthresh = 0xffffffff;
564
566
568 Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;
569 Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;
570 Tcb->MaxRexmit = TCP_MAX_LOSS;
571 Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;
572 Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;
573 Tcb->ConnectTimeout = TCP_CONNECT_TIME;
574
575 if (Sk->IpVersion == IP_VERSION_4) {
576 //
577 // initialize Tcb in the light of CfgData
578 //
579 Tcb->Ttl = CfgData->Tcp4CfgData.TimeToLive;
580 Tcb->Tos = CfgData->Tcp4CfgData.TypeOfService;
581
582 Tcb->UseDefaultAddr = CfgData->Tcp4CfgData.AccessPoint.UseDefaultAddress;
583
584 CopyMem (&Tcb->LocalEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.StationAddress, sizeof (IP4_ADDR));
585 Tcb->LocalEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.StationPort);
586 IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->Tcp4CfgData.AccessPoint.SubnetMask);
587
588 CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->Tcp4CfgData.AccessPoint.RemoteAddress, sizeof (IP4_ADDR));
589 Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp4CfgData.AccessPoint.RemotePort);
590
591 Option = CfgData->Tcp4CfgData.ControlOption;
592 } else {
593 Tcb->Ttl = CfgData->Tcp6CfgData.HopLimit;
594 Tcb->Tos = CfgData->Tcp6CfgData.TrafficClass;
595
596 IP6_COPY_ADDRESS (&Tcb->LocalEnd.Ip, &CfgData->Tcp6CfgData.AccessPoint.StationAddress);
597 Tcb->LocalEnd.Port = HTONS (CfgData->Tcp6CfgData.AccessPoint.StationPort);
598
599 IP6_COPY_ADDRESS (&Tcb->RemoteEnd.Ip, &CfgData->Tcp6CfgData.AccessPoint.RemoteAddress);
600 Tcb->RemoteEnd.Port = HTONS (CfgData->Tcp6CfgData.AccessPoint.RemotePort);
601
602 //
603 // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
604 //
605 Option = (EFI_TCP4_OPTION *)CfgData->Tcp6CfgData.ControlOption;
606 }
607
608 if (Option != NULL) {
610 Sk,
611 (UINT32)(TCP_COMP_VAL (
612 TCP_RCV_BUF_SIZE_MIN,
613 TCP_RCV_BUF_SIZE,
614 TCP_RCV_BUF_SIZE,
615 Option->ReceiveBufferSize
616 )
617 )
618 );
620 Sk,
621 (UINT32)(TCP_COMP_VAL (
622 TCP_SND_BUF_SIZE_MIN,
623 TCP_SND_BUF_SIZE,
624 TCP_SND_BUF_SIZE,
625 Option->SendBufferSize
626 )
627 )
628 );
629
631 Sk,
632 (UINT32)(TCP_COMP_VAL (
633 TCP_BACKLOG_MIN,
634 TCP_BACKLOG,
635 TCP_BACKLOG,
636 Option->MaxSynBackLog
637 )
638 )
639 );
640
641 Tcb->MaxRexmit = (UINT16)TCP_COMP_VAL (
642 TCP_MAX_LOSS_MIN,
645 Option->DataRetries
646 );
647 Tcb->FinWait2Timeout = TCP_COMP_VAL (
648 TCP_FIN_WAIT2_TIME,
649 TCP_FIN_WAIT2_TIME_MAX,
650 TCP_FIN_WAIT2_TIME,
651 (UINT32)(Option->FinTimeout * TCP_TICK_HZ)
652 );
653
654 if (Option->TimeWaitTimeout != 0) {
655 Tcb->TimeWaitTimeout = TCP_COMP_VAL (
656 TCP_TIME_WAIT_TIME,
657 TCP_TIME_WAIT_TIME_MAX,
658 TCP_TIME_WAIT_TIME,
659 (UINT32)(Option->TimeWaitTimeout * TCP_TICK_HZ)
660 );
661 } else {
662 Tcb->TimeWaitTimeout = 0;
663 }
664
665 if (Option->KeepAliveProbes != 0) {
666 TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);
667
668 Tcb->MaxKeepAlive = (UINT8)TCP_COMP_VAL (
669 TCP_MAX_KEEPALIVE_MIN,
670 TCP_MAX_KEEPALIVE,
671 TCP_MAX_KEEPALIVE,
672 Option->KeepAliveProbes
673 );
674 Tcb->KeepAliveIdle = TCP_COMP_VAL (
676 TCP_KEEPALIVE_IDLE_MAX,
678 (UINT32)(Option->KeepAliveTime * TCP_TICK_HZ)
679 );
680 Tcb->KeepAlivePeriod = TCP_COMP_VAL (
681 TCP_KEEPALIVE_PERIOD_MIN,
682 TCP_KEEPALIVE_PERIOD,
683 TCP_KEEPALIVE_PERIOD,
684 (UINT32)(Option->KeepAliveInterval * TCP_TICK_HZ)
685 );
686 }
687
688 Tcb->ConnectTimeout = TCP_COMP_VAL (
689 TCP_CONNECT_TIME_MIN,
690 TCP_CONNECT_TIME,
691 TCP_CONNECT_TIME,
692 (UINT32)(Option->ConnectionTimeout * TCP_TICK_HZ)
693 );
694
695 if (!Option->EnableNagle) {
696 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);
697 }
698
699 if (!Option->EnableTimeStamp) {
700 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);
701 }
702
703 if (!Option->EnableWindowScaling) {
704 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);
705 }
706 }
707
708 //
709 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
710 // determined, construct the IP device path and install it.
711 //
712 Status = TcpInstallDevicePath (Sk);
713 if (EFI_ERROR (Status)) {
714 goto OnExit;
715 }
716
717 //
718 // update state of Tcb and socket
719 //
720 if (((Sk->IpVersion == IP_VERSION_4) && !CfgData->Tcp4CfgData.AccessPoint.ActiveFlag) ||
721 ((Sk->IpVersion == IP_VERSION_6) && !CfgData->Tcp6CfgData.AccessPoint.ActiveFlag)
722 )
723 {
724 TcpSetState (Tcb, TCP_LISTEN);
725 SockSetState (Sk, SO_LISTENING);
726
727 Sk->ConfigureState = SO_CONFIGURED_PASSIVE;
728 } else {
729 Sk->ConfigureState = SO_CONFIGURED_ACTIVE;
730 }
731
732 if (Sk->IpVersion == IP_VERSION_6) {
734
735 if (NetIp6IsUnspecifiedAddr (&Tcb->RemoteEnd.Ip.v6)) {
736 Tcb->RemoteIpZero = TRUE;
737 }
738 }
739
740 TcpInsertTcb (Tcb);
741
742OnExit:
743
744 return Status;
745}
746
765 IN SOCKET *Sock,
766 IN UINT8 Request,
767 IN VOID *Data OPTIONAL
768 )
769{
770 TCP_CB *Tcb;
771 TCP_PROTO_DATA *ProtoData;
772
773 ProtoData = (TCP_PROTO_DATA *)Sock->ProtoReserved;
774 Tcb = ProtoData->TcpPcb;
775
776 switch (Request) {
777 case SOCK_POLL:
778 if (Tcb->Sk->IpVersion == IP_VERSION_4) {
779 ProtoData->TcpService->IpIo->Ip.Ip4->Poll (ProtoData->TcpService->IpIo->Ip.Ip4);
780 } else {
781 ProtoData->TcpService->IpIo->Ip.Ip6->Poll (ProtoData->TcpService->IpIo->Ip.Ip6);
782 }
783
784 break;
785
786 case SOCK_CONSUMED:
787 //
788 // After user received data from socket buffer, socket will
789 // notify TCP using this message to give it a chance to send out
790 // window update information
791 //
792 ASSERT (Tcb != NULL);
793 TcpOnAppConsume (Tcb);
794 break;
795
796 case SOCK_SND:
797
798 ASSERT (Tcb != NULL);
799 TcpOnAppSend (Tcb);
800 break;
801
802 case SOCK_CLOSE:
803
804 TcpOnAppClose (Tcb);
805
806 break;
807
808 case SOCK_ABORT:
809
810 TcpOnAppAbort (Tcb);
811
812 break;
813
814 case SOCK_SNDPUSH:
815 Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);
816 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);
817
818 break;
819
820 case SOCK_SNDURG:
821 Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;
822 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);
823
824 break;
825
826 case SOCK_CONNECT:
827
828 TcpOnAppConnect (Tcb);
829
830 break;
831
832 case SOCK_ATTACH:
833
834 return TcpAttachPcb (Sock);
835
836 break;
837
838 case SOCK_FLUSH:
839
840 TcpFlushPcb (Tcb);
841
842 break;
843
844 case SOCK_DETACH:
845
846 TcpDetachPcb (Sock);
847
848 break;
849
850 case SOCK_CONFIGURE:
851
852 return TcpConfigurePcb (
853 Sock,
854 (TCP_CONFIG_DATA *)Data
855 );
856
857 break;
858
859 case SOCK_MODE:
860
861 ASSERT ((Data != NULL) && (Tcb != NULL));
862
863 if (Tcb->Sk->IpVersion == IP_VERSION_4) {
864 return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *)Data);
865 } else {
866 return Tcp6GetMode (Tcb, (TCP6_MODE_DATA *)Data);
867 }
868
869 break;
870
871 case SOCK_ROUTE:
872
873 ASSERT ((Data != NULL) && (Tcb != NULL) && (Tcb->Sk->IpVersion == IP_VERSION_4));
874
875 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *)Data);
876
877 default:
878
879 return EFI_UNSUPPORTED;
880 }
881
882 return EFI_SUCCESS;
883}
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
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI IpIoRemoveIp(IN IP_IO *IpIo, IN IP_IO_IP_INFO *IpInfo)
Definition: DxeIpIoLib.c:1968
EFI_STATUS EFIAPI IpIoConfigIp(IN OUT IP_IO_IP_INFO *IpInfo, IN OUT VOID *IpConfigData OPTIONAL)
Definition: DxeIpIoLib.c:1806
IP_IO_IP_INFO *EFIAPI IpIoAddIp(IN OUT IP_IO *IpIo)
Definition: DxeIpIoLib.c:1700
#define NULL
Definition: Base.h:319
#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
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
Definition: DxeNetLib.c:766
VOID EFIAPI NetbufFreeList(IN OUT LIST_ENTRY *Head)
Definition: NetBuffer.c:319
#define SOCK_CONNECT
Need to connect to a peer.
Definition: Socket.h:89
#define SOCK_CONSUMED
Application has retrieved data from socket.
Definition: Socket.h:88
#define SOCK_IS_CONFIGURED(Sock)
Definition: Socket.h:125
#define SOCK_ATTACH
Attach current socket to a new PCB.
Definition: Socket.h:81
#define SET_RCV_BUFFSIZE(Sock, Size)
Definition: Socket.h:235
#define SOCK_CONFIGURE
Configure attached PCB.
Definition: Socket.h:83
#define SOCK_POLL
Need to poll to the protocol layer.
Definition: Socket.h:92
#define GET_SND_DATASIZE(Sock)
Definition: Socket.h:284
#define SOCK_CLOSE
Need to close the protocol process.
Definition: Socket.h:90
#define GET_BACKLOG(Sock)
Definition: Socket.h:303
#define SOCK_MODE
Need to get the mode data of the protocol.
Definition: Socket.h:94
VOID SockSetState(IN OUT SOCKET *Sock, IN UINT8 State)
Definition: SockImpl.c:920
#define SOCK_SND
Need protocol to send something.
Definition: Socket.h:85
#define SOCK_ABORT
Need to reset the protocol process.
Definition: Socket.h:91
#define SOCK_ROUTE
Need to add a route information.
Definition: Socket.h:93
#define SET_BACKLOG(Sock, Value)
Definition: Socket.h:293
#define GET_RCV_BUFFSIZE(Sock)
Definition: Socket.h:245
#define GET_SND_BUFFSIZE(Sock)
Definition: Socket.h:274
#define SET_SND_BUFFSIZE(Sock, Size)
Definition: Socket.h:264
#define SOCK_SNDURG
Need protocol to send urgent data.
Definition: Socket.h:87
#define SOCK_DETACH
Detach current socket from the PCB.
Definition: Socket.h:82
#define SOCK_FLUSH
Flush attached PCB.
Definition: Socket.h:84
#define SOCK_SNDPUSH
Need protocol to send pushed data.
Definition: Socket.h:86
EFI_TCP4_CONNECTION_STATE
Definition: Tcp4.h:103
EFI_TCP6_CONNECTION_STATE
Definition: Tcp6.h:243
EFI_STATUS TcpBind(IN TCP_ACCESS_POINT *TcpAp, IN UINT8 IpVersion)
EFI_STATUS TcpDispatcher(IN SOCKET *Sock, IN UINT8 Request, IN VOID *Data OPTIONAL)
VOID TcpFlushPcb(IN OUT TCP_CB *Tcb)
EFI_STATUS TcpAttachPcb(IN SOCKET *Sk)
EFI_STATUS Tcp4GetMode(IN TCP_CB *Tcb, IN OUT TCP4_MODE_DATA *Mode)
Definition: TcpDispatcher.c:63
EFI_STATUS TcpConfigurePcb(IN SOCKET *Sk, IN TCP_CONFIG_DATA *CfgData)
EFI_STATUS Tcp6GetMode(IN TCP_CB *Tcb, IN OUT TCP6_MODE_DATA *Mode)
EFI_STATUS Tcp4Route(IN TCP_CB *Tcb, IN TCP4_ROUTE_INFO *RouteInfo)
Definition: TcpDispatcher.c:30
VOID TcpDetachPcb(IN OUT SOCKET *Sk)
INTN TcpOnAppSend(IN OUT TCP_CB *Tcb)
Definition: TcpMisc.c:1012
INTN TcpInsertTcb(IN TCP_CB *Tcb)
Definition: TcpMisc.c:478
VOID TcpOnAppConsume(IN TCP_CB *Tcb)
Definition: TcpMisc.c:1054
EFI_STATUS TcpOnAppConnect(IN OUT TCP_CB *Tcb)
Definition: TcpMisc.c:934
VOID TcpOnAppClose(IN OUT TCP_CB *Tcb)
Definition: TcpMisc.c:961
BOOLEAN TcpFindTcbByPeer(IN EFI_IP_ADDRESS *Addr, IN TCP_PORTNO Port, IN UINT8 Version)
Definition: TcpMisc.c:364
VOID TcpSetState(IN TCP_CB *Tcb, IN UINT8 State)
Definition: TcpMisc.c:801
VOID TcpOnAppAbort(IN TCP_CB *Tcb)
Definition: TcpMisc.c:1098
EFI_STATUS TcpInstallDevicePath(IN SOCKET *Sock)
Definition: TcpMisc.c:1180
UINT16 TcpGetRcvMss(IN SOCKET *Sock)
Definition: TcpMisc.c:737
TCP_SEQNO TcpGetMaxSndNxt(IN TCP_CB *Tcb)
Definition: TcpOutput.c:137
#define TCP6_REFRESH_NEIGHBOR_TICK
Definition: TcpMain.h:45
#define TCP_CTRL_NO_KEEPALIVE
Disable keepalive timer.
Definition: TcpProto.h:59
#define TCP_CTRL_NO_NAGLE
Disable Nagle algorithm.
Definition: TcpProto.h:58
#define TCP_CLOSED
Definition: TcpProto.h:17
#define TCP_CTRL_NO_WS
Disable window scale option.
Definition: TcpProto.h:60
#define TCP_CTRL_SND_PSH
In PUSH send mode.
Definition: TcpProto.h:67
#define TCP_KEEPALIVE_IDLE_MIN
First keepalive.
Definition: TcpProto.h:95
#define TCP_MAX_LOSS
Default max times to retxmit.
Definition: TcpProto.h:94
#define TCP_TICK_HZ
The frequence of TCP tick.
Definition: TcpProto.h:85
#define TCP_CTRL_SND_URG
In urgent send mode.
Definition: TcpProto.h:65
#define TCP_CONGEST_OPEN
TCP is opening its congestion window.
Definition: TcpProto.h:53
#define TCP_CTRL_NO_TS
Disable Timestamp option.
Definition: TcpProto.h:62
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
UINT32 KeepAlivePeriod
Interval for subsequent keep alive probe.
Definition: TcpProto.h:319
UINT32 Tick
1 tick = 200ms
Definition: TcpProto.h:337
TCP_PEER RemoteEnd
Remote endpoint.
Definition: TcpProto.h:238
UINT16 MaxRexmit
The maximum number of retxmit before abort.
Definition: TcpProto.h:322
UINT8 MaxKeepAlive
Maximum keep alive probe times.
Definition: TcpProto.h:320
UINT32 Ssthresh
Slow start threshold.
Definition: TcpProto.h:302
UINT8 CongestState
The current congestion state(RFC3782).
Definition: TcpProto.h:305
UINT32 TimeWaitTimeout
The TIME_WAIT timeout.
Definition: TcpProto.h:324
TCP_SEQNO SndUp
Send urgent point.
Definition: TcpProto.h:258
UINT16 RcvMss
Max receive segment size.
Definition: TcpProto.h:271
UINT32 Rto
Current RTO, not scaled.
Definition: TcpProto.h:295
UINT8 State
TCP state, such as SYN_SENT, LISTEN.
Definition: TcpProto.h:248
TCP_SEQNO SndPsh
Send PUSH point.
Definition: TcpProto.h:257
UINT32 KeepAliveIdle
Idle time before sending first probe.
Definition: TcpProto.h:318
LIST_ENTRY RcvQue
Reassemble queue.
Definition: TcpProto.h:241
UINT16 SndMss
Max send segment size.
Definition: TcpProto.h:263
UINT32 FinWait2Timeout
The FIN_WAIT_2 timeout.
Definition: TcpProto.h:323
UINT32 ConnectTimeout
The connect establishment timeout.
Definition: TcpProto.h:325
UINT32 SRtt
Smoothed RTT, scaled by 8.
Definition: TcpProto.h:293
SOCKET * Sk
The socket it controlled.
Definition: TcpProto.h:236
TCP_PEER LocalEnd
Local endpoint.
Definition: TcpProto.h:237
IP_IO_IP_INFO * IpInfo
Pointer reference to Ip used to send pkt.
Definition: TcpProto.h:336
LIST_ENTRY List
Back and forward link entry.
Definition: TcpProto.h:233
BOOLEAN RemoteIpZero
RemoteEnd.Ip is ZERO when configured.
Definition: TcpProto.h:335
UINT32 CtrlFlag
Control flags, such as NO_NAGLE.
Definition: TcpProto.h:242
UINT32 CWnd
Sender's congestion window.
Definition: TcpProto.h:301
LIST_ENTRY SndQue
Retxmission queue.
Definition: TcpProto.h:240
EFI_IP_ADDRESS Ip
IP address, in network byte order.
Definition: TcpProto.h:223
TCP_PORTNO Port
Port number, in network byte order.
Definition: TcpProto.h:224
EFI_HANDLE SockHandle
The virtual handle of the socket.
Definition: Socket.h:461
UINT8 TypeOfService
Definition: Ip4.h:102
UINT32 ReceiveTimeout
Definition: Ip4.h:121
EFI_IPv4_ADDRESS SubnetMask
Definition: Ip4.h:98
UINT8 TimeToLive
Definition: Ip4.h:106
UINT8 DefaultProtocol
Definition: Ip4.h:63
EFI_IPv4_ADDRESS StationAddress
Definition: Ip4.h:94
BOOLEAN UseDefaultAddress
Definition: Ip4.h:90
UINT8 TrafficClass
Definition: Ip6.h:193
UINT32 ReceiveTimeout
Definition: Ip6.h:208
UINT8 DefaultProtocol
Definition: Ip6.h:144
UINT8 HopLimit
Definition: Ip6.h:197
EFI_IPv6_ADDRESS DestinationAddress
Definition: Ip6.h:168
EFI_IPv6_ADDRESS StationAddress
Definition: Ip6.h:188
UINT16 RemotePort
Definition: Tcp6.h:114
BOOLEAN ActiveFlag
Definition: Tcp6.h:119
EFI_IPv6_ADDRESS RemoteAddress
Definition: Tcp6.h:105
UINT16 StationPort
Definition: Tcp6.h:93
EFI_IPv6_ADDRESS StationAddress
Definition: Tcp6.h:87
EFI_TCP6_ACCESS_POINT AccessPoint
Definition: Tcp6.h:232
UINT8 TrafficClass
Definition: Tcp6.h:224
EFI_TCP6_OPTION * ControlOption
Definition: Tcp6.h:237
UINT32 KeepAliveTime
Definition: Tcp6.h:180
UINT32 KeepAliveInterval
Definition: Tcp6.h:187
UINT32 KeepAliveProbes
Definition: Tcp6.h:173
UINT32 SendBufferSize
Definition: Tcp6.h:133
UINT32 DataRetries
Definition: Tcp6.h:150
BOOLEAN EnableWindowScaling
Definition: Tcp6.h:202
UINT32 TimeWaitTimeout
Definition: Tcp6.h:167
UINT32 ReceiveBufferSize
Definition: Tcp6.h:129
UINT32 MaxSynBackLog
Definition: Tcp6.h:138
BOOLEAN EnablePathMtuDiscovery
Definition: Tcp6.h:214
BOOLEAN EnableTimeStamp
Definition: Tcp6.h:197
BOOLEAN EnableSelectiveAck
Definition: Tcp6.h:209
UINT32 FinTimeout
Definition: Tcp6.h:160
UINT32 ConnectionTimeout
Definition: Tcp6.h:144
BOOLEAN EnableNagle
Definition: Tcp6.h:192
Definition: Base.h:213