2 The implementation of a dispatch routine for processing TCP requests.
4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Add or remove a route entry in the IP route table associated with this TCP instance.
21 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
22 @param[in] RouteInfo Pointer to the route information to be processed.
24 @retval EFI_SUCCESS The operation completed successfully.
25 @retval EFI_NOT_STARTED The driver instance has not been started.
26 @retval EFI_NO_MAPPING When using the default address, configuration(DHCP,
27 BOOTP, RARP, etc.) is not finished yet.
28 @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
29 @retval EFI_NOT_FOUND This route is not in the routing table
30 (when RouteInfo->DeleteRoute is TRUE).
31 @retval EFI_ACCESS_DENIED The route is already defined in the routing table
32 (when RouteInfo->DeleteRoute is FALSE).
37 IN TCP4_ROUTE_INFO
*RouteInfo
44 ASSERT (Ip
.Ip4
!= NULL
);
46 return Ip
.Ip4
->Routes (
48 RouteInfo
->DeleteRoute
,
49 RouteInfo
->SubnetAddress
,
50 RouteInfo
->SubnetMask
,
51 RouteInfo
->GatewayAddress
57 Get the operational settings of this TCPv4 instance.
59 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
60 @param[in, out] Mode Pointer to the buffer to store the operational
63 @retval EFI_SUCCESS The mode data was read.
64 @retval EFI_NOT_STARTED No configuration data is available because this
65 instance hasn't been started.
71 IN OUT TCP4_MODE_DATA
*Mode
75 EFI_TCP4_CONFIG_DATA
*ConfigData
;
76 EFI_TCP4_ACCESS_POINT
*AccessPoint
;
77 EFI_TCP4_OPTION
*Option
;
82 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp4ConfigData
!= NULL
)) {
83 return EFI_NOT_STARTED
;
86 if (Mode
->Tcp4State
!= NULL
) {
87 *(Mode
->Tcp4State
) = (EFI_TCP4_CONNECTION_STATE
) Tcb
->State
;
90 if (Mode
->Tcp4ConfigData
!= NULL
) {
92 ConfigData
= Mode
->Tcp4ConfigData
;
93 AccessPoint
= &(ConfigData
->AccessPoint
);
94 Option
= ConfigData
->ControlOption
;
96 ConfigData
->TypeOfService
= Tcb
->Tos
;
97 ConfigData
->TimeToLive
= Tcb
->Ttl
;
99 AccessPoint
->UseDefaultAddress
= Tcb
->UseDefaultAddr
;
101 CopyMem (&AccessPoint
->StationAddress
, &Tcb
->LocalEnd
.Ip
, sizeof (EFI_IPv4_ADDRESS
));
103 AccessPoint
->SubnetMask
= Tcb
->SubnetMask
;
104 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
106 CopyMem (&AccessPoint
->RemoteAddress
, &Tcb
->RemoteEnd
.Ip
, sizeof (EFI_IPv4_ADDRESS
));
108 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
109 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
111 if (Option
!= NULL
) {
112 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
113 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
114 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
116 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
117 Option
->DataRetries
= Tcb
->MaxRexmit
;
118 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
119 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
120 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
121 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
122 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
124 Option
->EnableNagle
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
));
125 Option
->EnableTimeStamp
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
));
126 Option
->EnableWindowScaling
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
));
128 Option
->EnableSelectiveAck
= FALSE
;
129 Option
->EnablePathMtuDiscovery
= FALSE
;
133 Ip
= Tcb
->IpInfo
->Ip
.Ip4
;
136 return Ip
->GetModeData (Ip
, Mode
->Ip4ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
140 Get the operational settings of this TCPv6 instance.
142 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
143 @param[in, out] Mode Pointer to the buffer to store the operational
146 @retval EFI_SUCCESS The mode data was read.
147 @retval EFI_NOT_STARTED No configuration data is available because this
148 instance hasn't been started.
154 IN OUT TCP6_MODE_DATA
*Mode
158 EFI_TCP6_CONFIG_DATA
*ConfigData
;
159 EFI_TCP6_ACCESS_POINT
*AccessPoint
;
160 EFI_TCP6_OPTION
*Option
;
161 EFI_IP6_PROTOCOL
*Ip
;
165 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp6ConfigData
!= NULL
)) {
166 return EFI_NOT_STARTED
;
169 if (Mode
->Tcp6State
!= NULL
) {
170 *(Mode
->Tcp6State
) = (EFI_TCP6_CONNECTION_STATE
) (Tcb
->State
);
173 if (Mode
->Tcp6ConfigData
!= NULL
) {
175 ConfigData
= Mode
->Tcp6ConfigData
;
176 AccessPoint
= &(ConfigData
->AccessPoint
);
177 Option
= ConfigData
->ControlOption
;
179 ConfigData
->TrafficClass
= Tcb
->Tos
;
180 ConfigData
->HopLimit
= Tcb
->Ttl
;
182 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
183 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
184 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
186 IP6_COPY_ADDRESS (&AccessPoint
->StationAddress
, &Tcb
->LocalEnd
.Ip
);
187 IP6_COPY_ADDRESS (&AccessPoint
->RemoteAddress
, &Tcb
->RemoteEnd
.Ip
);
189 if (Option
!= NULL
) {
190 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
191 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
192 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
194 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
195 Option
->DataRetries
= Tcb
->MaxRexmit
;
196 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
197 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
198 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
199 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
200 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
202 Option
->EnableNagle
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
));
203 Option
->EnableTimeStamp
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
));
204 Option
->EnableWindowScaling
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
));
206 Option
->EnableSelectiveAck
= FALSE
;
207 Option
->EnablePathMtuDiscovery
= FALSE
;
211 Ip
= Tcb
->IpInfo
->Ip
.Ip6
;
214 return Ip
->GetModeData (Ip
, Mode
->Ip6ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
218 If TcpAp->StationPort isn't zero, check whether the access point
219 is registered, else generate a random station port for this
222 @param[in] TcpAp Pointer to the access point.
223 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
225 @retval EFI_SUCCESS The check passed or the port is assigned.
226 @retval EFI_INVALID_PARAMETER The non-zero station port is already used.
227 @retval EFI_OUT_OF_RESOURCES No port can be allocated.
232 IN TCP_ACCESS_POINT
*TcpAp
,
237 EFI_IP_ADDRESS Local
;
241 if (IpVersion
== IP_VERSION_4
) {
242 CopyMem (&Local
, &TcpAp
->Tcp4Ap
.StationAddress
, sizeof (EFI_IPv4_ADDRESS
));
243 Port
= &TcpAp
->Tcp4Ap
.StationPort
;
244 RandomPort
= &mTcp4RandomPort
;
246 IP6_COPY_ADDRESS (&Local
, &TcpAp
->Tcp6Ap
.StationAddress
);
247 Port
= &TcpAp
->Tcp6Ap
.StationPort
;
248 RandomPort
= &mTcp6RandomPort
;
253 // Check if a same endpoing is bound.
255 if (TcpFindTcbByPeer (&Local
, *Port
, IpVersion
)) {
257 return EFI_INVALID_PARAMETER
;
261 // generate a random port
265 if (TCP_PORT_USER_RESERVED
== *RandomPort
) {
266 *RandomPort
= TCP_PORT_KNOWN
;
271 while (TcpFindTcbByPeer (&Local
, *RandomPort
, IpVersion
)) {
274 if (*RandomPort
<= TCP_PORT_KNOWN
) {
278 "TcpBind: no port can be allocated for this pcb\n")
280 return EFI_OUT_OF_RESOURCES
;
283 *RandomPort
= TCP_PORT_KNOWN
+ 1;
296 Flush the Tcb add its associated protocols.
298 @param[in, out] Tcb Pointer to the TCP_CB to be flushed.
308 IpIoConfigIp (Tcb
->IpInfo
, NULL
);
312 if (SOCK_IS_CONFIGURED (Sock
)) {
313 RemoveEntryList (&Tcb
->List
);
315 if (Sock
->DevicePath
!= NULL
) {
317 // Uninstall the device path protocl.
319 gBS
->UninstallProtocolInterface (
321 &gEfiDevicePathProtocolGuid
,
325 FreePool (Sock
->DevicePath
);
326 Sock
->DevicePath
= NULL
;
330 NetbufFreeList (&Tcb
->SndQue
);
331 NetbufFreeList (&Tcb
->RcvQue
);
332 Tcb
->State
= TCP_CLOSED
;
333 Tcb
->RemoteIpZero
= FALSE
;
337 Attach a Pcb to the socket.
339 @param[in] Sk Pointer to the socket of this TCP instance.
341 @retval EFI_SUCCESS The operation completed successfully.
342 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
351 TCP_PROTO_DATA
*ProtoData
;
355 EFI_GUID
*IpProtocolGuid
;
357 if (Sk
->IpVersion
== IP_VERSION_4
) {
358 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
360 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
363 Tcb
= AllocateZeroPool (sizeof (TCP_CB
));
367 DEBUG ((EFI_D_ERROR
, "TcpConfigurePcb: failed to allocate a TCB\n"));
369 return EFI_OUT_OF_RESOURCES
;
372 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
373 IpIo
= ProtoData
->TcpService
->IpIo
;
376 // Create an IpInfo for this Tcb.
378 Tcb
->IpInfo
= IpIoAddIp (IpIo
);
379 if (Tcb
->IpInfo
== NULL
) {
382 return EFI_OUT_OF_RESOURCES
;
386 // Open the new created IP instance BY_CHILD.
388 Status
= gBS
->OpenProtocol (
389 Tcb
->IpInfo
->ChildHandle
,
394 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
396 if (EFI_ERROR (Status
)) {
397 IpIoRemoveIp (IpIo
, Tcb
->IpInfo
);
401 InitializeListHead (&Tcb
->List
);
402 InitializeListHead (&Tcb
->SndQue
);
403 InitializeListHead (&Tcb
->RcvQue
);
405 Tcb
->State
= TCP_CLOSED
;
407 ProtoData
->TcpPcb
= Tcb
;
413 Detach the Pcb of the socket.
415 @param[in, out] Sk Pointer to the socket of this TCP instance.
423 TCP_PROTO_DATA
*ProtoData
;
425 EFI_GUID
*IpProtocolGuid
;
427 if (Sk
->IpVersion
== IP_VERSION_4
) {
428 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
430 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
433 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
434 Tcb
= ProtoData
->TcpPcb
;
436 ASSERT (Tcb
!= NULL
);
441 // Close the IP protocol.
444 Tcb
->IpInfo
->ChildHandle
,
446 ProtoData
->TcpService
->IpIo
->Image
,
450 IpIoRemoveIp (ProtoData
->TcpService
->IpIo
, Tcb
->IpInfo
);
454 ProtoData
->TcpPcb
= NULL
;
458 Configure the Pcb using CfgData.
460 @param[in] Sk Pointer to the socket of this TCP instance.
461 @param[in] CfgData Pointer to the TCP configuration data.
463 @retval EFI_SUCCESS The operation completed successfully.
464 @retval EFI_INVALID_PARAMETER A same access point has been configured in
465 another TCP instance.
466 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
472 IN TCP_CONFIG_DATA
*CfgData
475 IP_IO_IP_CONFIG_DATA IpCfgData
;
477 EFI_TCP4_OPTION
*Option
;
478 TCP_PROTO_DATA
*TcpProto
;
480 TCP_ACCESS_POINT
*TcpAp
;
482 ASSERT ((CfgData
!= NULL
) && (Sk
!= NULL
) && (Sk
->SockHandle
!= NULL
));
484 TcpProto
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
485 Tcb
= TcpProto
->TcpPcb
;
487 ASSERT (Tcb
!= NULL
);
489 if (Sk
->IpVersion
== IP_VERSION_4
) {
491 // Add Ip for send pkt to the peer
493 CopyMem (&IpCfgData
.Ip4CfgData
, &mIp4IoDefaultIpConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
494 IpCfgData
.Ip4CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
495 IpCfgData
.Ip4CfgData
.TypeOfService
= CfgData
->Tcp4CfgData
.TypeOfService
;
496 IpCfgData
.Ip4CfgData
.TimeToLive
= CfgData
->Tcp4CfgData
.TimeToLive
;
497 IpCfgData
.Ip4CfgData
.UseDefaultAddress
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
498 IpCfgData
.Ip4CfgData
.SubnetMask
= CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
;
499 IpCfgData
.Ip4CfgData
.ReceiveTimeout
= (UINT32
) (-1);
501 &IpCfgData
.Ip4CfgData
.StationAddress
,
502 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
,
503 sizeof (EFI_IPv4_ADDRESS
)
507 ASSERT (Sk
->IpVersion
== IP_VERSION_6
);
509 CopyMem (&IpCfgData
.Ip6CfgData
, &mIp6IoDefaultIpConfigData
, sizeof (EFI_IP6_CONFIG_DATA
));
510 IpCfgData
.Ip6CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
511 IpCfgData
.Ip6CfgData
.TrafficClass
= CfgData
->Tcp6CfgData
.TrafficClass
;
512 IpCfgData
.Ip6CfgData
.HopLimit
= CfgData
->Tcp6CfgData
.HopLimit
;
513 IpCfgData
.Ip6CfgData
.ReceiveTimeout
= (UINT32
) (-1);
515 &IpCfgData
.Ip6CfgData
.StationAddress
,
516 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
519 &IpCfgData
.Ip6CfgData
.DestinationAddress
,
520 &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
525 // Configure the IP instance this Tcb consumes.
527 Status
= IpIoConfigIp (Tcb
->IpInfo
, &IpCfgData
);
528 if (EFI_ERROR (Status
)) {
532 if (Sk
->IpVersion
== IP_VERSION_4
) {
534 // Get the default address information if the instance is configured to use default address.
536 CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
= IpCfgData
.Ip4CfgData
.StationAddress
;
537 CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
= IpCfgData
.Ip4CfgData
.SubnetMask
;
539 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp4CfgData
.AccessPoint
;
542 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
,
543 &IpCfgData
.Ip6CfgData
.StationAddress
546 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp6CfgData
.AccessPoint
;
550 // check if we can bind this endpoint in CfgData
552 Status
= TcpBind (TcpAp
, Sk
->IpVersion
);
554 if (EFI_ERROR (Status
)) {
557 "TcpConfigurePcb: Bind endpoint failed with %r\n",
565 // Initalize the operating information in this Tcb
567 ASSERT (Tcb
->State
== TCP_CLOSED
&&
568 IsListEmpty (&Tcb
->SndQue
) &&
569 IsListEmpty (&Tcb
->RcvQue
));
571 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
572 Tcb
->State
= TCP_CLOSED
;
575 Tcb
->RcvMss
= TcpGetRcvMss (Sk
);
578 Tcb
->Rto
= 3 * TCP_TICK_HZ
;
580 Tcb
->CWnd
= Tcb
->SndMss
;
581 Tcb
->Ssthresh
= 0xffffffff;
583 Tcb
->CongestState
= TCP_CONGEST_OPEN
;
585 Tcb
->KeepAliveIdle
= TCP_KEEPALIVE_IDLE_MIN
;
586 Tcb
->KeepAlivePeriod
= TCP_KEEPALIVE_PERIOD
;
587 Tcb
->MaxKeepAlive
= TCP_MAX_KEEPALIVE
;
588 Tcb
->MaxRexmit
= TCP_MAX_LOSS
;
589 Tcb
->FinWait2Timeout
= TCP_FIN_WAIT2_TIME
;
590 Tcb
->TimeWaitTimeout
= TCP_TIME_WAIT_TIME
;
591 Tcb
->ConnectTimeout
= TCP_CONNECT_TIME
;
593 if (Sk
->IpVersion
== IP_VERSION_4
) {
595 // initialize Tcb in the light of CfgData
597 Tcb
->Ttl
= CfgData
->Tcp4CfgData
.TimeToLive
;
598 Tcb
->Tos
= CfgData
->Tcp4CfgData
.TypeOfService
;
600 Tcb
->UseDefaultAddr
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
602 CopyMem (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
, sizeof (IP4_ADDR
));
603 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.StationPort
);
604 Tcb
->SubnetMask
= CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
;
606 CopyMem (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.RemoteAddress
, sizeof (IP4_ADDR
));
607 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.RemotePort
);
609 Option
= CfgData
->Tcp4CfgData
.ControlOption
;
611 Tcb
->Ttl
= CfgData
->Tcp6CfgData
.HopLimit
;
612 Tcb
->Tos
= CfgData
->Tcp6CfgData
.TrafficClass
;
614 IP6_COPY_ADDRESS (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
);
615 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.StationPort
);
617 IP6_COPY_ADDRESS (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
);
618 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.RemotePort
);
621 // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
623 Option
= (EFI_TCP4_OPTION
*) CfgData
->Tcp6CfgData
.ControlOption
;
626 if (Option
!= NULL
) {
629 (UINT32
) (TCP_COMP_VAL (
630 TCP_RCV_BUF_SIZE_MIN
,
633 Option
->ReceiveBufferSize
639 (UINT32
) (TCP_COMP_VAL (
640 TCP_SND_BUF_SIZE_MIN
,
643 Option
->SendBufferSize
650 (UINT32
) (TCP_COMP_VAL (
654 Option
->MaxSynBackLog
659 Tcb
->MaxRexmit
= (UINT16
) TCP_COMP_VAL (
665 Tcb
->FinWait2Timeout
= TCP_COMP_VAL (
667 TCP_FIN_WAIT2_TIME_MAX
,
669 (UINT32
) (Option
->FinTimeout
* TCP_TICK_HZ
)
672 if (Option
->TimeWaitTimeout
!= 0) {
673 Tcb
->TimeWaitTimeout
= TCP_COMP_VAL (
675 TCP_TIME_WAIT_TIME_MAX
,
677 (UINT32
) (Option
->TimeWaitTimeout
* TCP_TICK_HZ
)
680 Tcb
->TimeWaitTimeout
= 0;
683 if (Option
->KeepAliveProbes
!= 0) {
684 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
686 Tcb
->MaxKeepAlive
= (UINT8
) TCP_COMP_VAL (
687 TCP_MAX_KEEPALIVE_MIN
,
690 Option
->KeepAliveProbes
692 Tcb
->KeepAliveIdle
= TCP_COMP_VAL (
693 TCP_KEEPALIVE_IDLE_MIN
,
694 TCP_KEEPALIVE_IDLE_MAX
,
695 TCP_KEEPALIVE_IDLE_MIN
,
696 (UINT32
) (Option
->KeepAliveTime
* TCP_TICK_HZ
)
698 Tcb
->KeepAlivePeriod
= TCP_COMP_VAL (
699 TCP_KEEPALIVE_PERIOD_MIN
,
700 TCP_KEEPALIVE_PERIOD
,
701 TCP_KEEPALIVE_PERIOD
,
702 (UINT32
) (Option
->KeepAliveInterval
* TCP_TICK_HZ
)
706 Tcb
->ConnectTimeout
= TCP_COMP_VAL (
707 TCP_CONNECT_TIME_MIN
,
710 (UINT32
) (Option
->ConnectionTimeout
* TCP_TICK_HZ
)
713 if (!Option
->EnableNagle
) {
714 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
717 if (!Option
->EnableTimeStamp
) {
718 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
721 if (!Option
->EnableWindowScaling
) {
722 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
727 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
728 // determined, construct the IP device path and install it.
730 Status
= TcpInstallDevicePath (Sk
);
731 if (EFI_ERROR (Status
)) {
736 // update state of Tcb and socket
738 if (((Sk
->IpVersion
== IP_VERSION_4
) && !CfgData
->Tcp4CfgData
.AccessPoint
.ActiveFlag
) ||
739 ((Sk
->IpVersion
== IP_VERSION_6
) && !CfgData
->Tcp6CfgData
.AccessPoint
.ActiveFlag
)
742 TcpSetState (Tcb
, TCP_LISTEN
);
743 SockSetState (Sk
, SO_LISTENING
);
745 Sk
->ConfigureState
= SO_CONFIGURED_PASSIVE
;
748 Sk
->ConfigureState
= SO_CONFIGURED_ACTIVE
;
751 if (Sk
->IpVersion
== IP_VERSION_6
) {
752 Tcb
->Tick
= TCP6_REFRESH_NEIGHBOR_TICK
;
754 if (NetIp6IsUnspecifiedAddr (&Tcb
->RemoteEnd
.Ip
.v6
)) {
755 Tcb
->RemoteIpZero
= TRUE
;
767 The procotol handler provided to the socket layer, which is used to
768 dispatch the socket level requests by calling the corresponding
771 @param[in] Sock Pointer to the socket of this TCP instance.
772 @param[in] Request The code of this operation request.
773 @param[in] Data Pointer to the operation specific data passed in
774 together with the operation request. This is an
775 optional parameter that may be NULL.
777 @retval EFI_SUCCESS The socket request completed successfully.
778 @retval other The error status returned by the corresponding TCP
786 IN VOID
*Data OPTIONAL
790 TCP_PROTO_DATA
*ProtoData
;
792 ProtoData
= (TCP_PROTO_DATA
*) Sock
->ProtoReserved
;
793 Tcb
= ProtoData
->TcpPcb
;
797 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
798 ProtoData
->TcpService
->IpIo
->Ip
.Ip4
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip4
);
800 ProtoData
->TcpService
->IpIo
->Ip
.Ip6
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip6
);
807 // After user received data from socket buffer, socket will
808 // notify TCP using this message to give it a chance to send out
809 // window update information
811 ASSERT (Tcb
!= NULL
);
812 TcpOnAppConsume (Tcb
);
817 ASSERT (Tcb
!= NULL
);
834 Tcb
->SndPsh
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
);
835 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_PSH
);
840 Tcb
->SndUp
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
) - 1;
841 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_URG
);
847 TcpOnAppConnect (Tcb
);
853 return TcpAttachPcb (Sock
);
871 return TcpConfigurePcb (
873 (TCP_CONFIG_DATA
*) Data
880 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
));
882 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
884 return Tcp4GetMode (Tcb
, (TCP4_MODE_DATA
*) Data
);
887 return Tcp6GetMode (Tcb
, (TCP6_MODE_DATA
*) Data
);
894 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
) && (Tcb
->Sk
->IpVersion
== IP_VERSION_4
));
896 return Tcp4Route (Tcb
, (TCP4_ROUTE_INFO
*) Data
);
900 return EFI_UNSUPPORTED
;