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 - 2018, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
14 Add or remove a route entry in the IP route table associated with this TCP instance.
16 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
17 @param[in] RouteInfo Pointer to the route information to be processed.
19 @retval EFI_SUCCESS The operation completed successfully.
20 @retval EFI_NOT_STARTED The driver instance has not been started.
21 @retval EFI_NO_MAPPING When using the default address, configuration(DHCP,
22 BOOTP, RARP, etc.) is not finished yet.
23 @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
24 @retval EFI_NOT_FOUND This route is not in the routing table
25 (when RouteInfo->DeleteRoute is TRUE).
26 @retval EFI_ACCESS_DENIED The route is already defined in the routing table
27 (when RouteInfo->DeleteRoute is FALSE).
32 IN TCP4_ROUTE_INFO
*RouteInfo
39 ASSERT (Ip
.Ip4
!= NULL
);
41 return Ip
.Ip4
->Routes (
43 RouteInfo
->DeleteRoute
,
44 RouteInfo
->SubnetAddress
,
45 RouteInfo
->SubnetMask
,
46 RouteInfo
->GatewayAddress
52 Get the operational settings of this TCPv4 instance.
54 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
55 @param[in, out] Mode Pointer to the buffer to store the operational
58 @retval EFI_SUCCESS The mode data was read.
59 @retval EFI_NOT_STARTED No configuration data is available because this
60 instance hasn't been started.
66 IN OUT TCP4_MODE_DATA
*Mode
70 EFI_TCP4_CONFIG_DATA
*ConfigData
;
71 EFI_TCP4_ACCESS_POINT
*AccessPoint
;
72 EFI_TCP4_OPTION
*Option
;
77 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp4ConfigData
!= NULL
)) {
78 return EFI_NOT_STARTED
;
81 if (Mode
->Tcp4State
!= NULL
) {
82 *(Mode
->Tcp4State
) = (EFI_TCP4_CONNECTION_STATE
) Tcb
->State
;
85 if (Mode
->Tcp4ConfigData
!= NULL
) {
87 ConfigData
= Mode
->Tcp4ConfigData
;
88 AccessPoint
= &(ConfigData
->AccessPoint
);
89 Option
= ConfigData
->ControlOption
;
91 ConfigData
->TypeOfService
= Tcb
->Tos
;
92 ConfigData
->TimeToLive
= Tcb
->Ttl
;
94 AccessPoint
->UseDefaultAddress
= Tcb
->UseDefaultAddr
;
96 IP4_COPY_ADDRESS (&AccessPoint
->StationAddress
, &Tcb
->LocalEnd
.Ip
);
98 IP4_COPY_ADDRESS (&AccessPoint
->SubnetMask
, &Tcb
->SubnetMask
);
99 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
101 IP4_COPY_ADDRESS (&AccessPoint
->RemoteAddress
, &Tcb
->RemoteEnd
.Ip
);
103 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
104 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
106 if (Option
!= NULL
) {
107 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
108 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
109 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
111 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
112 Option
->DataRetries
= Tcb
->MaxRexmit
;
113 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
114 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
115 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
116 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
117 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
119 Option
->EnableNagle
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
));
120 Option
->EnableTimeStamp
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
));
121 Option
->EnableWindowScaling
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
));
123 Option
->EnableSelectiveAck
= FALSE
;
124 Option
->EnablePathMtuDiscovery
= FALSE
;
128 Ip
= Tcb
->IpInfo
->Ip
.Ip4
;
131 return Ip
->GetModeData (Ip
, Mode
->Ip4ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
135 Get the operational settings of this TCPv6 instance.
137 @param[in] Tcb Pointer to the TCP_CB of this TCP instance.
138 @param[in, out] Mode Pointer to the buffer to store the operational
141 @retval EFI_SUCCESS The mode data was read.
142 @retval EFI_NOT_STARTED No configuration data is available because this
143 instance hasn't been started.
149 IN OUT TCP6_MODE_DATA
*Mode
153 EFI_TCP6_CONFIG_DATA
*ConfigData
;
154 EFI_TCP6_ACCESS_POINT
*AccessPoint
;
155 EFI_TCP6_OPTION
*Option
;
156 EFI_IP6_PROTOCOL
*Ip
;
160 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp6ConfigData
!= NULL
)) {
161 return EFI_NOT_STARTED
;
164 if (Mode
->Tcp6State
!= NULL
) {
165 *(Mode
->Tcp6State
) = (EFI_TCP6_CONNECTION_STATE
) (Tcb
->State
);
168 if (Mode
->Tcp6ConfigData
!= NULL
) {
170 ConfigData
= Mode
->Tcp6ConfigData
;
171 AccessPoint
= &(ConfigData
->AccessPoint
);
172 Option
= ConfigData
->ControlOption
;
174 ConfigData
->TrafficClass
= Tcb
->Tos
;
175 ConfigData
->HopLimit
= Tcb
->Ttl
;
177 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
178 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
179 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
181 IP6_COPY_ADDRESS (&AccessPoint
->StationAddress
, &Tcb
->LocalEnd
.Ip
);
182 IP6_COPY_ADDRESS (&AccessPoint
->RemoteAddress
, &Tcb
->RemoteEnd
.Ip
);
184 if (Option
!= NULL
) {
185 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
186 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
187 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
189 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
190 Option
->DataRetries
= Tcb
->MaxRexmit
;
191 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
192 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
193 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
194 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
195 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
197 Option
->EnableNagle
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
));
198 Option
->EnableTimeStamp
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
));
199 Option
->EnableWindowScaling
= (BOOLEAN
) (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
));
201 Option
->EnableSelectiveAck
= FALSE
;
202 Option
->EnablePathMtuDiscovery
= FALSE
;
206 Ip
= Tcb
->IpInfo
->Ip
.Ip6
;
209 return Ip
->GetModeData (Ip
, Mode
->Ip6ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
213 If TcpAp->StationPort isn't zero, check whether the access point
214 is registered, else generate a random station port for this
217 @param[in] TcpAp Pointer to the access point.
218 @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6
220 @retval EFI_SUCCESS The check passed or the port is assigned.
221 @retval EFI_INVALID_PARAMETER The non-zero station port is already used.
222 @retval EFI_OUT_OF_RESOURCES No port can be allocated.
227 IN TCP_ACCESS_POINT
*TcpAp
,
232 EFI_IP_ADDRESS Local
;
236 if (IpVersion
== IP_VERSION_4
) {
237 IP4_COPY_ADDRESS (&Local
, &TcpAp
->Tcp4Ap
.StationAddress
);
238 Port
= &TcpAp
->Tcp4Ap
.StationPort
;
239 RandomPort
= &mTcp4RandomPort
;
241 IP6_COPY_ADDRESS (&Local
, &TcpAp
->Tcp6Ap
.StationAddress
);
242 Port
= &TcpAp
->Tcp6Ap
.StationPort
;
243 RandomPort
= &mTcp6RandomPort
;
248 // Check if a same endpoing is bound.
250 if (TcpFindTcbByPeer (&Local
, *Port
, IpVersion
)) {
252 return EFI_INVALID_PARAMETER
;
256 // generate a random port
260 if (TCP_PORT_USER_RESERVED
== *RandomPort
) {
261 *RandomPort
= TCP_PORT_KNOWN
;
266 while (TcpFindTcbByPeer (&Local
, *RandomPort
, IpVersion
)) {
269 if (*RandomPort
<= TCP_PORT_KNOWN
) {
273 "TcpBind: no port can be allocated for this pcb\n")
275 return EFI_OUT_OF_RESOURCES
;
278 *RandomPort
= TCP_PORT_KNOWN
+ 1;
291 Flush the Tcb add its associated protocols.
293 @param[in, out] Tcb Pointer to the TCP_CB to be flushed.
303 IpIoConfigIp (Tcb
->IpInfo
, NULL
);
307 if (SOCK_IS_CONFIGURED (Sock
)) {
308 RemoveEntryList (&Tcb
->List
);
310 if (Sock
->DevicePath
!= NULL
) {
312 // Uninstall the device path protocol.
314 gBS
->UninstallProtocolInterface (
316 &gEfiDevicePathProtocolGuid
,
320 FreePool (Sock
->DevicePath
);
321 Sock
->DevicePath
= NULL
;
325 NetbufFreeList (&Tcb
->SndQue
);
326 NetbufFreeList (&Tcb
->RcvQue
);
327 Tcb
->State
= TCP_CLOSED
;
328 Tcb
->RemoteIpZero
= FALSE
;
332 Attach a Pcb to the socket.
334 @param[in] Sk Pointer to the socket of this TCP instance.
336 @retval EFI_SUCCESS The operation completed successfully.
337 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
346 TCP_PROTO_DATA
*ProtoData
;
350 EFI_GUID
*IpProtocolGuid
;
352 if (Sk
->IpVersion
== IP_VERSION_4
) {
353 IpProtocolGuid
= &gEfiIp4ProtocolGuid
;
355 IpProtocolGuid
= &gEfiIp6ProtocolGuid
;
358 Tcb
= AllocateZeroPool (sizeof (TCP_CB
));
362 DEBUG ((EFI_D_ERROR
, "TcpConfigurePcb: failed to allocate a TCB\n"));
364 return EFI_OUT_OF_RESOURCES
;
367 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
368 IpIo
= ProtoData
->TcpService
->IpIo
;
371 // Create an IpInfo for this Tcb.
373 Tcb
->IpInfo
= IpIoAddIp (IpIo
);
374 if (Tcb
->IpInfo
== NULL
) {
377 return EFI_OUT_OF_RESOURCES
;
381 // Open the new created IP instance BY_CHILD.
383 Status
= gBS
->OpenProtocol (
384 Tcb
->IpInfo
->ChildHandle
,
389 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
391 if (EFI_ERROR (Status
)) {
392 IpIoRemoveIp (IpIo
, Tcb
->IpInfo
);
397 InitializeListHead (&Tcb
->List
);
398 InitializeListHead (&Tcb
->SndQue
);
399 InitializeListHead (&Tcb
->RcvQue
);
401 Tcb
->State
= TCP_CLOSED
;
403 ProtoData
->TcpPcb
= Tcb
;
409 Detach the Pcb of the socket.
411 @param[in, out] Sk Pointer to the socket of this TCP instance.
419 TCP_PROTO_DATA
*ProtoData
;
422 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
423 Tcb
= ProtoData
->TcpPcb
;
425 ASSERT (Tcb
!= NULL
);
429 IpIoRemoveIp (ProtoData
->TcpService
->IpIo
, Tcb
->IpInfo
);
433 ProtoData
->TcpPcb
= NULL
;
437 Configure the Pcb using CfgData.
439 @param[in] Sk Pointer to the socket of this TCP instance.
440 @param[in] CfgData Pointer to the TCP configuration data.
442 @retval EFI_SUCCESS The operation completed successfully.
443 @retval EFI_INVALID_PARAMETER A same access point has been configured in
444 another TCP instance.
445 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
451 IN TCP_CONFIG_DATA
*CfgData
454 IP_IO_IP_CONFIG_DATA IpCfgData
;
456 EFI_TCP4_OPTION
*Option
;
457 TCP_PROTO_DATA
*TcpProto
;
459 TCP_ACCESS_POINT
*TcpAp
;
461 ASSERT ((CfgData
!= NULL
) && (Sk
!= NULL
) && (Sk
->SockHandle
!= NULL
));
463 TcpProto
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
464 Tcb
= TcpProto
->TcpPcb
;
466 ASSERT (Tcb
!= NULL
);
468 if (Sk
->IpVersion
== IP_VERSION_4
) {
470 // Add Ip for send pkt to the peer
472 CopyMem (&IpCfgData
.Ip4CfgData
, &mIp4IoDefaultIpConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
473 IpCfgData
.Ip4CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
474 IpCfgData
.Ip4CfgData
.TypeOfService
= CfgData
->Tcp4CfgData
.TypeOfService
;
475 IpCfgData
.Ip4CfgData
.TimeToLive
= CfgData
->Tcp4CfgData
.TimeToLive
;
476 IpCfgData
.Ip4CfgData
.UseDefaultAddress
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
478 &IpCfgData
.Ip4CfgData
.SubnetMask
,
479 &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
481 IpCfgData
.Ip4CfgData
.ReceiveTimeout
= (UINT32
) (-1);
483 &IpCfgData
.Ip4CfgData
.StationAddress
,
484 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
488 ASSERT (Sk
->IpVersion
== IP_VERSION_6
);
490 CopyMem (&IpCfgData
.Ip6CfgData
, &mIp6IoDefaultIpConfigData
, sizeof (EFI_IP6_CONFIG_DATA
));
491 IpCfgData
.Ip6CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
492 IpCfgData
.Ip6CfgData
.TrafficClass
= CfgData
->Tcp6CfgData
.TrafficClass
;
493 IpCfgData
.Ip6CfgData
.HopLimit
= CfgData
->Tcp6CfgData
.HopLimit
;
494 IpCfgData
.Ip6CfgData
.ReceiveTimeout
= (UINT32
) (-1);
496 &IpCfgData
.Ip6CfgData
.StationAddress
,
497 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
500 &IpCfgData
.Ip6CfgData
.DestinationAddress
,
501 &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
506 // Configure the IP instance this Tcb consumes.
508 Status
= IpIoConfigIp (Tcb
->IpInfo
, &IpCfgData
);
509 if (EFI_ERROR (Status
)) {
513 if (Sk
->IpVersion
== IP_VERSION_4
) {
515 // Get the default address information if the instance is configured to use default address.
518 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
,
519 &IpCfgData
.Ip4CfgData
.StationAddress
522 &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
,
523 &IpCfgData
.Ip4CfgData
.SubnetMask
526 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp4CfgData
.AccessPoint
;
529 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
,
530 &IpCfgData
.Ip6CfgData
.StationAddress
533 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp6CfgData
.AccessPoint
;
537 // check if we can bind this endpoint in CfgData
539 Status
= TcpBind (TcpAp
, Sk
->IpVersion
);
541 if (EFI_ERROR (Status
)) {
544 "TcpConfigurePcb: Bind endpoint failed with %r\n",
552 // Initialize the operating information in this Tcb
554 ASSERT (Tcb
->State
== TCP_CLOSED
&&
555 IsListEmpty (&Tcb
->SndQue
) &&
556 IsListEmpty (&Tcb
->RcvQue
));
558 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
559 Tcb
->State
= TCP_CLOSED
;
562 Tcb
->RcvMss
= TcpGetRcvMss (Sk
);
565 Tcb
->Rto
= 3 * TCP_TICK_HZ
;
567 Tcb
->CWnd
= Tcb
->SndMss
;
568 Tcb
->Ssthresh
= 0xffffffff;
570 Tcb
->CongestState
= TCP_CONGEST_OPEN
;
572 Tcb
->KeepAliveIdle
= TCP_KEEPALIVE_IDLE_MIN
;
573 Tcb
->KeepAlivePeriod
= TCP_KEEPALIVE_PERIOD
;
574 Tcb
->MaxKeepAlive
= TCP_MAX_KEEPALIVE
;
575 Tcb
->MaxRexmit
= TCP_MAX_LOSS
;
576 Tcb
->FinWait2Timeout
= TCP_FIN_WAIT2_TIME
;
577 Tcb
->TimeWaitTimeout
= TCP_TIME_WAIT_TIME
;
578 Tcb
->ConnectTimeout
= TCP_CONNECT_TIME
;
580 if (Sk
->IpVersion
== IP_VERSION_4
) {
582 // initialize Tcb in the light of CfgData
584 Tcb
->Ttl
= CfgData
->Tcp4CfgData
.TimeToLive
;
585 Tcb
->Tos
= CfgData
->Tcp4CfgData
.TypeOfService
;
587 Tcb
->UseDefaultAddr
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
589 CopyMem (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
, sizeof (IP4_ADDR
));
590 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.StationPort
);
591 IP4_COPY_ADDRESS (&Tcb
->SubnetMask
, &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
);
593 CopyMem (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.RemoteAddress
, sizeof (IP4_ADDR
));
594 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.RemotePort
);
596 Option
= CfgData
->Tcp4CfgData
.ControlOption
;
598 Tcb
->Ttl
= CfgData
->Tcp6CfgData
.HopLimit
;
599 Tcb
->Tos
= CfgData
->Tcp6CfgData
.TrafficClass
;
601 IP6_COPY_ADDRESS (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
);
602 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.StationPort
);
604 IP6_COPY_ADDRESS (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
);
605 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.RemotePort
);
608 // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
610 Option
= (EFI_TCP4_OPTION
*) CfgData
->Tcp6CfgData
.ControlOption
;
613 if (Option
!= NULL
) {
616 (UINT32
) (TCP_COMP_VAL (
617 TCP_RCV_BUF_SIZE_MIN
,
620 Option
->ReceiveBufferSize
626 (UINT32
) (TCP_COMP_VAL (
627 TCP_SND_BUF_SIZE_MIN
,
630 Option
->SendBufferSize
637 (UINT32
) (TCP_COMP_VAL (
641 Option
->MaxSynBackLog
646 Tcb
->MaxRexmit
= (UINT16
) TCP_COMP_VAL (
652 Tcb
->FinWait2Timeout
= TCP_COMP_VAL (
654 TCP_FIN_WAIT2_TIME_MAX
,
656 (UINT32
) (Option
->FinTimeout
* TCP_TICK_HZ
)
659 if (Option
->TimeWaitTimeout
!= 0) {
660 Tcb
->TimeWaitTimeout
= TCP_COMP_VAL (
662 TCP_TIME_WAIT_TIME_MAX
,
664 (UINT32
) (Option
->TimeWaitTimeout
* TCP_TICK_HZ
)
667 Tcb
->TimeWaitTimeout
= 0;
670 if (Option
->KeepAliveProbes
!= 0) {
671 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
673 Tcb
->MaxKeepAlive
= (UINT8
) TCP_COMP_VAL (
674 TCP_MAX_KEEPALIVE_MIN
,
677 Option
->KeepAliveProbes
679 Tcb
->KeepAliveIdle
= TCP_COMP_VAL (
680 TCP_KEEPALIVE_IDLE_MIN
,
681 TCP_KEEPALIVE_IDLE_MAX
,
682 TCP_KEEPALIVE_IDLE_MIN
,
683 (UINT32
) (Option
->KeepAliveTime
* TCP_TICK_HZ
)
685 Tcb
->KeepAlivePeriod
= TCP_COMP_VAL (
686 TCP_KEEPALIVE_PERIOD_MIN
,
687 TCP_KEEPALIVE_PERIOD
,
688 TCP_KEEPALIVE_PERIOD
,
689 (UINT32
) (Option
->KeepAliveInterval
* TCP_TICK_HZ
)
693 Tcb
->ConnectTimeout
= TCP_COMP_VAL (
694 TCP_CONNECT_TIME_MIN
,
697 (UINT32
) (Option
->ConnectionTimeout
* TCP_TICK_HZ
)
700 if (!Option
->EnableNagle
) {
701 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
704 if (!Option
->EnableTimeStamp
) {
705 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
708 if (!Option
->EnableWindowScaling
) {
709 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
714 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
715 // determined, construct the IP device path and install it.
717 Status
= TcpInstallDevicePath (Sk
);
718 if (EFI_ERROR (Status
)) {
723 // update state of Tcb and socket
725 if (((Sk
->IpVersion
== IP_VERSION_4
) && !CfgData
->Tcp4CfgData
.AccessPoint
.ActiveFlag
) ||
726 ((Sk
->IpVersion
== IP_VERSION_6
) && !CfgData
->Tcp6CfgData
.AccessPoint
.ActiveFlag
)
729 TcpSetState (Tcb
, TCP_LISTEN
);
730 SockSetState (Sk
, SO_LISTENING
);
732 Sk
->ConfigureState
= SO_CONFIGURED_PASSIVE
;
735 Sk
->ConfigureState
= SO_CONFIGURED_ACTIVE
;
738 if (Sk
->IpVersion
== IP_VERSION_6
) {
739 Tcb
->Tick
= TCP6_REFRESH_NEIGHBOR_TICK
;
741 if (NetIp6IsUnspecifiedAddr (&Tcb
->RemoteEnd
.Ip
.v6
)) {
742 Tcb
->RemoteIpZero
= TRUE
;
754 The protocol handler provided to the socket layer, which is used to
755 dispatch the socket level requests by calling the corresponding
758 @param[in] Sock Pointer to the socket of this TCP instance.
759 @param[in] Request The code of this operation request.
760 @param[in] Data Pointer to the operation specific data passed in
761 together with the operation request. This is an
762 optional parameter that may be NULL.
764 @retval EFI_SUCCESS The socket request completed successfully.
765 @retval other The error status returned by the corresponding TCP
773 IN VOID
*Data OPTIONAL
777 TCP_PROTO_DATA
*ProtoData
;
779 ProtoData
= (TCP_PROTO_DATA
*) Sock
->ProtoReserved
;
780 Tcb
= ProtoData
->TcpPcb
;
784 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
785 ProtoData
->TcpService
->IpIo
->Ip
.Ip4
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip4
);
787 ProtoData
->TcpService
->IpIo
->Ip
.Ip6
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip6
);
794 // After user received data from socket buffer, socket will
795 // notify TCP using this message to give it a chance to send out
796 // window update information
798 ASSERT (Tcb
!= NULL
);
799 TcpOnAppConsume (Tcb
);
804 ASSERT (Tcb
!= NULL
);
821 Tcb
->SndPsh
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
);
822 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_PSH
);
827 Tcb
->SndUp
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
) - 1;
828 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_URG
);
834 TcpOnAppConnect (Tcb
);
840 return TcpAttachPcb (Sock
);
858 return TcpConfigurePcb (
860 (TCP_CONFIG_DATA
*) Data
867 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
));
869 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
871 return Tcp4GetMode (Tcb
, (TCP4_MODE_DATA
*) Data
);
874 return Tcp6GetMode (Tcb
, (TCP6_MODE_DATA
*) Data
);
881 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
) && (Tcb
->Sk
->IpVersion
== IP_VERSION_4
));
883 return Tcp4Route (Tcb
, (TCP4_ROUTE_INFO
*) Data
);
887 return EFI_UNSUPPORTED
;