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 protocl.
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
);
396 InitializeListHead (&Tcb
->List
);
397 InitializeListHead (&Tcb
->SndQue
);
398 InitializeListHead (&Tcb
->RcvQue
);
400 Tcb
->State
= TCP_CLOSED
;
402 ProtoData
->TcpPcb
= Tcb
;
408 Detach the Pcb of the socket.
410 @param[in, out] Sk Pointer to the socket of this TCP instance.
418 TCP_PROTO_DATA
*ProtoData
;
421 ProtoData
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
422 Tcb
= ProtoData
->TcpPcb
;
424 ASSERT (Tcb
!= NULL
);
428 IpIoRemoveIp (ProtoData
->TcpService
->IpIo
, Tcb
->IpInfo
);
432 ProtoData
->TcpPcb
= NULL
;
436 Configure the Pcb using CfgData.
438 @param[in] Sk Pointer to the socket of this TCP instance.
439 @param[in] CfgData Pointer to the TCP configuration data.
441 @retval EFI_SUCCESS The operation completed successfully.
442 @retval EFI_INVALID_PARAMETER A same access point has been configured in
443 another TCP instance.
444 @retval EFI_OUT_OF_RESOURCES Failed due to resource limits.
450 IN TCP_CONFIG_DATA
*CfgData
453 IP_IO_IP_CONFIG_DATA IpCfgData
;
455 EFI_TCP4_OPTION
*Option
;
456 TCP_PROTO_DATA
*TcpProto
;
458 TCP_ACCESS_POINT
*TcpAp
;
460 ASSERT ((CfgData
!= NULL
) && (Sk
!= NULL
) && (Sk
->SockHandle
!= NULL
));
462 TcpProto
= (TCP_PROTO_DATA
*) Sk
->ProtoReserved
;
463 Tcb
= TcpProto
->TcpPcb
;
465 ASSERT (Tcb
!= NULL
);
467 if (Sk
->IpVersion
== IP_VERSION_4
) {
469 // Add Ip for send pkt to the peer
471 CopyMem (&IpCfgData
.Ip4CfgData
, &mIp4IoDefaultIpConfigData
, sizeof (EFI_IP4_CONFIG_DATA
));
472 IpCfgData
.Ip4CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
473 IpCfgData
.Ip4CfgData
.TypeOfService
= CfgData
->Tcp4CfgData
.TypeOfService
;
474 IpCfgData
.Ip4CfgData
.TimeToLive
= CfgData
->Tcp4CfgData
.TimeToLive
;
475 IpCfgData
.Ip4CfgData
.UseDefaultAddress
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
477 &IpCfgData
.Ip4CfgData
.SubnetMask
,
478 &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
480 IpCfgData
.Ip4CfgData
.ReceiveTimeout
= (UINT32
) (-1);
482 &IpCfgData
.Ip4CfgData
.StationAddress
,
483 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
487 ASSERT (Sk
->IpVersion
== IP_VERSION_6
);
489 CopyMem (&IpCfgData
.Ip6CfgData
, &mIp6IoDefaultIpConfigData
, sizeof (EFI_IP6_CONFIG_DATA
));
490 IpCfgData
.Ip6CfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
491 IpCfgData
.Ip6CfgData
.TrafficClass
= CfgData
->Tcp6CfgData
.TrafficClass
;
492 IpCfgData
.Ip6CfgData
.HopLimit
= CfgData
->Tcp6CfgData
.HopLimit
;
493 IpCfgData
.Ip6CfgData
.ReceiveTimeout
= (UINT32
) (-1);
495 &IpCfgData
.Ip6CfgData
.StationAddress
,
496 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
499 &IpCfgData
.Ip6CfgData
.DestinationAddress
,
500 &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
505 // Configure the IP instance this Tcb consumes.
507 Status
= IpIoConfigIp (Tcb
->IpInfo
, &IpCfgData
);
508 if (EFI_ERROR (Status
)) {
512 if (Sk
->IpVersion
== IP_VERSION_4
) {
514 // Get the default address information if the instance is configured to use default address.
517 &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
,
518 &IpCfgData
.Ip4CfgData
.StationAddress
521 &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
,
522 &IpCfgData
.Ip4CfgData
.SubnetMask
525 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp4CfgData
.AccessPoint
;
528 &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
,
529 &IpCfgData
.Ip6CfgData
.StationAddress
532 TcpAp
= (TCP_ACCESS_POINT
*) &CfgData
->Tcp6CfgData
.AccessPoint
;
536 // check if we can bind this endpoint in CfgData
538 Status
= TcpBind (TcpAp
, Sk
->IpVersion
);
540 if (EFI_ERROR (Status
)) {
543 "TcpConfigurePcb: Bind endpoint failed with %r\n",
551 // Initalize the operating information in this Tcb
553 ASSERT (Tcb
->State
== TCP_CLOSED
&&
554 IsListEmpty (&Tcb
->SndQue
) &&
555 IsListEmpty (&Tcb
->RcvQue
));
557 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
558 Tcb
->State
= TCP_CLOSED
;
561 Tcb
->RcvMss
= TcpGetRcvMss (Sk
);
564 Tcb
->Rto
= 3 * TCP_TICK_HZ
;
566 Tcb
->CWnd
= Tcb
->SndMss
;
567 Tcb
->Ssthresh
= 0xffffffff;
569 Tcb
->CongestState
= TCP_CONGEST_OPEN
;
571 Tcb
->KeepAliveIdle
= TCP_KEEPALIVE_IDLE_MIN
;
572 Tcb
->KeepAlivePeriod
= TCP_KEEPALIVE_PERIOD
;
573 Tcb
->MaxKeepAlive
= TCP_MAX_KEEPALIVE
;
574 Tcb
->MaxRexmit
= TCP_MAX_LOSS
;
575 Tcb
->FinWait2Timeout
= TCP_FIN_WAIT2_TIME
;
576 Tcb
->TimeWaitTimeout
= TCP_TIME_WAIT_TIME
;
577 Tcb
->ConnectTimeout
= TCP_CONNECT_TIME
;
579 if (Sk
->IpVersion
== IP_VERSION_4
) {
581 // initialize Tcb in the light of CfgData
583 Tcb
->Ttl
= CfgData
->Tcp4CfgData
.TimeToLive
;
584 Tcb
->Tos
= CfgData
->Tcp4CfgData
.TypeOfService
;
586 Tcb
->UseDefaultAddr
= CfgData
->Tcp4CfgData
.AccessPoint
.UseDefaultAddress
;
588 CopyMem (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.StationAddress
, sizeof (IP4_ADDR
));
589 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.StationPort
);
590 IP4_COPY_ADDRESS (&Tcb
->SubnetMask
, &CfgData
->Tcp4CfgData
.AccessPoint
.SubnetMask
);
592 CopyMem (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp4CfgData
.AccessPoint
.RemoteAddress
, sizeof (IP4_ADDR
));
593 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp4CfgData
.AccessPoint
.RemotePort
);
595 Option
= CfgData
->Tcp4CfgData
.ControlOption
;
597 Tcb
->Ttl
= CfgData
->Tcp6CfgData
.HopLimit
;
598 Tcb
->Tos
= CfgData
->Tcp6CfgData
.TrafficClass
;
600 IP6_COPY_ADDRESS (&Tcb
->LocalEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.StationAddress
);
601 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.StationPort
);
603 IP6_COPY_ADDRESS (&Tcb
->RemoteEnd
.Ip
, &CfgData
->Tcp6CfgData
.AccessPoint
.RemoteAddress
);
604 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->Tcp6CfgData
.AccessPoint
.RemotePort
);
607 // Type EFI_TCP4_OPTION and EFI_TCP6_OPTION are the same.
609 Option
= (EFI_TCP4_OPTION
*) CfgData
->Tcp6CfgData
.ControlOption
;
612 if (Option
!= NULL
) {
615 (UINT32
) (TCP_COMP_VAL (
616 TCP_RCV_BUF_SIZE_MIN
,
619 Option
->ReceiveBufferSize
625 (UINT32
) (TCP_COMP_VAL (
626 TCP_SND_BUF_SIZE_MIN
,
629 Option
->SendBufferSize
636 (UINT32
) (TCP_COMP_VAL (
640 Option
->MaxSynBackLog
645 Tcb
->MaxRexmit
= (UINT16
) TCP_COMP_VAL (
651 Tcb
->FinWait2Timeout
= TCP_COMP_VAL (
653 TCP_FIN_WAIT2_TIME_MAX
,
655 (UINT32
) (Option
->FinTimeout
* TCP_TICK_HZ
)
658 if (Option
->TimeWaitTimeout
!= 0) {
659 Tcb
->TimeWaitTimeout
= TCP_COMP_VAL (
661 TCP_TIME_WAIT_TIME_MAX
,
663 (UINT32
) (Option
->TimeWaitTimeout
* TCP_TICK_HZ
)
666 Tcb
->TimeWaitTimeout
= 0;
669 if (Option
->KeepAliveProbes
!= 0) {
670 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
672 Tcb
->MaxKeepAlive
= (UINT8
) TCP_COMP_VAL (
673 TCP_MAX_KEEPALIVE_MIN
,
676 Option
->KeepAliveProbes
678 Tcb
->KeepAliveIdle
= TCP_COMP_VAL (
679 TCP_KEEPALIVE_IDLE_MIN
,
680 TCP_KEEPALIVE_IDLE_MAX
,
681 TCP_KEEPALIVE_IDLE_MIN
,
682 (UINT32
) (Option
->KeepAliveTime
* TCP_TICK_HZ
)
684 Tcb
->KeepAlivePeriod
= TCP_COMP_VAL (
685 TCP_KEEPALIVE_PERIOD_MIN
,
686 TCP_KEEPALIVE_PERIOD
,
687 TCP_KEEPALIVE_PERIOD
,
688 (UINT32
) (Option
->KeepAliveInterval
* TCP_TICK_HZ
)
692 Tcb
->ConnectTimeout
= TCP_COMP_VAL (
693 TCP_CONNECT_TIME_MIN
,
696 (UINT32
) (Option
->ConnectionTimeout
* TCP_TICK_HZ
)
699 if (!Option
->EnableNagle
) {
700 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
703 if (!Option
->EnableTimeStamp
) {
704 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
707 if (!Option
->EnableWindowScaling
) {
708 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
713 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is
714 // determined, construct the IP device path and install it.
716 Status
= TcpInstallDevicePath (Sk
);
717 if (EFI_ERROR (Status
)) {
722 // update state of Tcb and socket
724 if (((Sk
->IpVersion
== IP_VERSION_4
) && !CfgData
->Tcp4CfgData
.AccessPoint
.ActiveFlag
) ||
725 ((Sk
->IpVersion
== IP_VERSION_6
) && !CfgData
->Tcp6CfgData
.AccessPoint
.ActiveFlag
)
728 TcpSetState (Tcb
, TCP_LISTEN
);
729 SockSetState (Sk
, SO_LISTENING
);
731 Sk
->ConfigureState
= SO_CONFIGURED_PASSIVE
;
734 Sk
->ConfigureState
= SO_CONFIGURED_ACTIVE
;
737 if (Sk
->IpVersion
== IP_VERSION_6
) {
738 Tcb
->Tick
= TCP6_REFRESH_NEIGHBOR_TICK
;
740 if (NetIp6IsUnspecifiedAddr (&Tcb
->RemoteEnd
.Ip
.v6
)) {
741 Tcb
->RemoteIpZero
= TRUE
;
753 The procotol handler provided to the socket layer, which is used to
754 dispatch the socket level requests by calling the corresponding
757 @param[in] Sock Pointer to the socket of this TCP instance.
758 @param[in] Request The code of this operation request.
759 @param[in] Data Pointer to the operation specific data passed in
760 together with the operation request. This is an
761 optional parameter that may be NULL.
763 @retval EFI_SUCCESS The socket request completed successfully.
764 @retval other The error status returned by the corresponding TCP
772 IN VOID
*Data OPTIONAL
776 TCP_PROTO_DATA
*ProtoData
;
778 ProtoData
= (TCP_PROTO_DATA
*) Sock
->ProtoReserved
;
779 Tcb
= ProtoData
->TcpPcb
;
783 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
784 ProtoData
->TcpService
->IpIo
->Ip
.Ip4
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip4
);
786 ProtoData
->TcpService
->IpIo
->Ip
.Ip6
->Poll (ProtoData
->TcpService
->IpIo
->Ip
.Ip6
);
793 // After user received data from socket buffer, socket will
794 // notify TCP using this message to give it a chance to send out
795 // window update information
797 ASSERT (Tcb
!= NULL
);
798 TcpOnAppConsume (Tcb
);
803 ASSERT (Tcb
!= NULL
);
820 Tcb
->SndPsh
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
);
821 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_PSH
);
826 Tcb
->SndUp
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
) - 1;
827 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_URG
);
833 TcpOnAppConnect (Tcb
);
839 return TcpAttachPcb (Sock
);
857 return TcpConfigurePcb (
859 (TCP_CONFIG_DATA
*) Data
866 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
));
868 if (Tcb
->Sk
->IpVersion
== IP_VERSION_4
) {
870 return Tcp4GetMode (Tcb
, (TCP4_MODE_DATA
*) Data
);
873 return Tcp6GetMode (Tcb
, (TCP6_MODE_DATA
*) Data
);
880 ASSERT ((Data
!= NULL
) && (Tcb
!= NULL
) && (Tcb
->Sk
->IpVersion
== IP_VERSION_4
));
882 return Tcp4Route (Tcb
, (TCP4_ROUTE_INFO
*) Data
);
886 return EFI_UNSUPPORTED
;