2 The implementation of a dispatch routine for processing TCP requests.
4 (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>
5 Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php.
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 Add or remove a route entry in the IP route table associated with this TCP instance.
22 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
23 @param[in] RouteInfo Pointer to the route information to be processed.
25 @retval EFI_SUCCESS The operation completed successfully.
26 @retval EFI_NOT_STARTED The driver instance has not been started.
27 @retval EFI_NO_MAPPING When using the default address, configuration(DHCP,
28 BOOTP, RARP, etc.) is not finished yet.
29 @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
30 @retval EFI_NOT_FOUND This route is not in the routing table
31 (when RouteInfo->DeleteRoute is TRUE).
32 @retval EFI_ACCESS_DENIED The route is already defined in the routing table
33 (when RouteInfo->DeleteRoute is FALSE).
38 IN TCP4_ROUTE_INFO
*RouteInfo
45 ASSERT (Ip
.Ip4
!= NULL
);
47 return Ip
.Ip4
->Routes (
49 RouteInfo
->DeleteRoute
,
50 RouteInfo
->SubnetAddress
,
51 RouteInfo
->SubnetMask
,
52 RouteInfo
->GatewayAddress
58 Get the operational settings of this TCPv4 instance.
60 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
61 @param[in, out] Mode Pointer to the buffer to store the operational
64 @retval EFI_SUCCESS The mode data was read.
65 @retval EFI_NOT_STARTED No configuration data is available because this
66 instance hasn't been started.
72 IN OUT TCP4_MODE_DATA
*Mode
76 EFI_TCP4_CONFIG_DATA
*ConfigData
;
77 EFI_TCP4_ACCESS_POINT
*AccessPoint
;
78 EFI_TCP4_OPTION
*Option
;
83 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp4ConfigData
!= NULL
)) {
84 return EFI_NOT_STARTED
;
87 if (Mode
->Tcp4State
!= NULL
) {
88 *(Mode
->Tcp4State
) = (EFI_TCP4_CONNECTION_STATE
) Tcb
->State
;
91 if (Mode
->Tcp4ConfigData
!= NULL
) {
93 ConfigData
= Mode
->Tcp4ConfigData
;
94 AccessPoint
= &(ConfigData
->AccessPoint
);
95 Option
= ConfigData
->ControlOption
;
97 ConfigData
->TypeOfService
= Tcb
->Tos
;
98 ConfigData
->TimeToLive
= Tcb
->Ttl
;
100 AccessPoint
->UseDefaultAddress
= Tcb
->UseDefaultAddr
;
102 IP4_COPY_ADDRESS (&AccessPoint
->StationAddress
, &Tcb
->LocalEnd
.Ip
);
104 IP4_COPY_ADDRESS (&AccessPoint
->SubnetMask
, &Tcb
->SubnetMask
);
105 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
107 IP4_COPY_ADDRESS (&AccessPoint
->RemoteAddress
, &Tcb
->RemoteEnd
.Ip
);
109 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
110 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
112 if (Option
!= NULL
) {
113 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
114 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
115 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
117 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
118 Option
->DataRetries
= Tcb
->MaxRexmit
;
119 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
120 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
121 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
122 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
123 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
125 Option
->EnableNagle
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
));
126 Option
->EnableTimeStamp
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
));
127 Option
->EnableWindowScaling
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
));
129 Option
->EnableSelectiveAck
= FALSE
;
130 Option
->EnablePathMtuDiscovery
= FALSE
;
134 Ip
= Tcb
->IpInfo
->Ip
.Ip4
;
137 return Ip
->GetModeData (Ip
, Mode
->Ip4ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
141 Get the operational settings of this TCPv6 instance.
143 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
144 @param[in, out] Mode Pointer to the buffer to store the operational
147 @retval EFI_SUCCESS The mode data was read.
148 @retval EFI_NOT_STARTED No configuration data is available because this
149 instance hasn't been started.
155 IN OUT TCP6_MODE_DATA
*Mode
159 EFI_TCP6_CONFIG_DATA
*ConfigData
;
160 EFI_TCP6_ACCESS_POINT
*AccessPoint
;
161 EFI_TCP6_OPTION
*Option
;
162 EFI_IP6_PROTOCOL
*Ip
;
166 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp6ConfigData
!= NULL
)) {
167 return EFI_NOT_STARTED
;
170 if (Mode
->Tcp6State
!= NULL
) {
171 *(Mode
->Tcp6State
) = (EFI_TCP6_CONNECTION_STATE
) (Tcb
->State
);
174 if (Mode
->Tcp6ConfigData
!= NULL
) {
176 ConfigData
= Mode
->Tcp6ConfigData
;
177 AccessPoint
= &(ConfigData
->AccessPoint
);
178 Option
= ConfigData
->ControlOption
;
180 ConfigData
->TrafficClass
= Tcb
->Tos
;
181 ConfigData
->HopLimit
= Tcb
->Ttl
;
183 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
184 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
185 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
187 IP6_COPY_ADDRESS (&AccessPoint
->StationAddress
, &Tcb
->LocalEnd
.Ip
);
188 IP6_COPY_ADDRESS (&AccessPoint
->RemoteAddress
, &Tcb
->RemoteEnd
.Ip
);
190 if (Option
!= NULL
) {
191 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
192 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
193 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
195 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
196 Option
->DataRetries
= Tcb
->MaxRexmit
;
197 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
198 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
199 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
200 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
201 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
203 Option
->EnableNagle
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
));
204 Option
->EnableTimeStamp
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
));
205 Option
->EnableWindowScaling
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
));
207 Option
->EnableSelectiveAck
= FALSE
;
208 Option
->EnablePathMtuDiscovery
= FALSE
;
212 Ip
= Tcb
->IpInfo
->Ip
.Ip6
;
215 return Ip
->GetModeData (Ip
, Mode
->Ip6ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
219 If TcpAp->StationPort isn't zero, check whether the access point
220 is registered, else generate a random station port for this
223 @param[in] TcpAp Pointer to the access point.
224 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
226 @retval EFI_SUCCESS The check passed or the port is assigned.
227 @retval EFI_INVALID_PARAMETER The non-zero station port is already used.
228 @retval EFI_OUT_OF_RESOURCES No port can be allocated.
233 IN TCP_ACCESS_POINT
*TcpAp
,
238 EFI_IP_ADDRESS Local
;
242 if (IpVersion
== IP_VERSION_4
) {
243 IP4_COPY_ADDRESS (&Local
, &TcpAp
->Tcp4Ap
.StationAddress
);
244 Port
= &TcpAp
->Tcp4Ap
.StationPort
;
245 RandomPort
= &mTcp4RandomPort
;
247 IP6_COPY_ADDRESS (&Local
, &TcpAp
->Tcp6Ap
.StationAddress
);
248 Port
= &TcpAp
->Tcp6Ap
.StationPort
;
249 RandomPort
= &mTcp6RandomPort
;
254 // Check if a same endpoing is bound.
256 if (TcpFindTcbByPeer (&Local
, *Port
, IpVersion
)) {
258 return EFI_INVALID_PARAMETER
;
262 // generate a random port
266 if (TCP_PORT_USER_RESERVED
== *RandomPort
) {
267 *RandomPort
= TCP_PORT_KNOWN
;
272 while (TcpFindTcbByPeer (&Local
, *RandomPort
, IpVersion
)) {
275 if (*RandomPort
<= TCP_PORT_KNOWN
) {
279 "TcpBind: no port can be allocated for this pcb\n")
281 return EFI_OUT_OF_RESOURCES
;
284 *RandomPort
= TCP_PORT_KNOWN
+ 1;
297 Flush the Tcb add its associated protocols.
299 @param[in, out] Tcb Pointer to the TCP_CB to be flushed.
309 IpIoConfigIp (Tcb
->IpInfo
, NULL
);
313 if (SOCK_IS_CONFIGURED (Sock
)) {
314 RemoveEntryList (&Tcb
->List
);
316 if (Sock
->DevicePath
!= NULL
) {
318 // Uninstall the device path protocl.
320 gBS
->UninstallProtocolInterface (
322 &gEfiDevicePathProtocolGuid
,
326 FreePool (Sock
->DevicePath
);
327 Sock
->DevicePath
= NULL
;
331 NetbufFreeList (&Tcb
->SndQue
);
332 NetbufFreeList (&Tcb
->RcvQue
);
333 Tcb
->State
= TCP_CLOSED
;
334 Tcb
->RemoteIpZero
= FALSE
;
338 Attach a Pcb to the socket.
340 @param[in] Sk Pointer to the socket of this TCP instance.
342 @retval EFI_SUCCESS The operation completed successfully.
343 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
352 TCP_PROTO_DATA
*ProtoData
;
356 EFI_GUID
*IpProtocolGuid
;
358 if (Sk
->IpVersion
== IP_VERSION_4
) {
359 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
361 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
364 Tcb
= AllocateZeroPool (sizeof (TCP_CB
));
368 DEBUG ((EFI_D_ERROR
, "TcpConfigurePcb: failed to allocate a TCB\n"));
370 return EFI_OUT_OF_RESOURCES
;
373 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
374 IpIo
= ProtoData
->TcpService
->IpIo
;
377 // Create an IpInfo for this Tcb.
379 Tcb
->IpInfo
= IpIoAddIp (IpIo
);
380 if (Tcb
->IpInfo
== NULL
) {
383 return EFI_OUT_OF_RESOURCES
;
387 // Open the new created IP instance BY_CHILD.
389 Status
= gBS
->OpenProtocol (
390 Tcb
->IpInfo
->ChildHandle
,
395 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
397 if (EFI_ERROR (Status
)) {
398 IpIoRemoveIp (IpIo
, Tcb
->IpInfo
);
402 InitializeListHead (&Tcb
->List
);
403 InitializeListHead (&Tcb
->SndQue
);
404 InitializeListHead (&Tcb
->RcvQue
);
406 Tcb
->State
= TCP_CLOSED
;
408 ProtoData
->TcpPcb
= Tcb
;
414 Detach the Pcb of the socket.
416 @param[in, out] Sk Pointer to the socket of this TCP instance.
424 TCP_PROTO_DATA
*ProtoData
;
427 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
428 Tcb
= ProtoData
->TcpPcb
;
430 ASSERT (Tcb
!= NULL
);
434 IpIoRemoveIp (ProtoData
->TcpService
->IpIo
, Tcb
->IpInfo
);
438 ProtoData
->TcpPcb
= NULL
;
442 Configure the Pcb using CfgData.
444 @param[in] Sk Pointer to the socket of this TCP instance.
445 @param[in] CfgData Pointer to the TCP configuration data.
447 @retval EFI_SUCCESS The operation completed successfully.
448 @retval EFI_INVALID_PARAMETER A same access point has been configured in
449 another TCP instance.
450 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
456 IN TCP_CONFIG_DATA
*CfgData
459 IP_IO_IP_CONFIG_DATA IpCfgData
;
461 EFI_TCP4_OPTION
*Option
;
462 TCP_PROTO_DATA
*TcpProto
;
464 TCP_ACCESS_POINT
*TcpAp
;
466 ASSERT ((CfgData
!= NULL
) && (Sk
!= NULL
) && (Sk
->SockHandle
!= NULL
));
468 TcpProto
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
469 Tcb
= TcpProto
->TcpPcb
;
471 ASSERT (Tcb
!= NULL
);
473 if (Sk
->IpVersion
== IP_VERSION_4
) {
475 // Add Ip for send pkt to the peer
477 CopyMem (&IpCfgData
.Ip4CfgData
, &mIp4IoDefaultIpConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
478 IpCfgData
.Ip4CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
479 IpCfgData
.Ip4CfgData
.TypeOfService
= CfgData
->Tcp4CfgData
.TypeOfService
;
480 IpCfgData
.Ip4CfgData
.TimeToLive
= CfgData
->Tcp4CfgData
.TimeToLive
;
481 IpCfgData
.Ip4CfgData
.UseDefaultAddress
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
483 &IpCfgData
.Ip4CfgData
.SubnetMask
,
484 &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
486 IpCfgData
.Ip4CfgData
.ReceiveTimeout
= (UINT32
) (-1);
488 &IpCfgData
.Ip4CfgData
.StationAddress
,
489 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
493 ASSERT (Sk
->IpVersion
== IP_VERSION_6
);
495 CopyMem (&IpCfgData
.Ip6CfgData
, &mIp6IoDefaultIpConfigData
, sizeof (EFI_IP6_CONFIG_DATA
));
496 IpCfgData
.Ip6CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
497 IpCfgData
.Ip6CfgData
.TrafficClass
= CfgData
->Tcp6CfgData
.TrafficClass
;
498 IpCfgData
.Ip6CfgData
.HopLimit
= CfgData
->Tcp6CfgData
.HopLimit
;
499 IpCfgData
.Ip6CfgData
.ReceiveTimeout
= (UINT32
) (-1);
501 &IpCfgData
.Ip6CfgData
.StationAddress
,
502 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
505 &IpCfgData
.Ip6CfgData
.DestinationAddress
,
506 &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
511 // Configure the IP instance this Tcb consumes.
513 Status
= IpIoConfigIp (Tcb
->IpInfo
, &IpCfgData
);
514 if (EFI_ERROR (Status
)) {
518 if (Sk
->IpVersion
== IP_VERSION_4
) {
520 // Get the default address information if the instance is configured to use default address.
523 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
,
524 &IpCfgData
.Ip4CfgData
.StationAddress
527 &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
,
528 &IpCfgData
.Ip4CfgData
.SubnetMask
531 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp4CfgData
.AccessPoint
;
534 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
,
535 &IpCfgData
.Ip6CfgData
.StationAddress
538 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp6CfgData
.AccessPoint
;
542 // check if we can bind this endpoint in CfgData
544 Status
= TcpBind (TcpAp
, Sk
->IpVersion
);
546 if (EFI_ERROR (Status
)) {
549 "TcpConfigurePcb: Bind endpoint failed with %r\n",
557 // Initalize the operating information in this Tcb
559 ASSERT (Tcb
->State
== TCP_CLOSED
&&
560 IsListEmpty (&Tcb
->SndQue
) &&
561 IsListEmpty (&Tcb
->RcvQue
));
563 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
564 Tcb
->State
= TCP_CLOSED
;
567 Tcb
->RcvMss
= TcpGetRcvMss (Sk
);
570 Tcb
->Rto
= 3 * TCP_TICK_HZ
;
572 Tcb
->CWnd
= Tcb
->SndMss
;
573 Tcb
->Ssthresh
= 0xffffffff;
575 Tcb
->CongestState
= TCP_CONGEST_OPEN
;
577 Tcb
->KeepAliveIdle
= TCP_KEEPALIVE_IDLE_MIN
;
578 Tcb
->KeepAlivePeriod
= TCP_KEEPALIVE_PERIOD
;
579 Tcb
->MaxKeepAlive
= TCP_MAX_KEEPALIVE
;
580 Tcb
->MaxRexmit
= TCP_MAX_LOSS
;
581 Tcb
->FinWait2Timeout
= TCP_FIN_WAIT2_TIME
;
582 Tcb
->TimeWaitTimeout
= TCP_TIME_WAIT_TIME
;
583 Tcb
->ConnectTimeout
= TCP_CONNECT_TIME
;
585 if (Sk
->IpVersion
== IP_VERSION_4
) {
587 // initialize Tcb in the light of CfgData
589 Tcb
->Ttl
= CfgData
->Tcp4CfgData
.TimeToLive
;
590 Tcb
->Tos
= CfgData
->Tcp4CfgData
.TypeOfService
;
592 Tcb
->UseDefaultAddr
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
594 CopyMem (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
, sizeof (IP4_ADDR
));
595 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.StationPort
);
596 IP4_COPY_ADDRESS (&Tcb
->SubnetMask
, &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
);
598 CopyMem (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.RemoteAddress
, sizeof (IP4_ADDR
));
599 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.RemotePort
);
601 Option
= CfgData
->Tcp4CfgData
.ControlOption
;
603 Tcb
->Ttl
= CfgData
->Tcp6CfgData
.HopLimit
;
604 Tcb
->Tos
= CfgData
->Tcp6CfgData
.TrafficClass
;
606 IP6_COPY_ADDRESS (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
);
607 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.StationPort
);
609 IP6_COPY_ADDRESS (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
);
610 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.RemotePort
);
613 // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
615 Option
= (EFI_TCP4_OPTION
*) CfgData
->Tcp6CfgData
.ControlOption
;
618 if (Option
!= NULL
) {
621 (UINT32
) (TCP_COMP_VAL (
622 TCP_RCV_BUF_SIZE_MIN
,
625 Option
->ReceiveBufferSize
631 (UINT32
) (TCP_COMP_VAL (
632 TCP_SND_BUF_SIZE_MIN
,
635 Option
->SendBufferSize
642 (UINT32
) (TCP_COMP_VAL (
646 Option
->MaxSynBackLog
651 Tcb
->MaxRexmit
= (UINT16
) TCP_COMP_VAL (
657 Tcb
->FinWait2Timeout
= TCP_COMP_VAL (
659 TCP_FIN_WAIT2_TIME_MAX
,
661 (UINT32
) (Option
->FinTimeout
* TCP_TICK_HZ
)
664 if (Option
->TimeWaitTimeout
!= 0) {
665 Tcb
->TimeWaitTimeout
= TCP_COMP_VAL (
667 TCP_TIME_WAIT_TIME_MAX
,
669 (UINT32
) (Option
->TimeWaitTimeout
* TCP_TICK_HZ
)
672 Tcb
->TimeWaitTimeout
= 0;
675 if (Option
->KeepAliveProbes
!= 0) {
676 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
678 Tcb
->MaxKeepAlive
= (UINT8
) TCP_COMP_VAL (
679 TCP_MAX_KEEPALIVE_MIN
,
682 Option
->KeepAliveProbes
684 Tcb
->KeepAliveIdle
= TCP_COMP_VAL (
685 TCP_KEEPALIVE_IDLE_MIN
,
686 TCP_KEEPALIVE_IDLE_MAX
,
687 TCP_KEEPALIVE_IDLE_MIN
,
688 (UINT32
) (Option
->KeepAliveTime
* TCP_TICK_HZ
)
690 Tcb
->KeepAlivePeriod
= TCP_COMP_VAL (
691 TCP_KEEPALIVE_PERIOD_MIN
,
692 TCP_KEEPALIVE_PERIOD
,
693 TCP_KEEPALIVE_PERIOD
,
694 (UINT32
) (Option
->KeepAliveInterval
* TCP_TICK_HZ
)
698 Tcb
->ConnectTimeout
= TCP_COMP_VAL (
699 TCP_CONNECT_TIME_MIN
,
702 (UINT32
) (Option
->ConnectionTimeout
* TCP_TICK_HZ
)
705 if (!Option
->EnableNagle
) {
706 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
709 if (!Option
->EnableTimeStamp
) {
710 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
713 if (!Option
->EnableWindowScaling
) {
714 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
719 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
720 // determined, construct the IP device path and install it.
722 Status
= TcpInstallDevicePath (Sk
);
723 if (EFI_ERROR (Status
)) {
728 // update state of Tcb and socket
730 if (((Sk
->IpVersion
== IP_VERSION_4
) && !CfgData
->Tcp4CfgData
.AccessPoint
.ActiveFlag
) ||
731 ((Sk
->IpVersion
== IP_VERSION_6
) && !CfgData
->Tcp6CfgData
.AccessPoint
.ActiveFlag
)
734 TcpSetState (Tcb
, TCP_LISTEN
);
735 SockSetState (Sk
, SO_LISTENING
);
737 Sk
->ConfigureState
= SO_CONFIGURED_PASSIVE
;
740 Sk
->ConfigureState
= SO_CONFIGURED_ACTIVE
;
743 if (Sk
->IpVersion
== IP_VERSION_6
) {
744 Tcb
->Tick
= TCP6_REFRESH_NEIGHBOR_TICK
;
746 if (NetIp6IsUnspecifiedAddr (&Tcb
->RemoteEnd
.Ip
.v6
)) {
747 Tcb
->RemoteIpZero
= TRUE
;
759 The procotol handler provided to the socket layer, which is used to
760 dispatch the socket level requests by calling the corresponding
763 @param[in] Sock Pointer to the socket of this TCP instance.
764 @param[in] Request The code of this operation request.
765 @param[in] Data Pointer to the operation specific data passed in
766 together with the operation request. This is an
767 optional parameter that may be NULL.
769 @retval EFI_SUCCESS The socket request completed successfully.
770 @retval other The error status returned by the corresponding TCP
778 IN VOID
*Data OPTIONAL
782 TCP_PROTO_DATA
*ProtoData
;
784 ProtoData
= (TCP_PROTO_DATA
*) Sock
->ProtoReserved
;
785 Tcb
= ProtoData
->TcpPcb
;
789 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
790 ProtoData
->TcpService
->IpIo
->Ip
.Ip4
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip4
);
792 ProtoData
->TcpService
->IpIo
->Ip
.Ip6
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip6
);
799 // After user received data from socket buffer, socket will
800 // notify TCP using this message to give it a chance to send out
801 // window update information
803 ASSERT (Tcb
!= NULL
);
804 TcpOnAppConsume (Tcb
);
809 ASSERT (Tcb
!= NULL
);
826 Tcb
->SndPsh
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
);
827 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_PSH
);
832 Tcb
->SndUp
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
) - 1;
833 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_URG
);
839 TcpOnAppConnect (Tcb
);
845 return TcpAttachPcb (Sock
);
863 return TcpConfigurePcb (
865 (TCP_CONFIG_DATA
*) Data
872 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
));
874 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
876 return Tcp4GetMode (Tcb
, (TCP4_MODE_DATA
*) Data
);
879 return Tcp6GetMode (Tcb
, (TCP6_MODE_DATA
*) Data
);
886 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
) && (Tcb
->Sk
->IpVersion
== IP_VERSION_4
));
888 return Tcp4Route (Tcb
, (TCP4_ROUTE_INFO
*) Data
);
892 return EFI_UNSUPPORTED
;