2 The implementation of a dispatch routine for processing TCP requests.
4 Copyright (c) 2009 - 2012, 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.
307 TCP_PROTO_DATA
*TcpProto
;
309 IpIoConfigIp (Tcb
->IpInfo
, NULL
);
312 TcpProto
= (TCP_PROTO_DATA
*) Sock
->ProtoReserved
;
314 if (SOCK_IS_CONFIGURED (Sock
)) {
315 RemoveEntryList (&Tcb
->List
);
317 if (Sock
->DevicePath
!= NULL
) {
319 // Uninstall the device path protocl.
321 gBS
->UninstallProtocolInterface (
323 &gEfiDevicePathProtocolGuid
,
327 FreePool (Sock
->DevicePath
);
328 Sock
->DevicePath
= NULL
;
331 TcpSetVariableData (TcpProto
->TcpService
);
334 NetbufFreeList (&Tcb
->SndQue
);
335 NetbufFreeList (&Tcb
->RcvQue
);
336 Tcb
->State
= TCP_CLOSED
;
337 Tcb
->RemoteIpZero
= FALSE
;
341 Attach a Pcb to the socket.
343 @param[in] Sk Pointer to the socket of this TCP instance.
345 @retval EFI_SUCCESS The operation completed successfully.
346 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
355 TCP_PROTO_DATA
*ProtoData
;
359 EFI_GUID
*IpProtocolGuid
;
361 if (Sk
->IpVersion
== IP_VERSION_4
) {
362 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
364 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
367 Tcb
= AllocateZeroPool (sizeof (TCP_CB
));
371 DEBUG ((EFI_D_ERROR
, "TcpConfigurePcb: failed to allocate a TCB\n"));
373 return EFI_OUT_OF_RESOURCES
;
376 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
377 IpIo
= ProtoData
->TcpService
->IpIo
;
380 // Create an IpInfo for this Tcb.
382 Tcb
->IpInfo
= IpIoAddIp (IpIo
);
383 if (Tcb
->IpInfo
== NULL
) {
386 return EFI_OUT_OF_RESOURCES
;
390 // Open the new created IP instance BY_CHILD.
392 Status
= gBS
->OpenProtocol (
393 Tcb
->IpInfo
->ChildHandle
,
398 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
400 if (EFI_ERROR (Status
)) {
401 IpIoRemoveIp (IpIo
, Tcb
->IpInfo
);
405 InitializeListHead (&Tcb
->List
);
406 InitializeListHead (&Tcb
->SndQue
);
407 InitializeListHead (&Tcb
->RcvQue
);
409 Tcb
->State
= TCP_CLOSED
;
411 ProtoData
->TcpPcb
= Tcb
;
417 Detach the Pcb of the socket.
419 @param[in, out] Sk Pointer to the socket of this TCP instance.
427 TCP_PROTO_DATA
*ProtoData
;
429 EFI_GUID
*IpProtocolGuid
;
431 if (Sk
->IpVersion
== IP_VERSION_4
) {
432 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
434 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
437 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
438 Tcb
= ProtoData
->TcpPcb
;
440 ASSERT (Tcb
!= NULL
);
445 // Close the IP protocol.
448 Tcb
->IpInfo
->ChildHandle
,
450 ProtoData
->TcpService
->IpIo
->Image
,
454 IpIoRemoveIp (ProtoData
->TcpService
->IpIo
, Tcb
->IpInfo
);
458 ProtoData
->TcpPcb
= NULL
;
462 Configure the Pcb using CfgData.
464 @param[in] Sk Pointer to the socket of this TCP instance.
465 @param[in] CfgData Pointer to the TCP configuration data.
467 @retval EFI_SUCCESS The operation completed successfully.
468 @retval EFI_INVALID_PARAMETER A same access point has been configured in
469 another TCP instance.
470 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
476 IN TCP_CONFIG_DATA
*CfgData
479 IP_IO_IP_CONFIG_DATA IpCfgData
;
481 EFI_TCP4_OPTION
*Option
;
482 TCP_PROTO_DATA
*TcpProto
;
484 TCP_ACCESS_POINT
*TcpAp
;
486 ASSERT ((CfgData
!= NULL
) && (Sk
!= NULL
) && (Sk
->SockHandle
!= NULL
));
488 TcpProto
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
489 Tcb
= TcpProto
->TcpPcb
;
491 ASSERT (Tcb
!= NULL
);
493 if (Sk
->IpVersion
== IP_VERSION_4
) {
495 // Add Ip for send pkt to the peer
497 CopyMem (&IpCfgData
.Ip4CfgData
, &mIp4IoDefaultIpConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
498 IpCfgData
.Ip4CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
499 IpCfgData
.Ip4CfgData
.TypeOfService
= CfgData
->Tcp4CfgData
.TypeOfService
;
500 IpCfgData
.Ip4CfgData
.TimeToLive
= CfgData
->Tcp4CfgData
.TimeToLive
;
501 IpCfgData
.Ip4CfgData
.UseDefaultAddress
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
502 IpCfgData
.Ip4CfgData
.SubnetMask
= CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
;
503 IpCfgData
.Ip4CfgData
.ReceiveTimeout
= (UINT32
) (-1);
505 &IpCfgData
.Ip4CfgData
.StationAddress
,
506 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
,
507 sizeof (EFI_IPv4_ADDRESS
)
511 ASSERT (Sk
->IpVersion
== IP_VERSION_6
);
513 CopyMem (&IpCfgData
.Ip6CfgData
, &mIp6IoDefaultIpConfigData
, sizeof (EFI_IP6_CONFIG_DATA
));
514 IpCfgData
.Ip6CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
515 IpCfgData
.Ip6CfgData
.TrafficClass
= CfgData
->Tcp6CfgData
.TrafficClass
;
516 IpCfgData
.Ip6CfgData
.HopLimit
= CfgData
->Tcp6CfgData
.HopLimit
;
517 IpCfgData
.Ip6CfgData
.ReceiveTimeout
= (UINT32
) (-1);
519 &IpCfgData
.Ip6CfgData
.StationAddress
,
520 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
523 &IpCfgData
.Ip6CfgData
.DestinationAddress
,
524 &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
529 // Configure the IP instance this Tcb consumes.
531 Status
= IpIoConfigIp (Tcb
->IpInfo
, &IpCfgData
);
532 if (EFI_ERROR (Status
)) {
536 if (Sk
->IpVersion
== IP_VERSION_4
) {
538 // Get the default address information if the instance is configured to use default address.
540 CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
= IpCfgData
.Ip4CfgData
.StationAddress
;
541 CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
= IpCfgData
.Ip4CfgData
.SubnetMask
;
543 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp4CfgData
.AccessPoint
;
546 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
,
547 &IpCfgData
.Ip6CfgData
.StationAddress
550 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp6CfgData
.AccessPoint
;
554 // check if we can bind this endpoint in CfgData
556 Status
= TcpBind (TcpAp
, Sk
->IpVersion
);
558 if (EFI_ERROR (Status
)) {
561 "TcpConfigurePcb: Bind endpoint failed with %r\n",
569 // Initalize the operating information in this Tcb
571 ASSERT (Tcb
->State
== TCP_CLOSED
&&
572 IsListEmpty (&Tcb
->SndQue
) &&
573 IsListEmpty (&Tcb
->RcvQue
));
575 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
576 Tcb
->State
= TCP_CLOSED
;
579 Tcb
->RcvMss
= TcpGetRcvMss (Sk
);
582 Tcb
->Rto
= 3 * TCP_TICK_HZ
;
584 Tcb
->CWnd
= Tcb
->SndMss
;
585 Tcb
->Ssthresh
= 0xffffffff;
587 Tcb
->CongestState
= TCP_CONGEST_OPEN
;
589 Tcb
->KeepAliveIdle
= TCP_KEEPALIVE_IDLE_MIN
;
590 Tcb
->KeepAlivePeriod
= TCP_KEEPALIVE_PERIOD
;
591 Tcb
->MaxKeepAlive
= TCP_MAX_KEEPALIVE
;
592 Tcb
->MaxRexmit
= TCP_MAX_LOSS
;
593 Tcb
->FinWait2Timeout
= TCP_FIN_WAIT2_TIME
;
594 Tcb
->TimeWaitTimeout
= TCP_TIME_WAIT_TIME
;
595 Tcb
->ConnectTimeout
= TCP_CONNECT_TIME
;
597 if (Sk
->IpVersion
== IP_VERSION_4
) {
599 // initialize Tcb in the light of CfgData
601 Tcb
->Ttl
= CfgData
->Tcp4CfgData
.TimeToLive
;
602 Tcb
->Tos
= CfgData
->Tcp4CfgData
.TypeOfService
;
604 Tcb
->UseDefaultAddr
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
606 CopyMem (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
, sizeof (IP4_ADDR
));
607 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.StationPort
);
608 Tcb
->SubnetMask
= CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
;
610 CopyMem (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.RemoteAddress
, sizeof (IP4_ADDR
));
611 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.RemotePort
);
613 Option
= CfgData
->Tcp4CfgData
.ControlOption
;
615 Tcb
->Ttl
= CfgData
->Tcp6CfgData
.HopLimit
;
616 Tcb
->Tos
= CfgData
->Tcp6CfgData
.TrafficClass
;
618 IP6_COPY_ADDRESS (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
);
619 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.StationPort
);
621 IP6_COPY_ADDRESS (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
);
622 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.RemotePort
);
625 // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
627 Option
= (EFI_TCP4_OPTION
*) CfgData
->Tcp6CfgData
.ControlOption
;
630 if (Option
!= NULL
) {
633 (UINT32
) (TCP_COMP_VAL (
634 TCP_RCV_BUF_SIZE_MIN
,
637 Option
->ReceiveBufferSize
643 (UINT32
) (TCP_COMP_VAL (
644 TCP_SND_BUF_SIZE_MIN
,
647 Option
->SendBufferSize
654 (UINT32
) (TCP_COMP_VAL (
658 Option
->MaxSynBackLog
663 Tcb
->MaxRexmit
= (UINT16
) TCP_COMP_VAL (
669 Tcb
->FinWait2Timeout
= TCP_COMP_VAL (
671 TCP_FIN_WAIT2_TIME_MAX
,
673 (UINT32
) (Option
->FinTimeout
* TCP_TICK_HZ
)
676 if (Option
->TimeWaitTimeout
!= 0) {
677 Tcb
->TimeWaitTimeout
= TCP_COMP_VAL (
679 TCP_TIME_WAIT_TIME_MAX
,
681 (UINT32
) (Option
->TimeWaitTimeout
* TCP_TICK_HZ
)
684 Tcb
->TimeWaitTimeout
= 0;
687 if (Option
->KeepAliveProbes
!= 0) {
688 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
690 Tcb
->MaxKeepAlive
= (UINT8
) TCP_COMP_VAL (
691 TCP_MAX_KEEPALIVE_MIN
,
694 Option
->KeepAliveProbes
696 Tcb
->KeepAliveIdle
= TCP_COMP_VAL (
697 TCP_KEEPALIVE_IDLE_MIN
,
698 TCP_KEEPALIVE_IDLE_MAX
,
699 TCP_KEEPALIVE_IDLE_MIN
,
700 (UINT32
) (Option
->KeepAliveTime
* TCP_TICK_HZ
)
702 Tcb
->KeepAlivePeriod
= TCP_COMP_VAL (
703 TCP_KEEPALIVE_PERIOD_MIN
,
704 TCP_KEEPALIVE_PERIOD
,
705 TCP_KEEPALIVE_PERIOD
,
706 (UINT32
) (Option
->KeepAliveInterval
* TCP_TICK_HZ
)
710 Tcb
->ConnectTimeout
= TCP_COMP_VAL (
711 TCP_CONNECT_TIME_MIN
,
714 (UINT32
) (Option
->ConnectionTimeout
* TCP_TICK_HZ
)
717 if (!Option
->EnableNagle
) {
718 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
721 if (!Option
->EnableTimeStamp
) {
722 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
725 if (!Option
->EnableWindowScaling
) {
726 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
731 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
732 // determined, construct the IP device path and install it.
734 Status
= TcpInstallDevicePath (Sk
);
735 if (EFI_ERROR (Status
)) {
740 // update state of Tcb and socket
742 if (((Sk
->IpVersion
== IP_VERSION_4
) && !CfgData
->Tcp4CfgData
.AccessPoint
.ActiveFlag
) ||
743 ((Sk
->IpVersion
== IP_VERSION_6
) && !CfgData
->Tcp6CfgData
.AccessPoint
.ActiveFlag
)
746 TcpSetState (Tcb
, TCP_LISTEN
);
747 SockSetState (Sk
, SO_LISTENING
);
749 Sk
->ConfigureState
= SO_CONFIGURED_PASSIVE
;
752 Sk
->ConfigureState
= SO_CONFIGURED_ACTIVE
;
755 if (Sk
->IpVersion
== IP_VERSION_6
) {
756 Tcb
->Tick
= TCP6_REFRESH_NEIGHBOR_TICK
;
758 if (NetIp6IsUnspecifiedAddr (&Tcb
->RemoteEnd
.Ip
.v6
)) {
759 Tcb
->RemoteIpZero
= TRUE
;
771 The procotol handler provided to the socket layer, which is used to
772 dispatch the socket level requests by calling the corresponding
775 @param[in] Sock Pointer to the socket of this TCP instance.
776 @param[in] Request The code of this operation request.
777 @param[in] Data Pointer to the operation specific data passed in
778 together with the operation request. This is an
779 optional parameter that may be NULL.
781 @retval EFI_SUCCESS The socket request completed successfully.
782 @retval other The error status returned by the corresponding TCP
790 IN VOID
*Data OPTIONAL
794 TCP_PROTO_DATA
*ProtoData
;
796 ProtoData
= (TCP_PROTO_DATA
*) Sock
->ProtoReserved
;
797 Tcb
= ProtoData
->TcpPcb
;
801 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
802 ProtoData
->TcpService
->IpIo
->Ip
.Ip4
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip4
);
804 ProtoData
->TcpService
->IpIo
->Ip
.Ip6
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip6
);
811 // After user received data from socket buffer, socket will
812 // notify TCP using this message to give it a chance to send out
813 // window update information
815 ASSERT (Tcb
!= NULL
);
816 TcpOnAppConsume (Tcb
);
821 ASSERT (Tcb
!= NULL
);
838 Tcb
->SndPsh
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
);
839 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_PSH
);
844 Tcb
->SndUp
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
) - 1;
845 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_URG
);
851 TcpOnAppConnect (Tcb
);
857 return TcpAttachPcb (Sock
);
875 return TcpConfigurePcb (
877 (TCP_CONFIG_DATA
*) Data
884 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
));
886 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
888 return Tcp4GetMode (Tcb
, (TCP4_MODE_DATA
*) Data
);
891 return Tcp6GetMode (Tcb
, (TCP6_MODE_DATA
*) Data
);
898 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
) && (Tcb
->Sk
->IpVersion
== IP_VERSION_4
));
900 return Tcp4Route (Tcb
, (TCP4_ROUTE_INFO
*) Data
);
904 return EFI_UNSUPPORTED
;