3 Copyright (c) 2005 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 #define TCP_COMP_VAL(Min, Max, Default, Val) \
24 ((((Val) <= (Max)) && ((Val) >= (Min))) ? (Val) : (Default))
30 IN TCP4_ROUTE_INFO
*RouteInfo
36 Add or remove a route entry in the IP route table associated
37 with this TCP instance.
41 Tcb - Pointer to the TCP_CB of this TCP instance.
42 RouteInfo - Pointer to the route info to be processed.
46 EFI_SUCCESS - The operation completed successfully.
47 EFI_NOT_STARTED - The driver instance has not been started.
48 EFI_NO_MAPPING - When using the default address, configuration(DHCP,
49 BOOTP, RARP, etc.) is not finished yet.
50 EFI_OUT_OF_RESOURCES - Could not add the entry to the routing table.
51 EFI_NOT_FOUND - This route is not in the routing table
52 (when RouteInfo->DeleteRoute is TRUE).
53 EFI_ACCESS_DENIED - The route is already defined in the routing table
54 (when RouteInfo->DeleteRoute is FALSE).
66 RouteInfo
->DeleteRoute
,
67 RouteInfo
->SubnetAddress
,
68 RouteInfo
->SubnetMask
,
69 RouteInfo
->GatewayAddress
76 Get the operational settings of this TCP instance.
78 @param Tcb Pointer to the TCP_CB of this TCP instance.
79 @param Mode Pointer to the buffer to store the operational
82 @retval EFI_SUCCESS The mode data is read.
83 @retval EFI_NOT_STARTED No configuration data is available because this
84 instance hasn't been started.
91 IN TCP4_MODE_DATA
*Mode
95 EFI_TCP4_CONFIG_DATA
*ConfigData
;
96 EFI_TCP4_ACCESS_POINT
*AccessPoint
;
97 EFI_TCP4_OPTION
*Option
;
102 if (!SOCK_IS_CONFIGURED (Sock
) && (Mode
->Tcp4ConfigData
!= NULL
)) {
103 return EFI_NOT_STARTED
;
106 if (Mode
->Tcp4State
) {
107 *(Mode
->Tcp4State
) = Tcb
->State
;
110 if (Mode
->Tcp4ConfigData
) {
112 ConfigData
= Mode
->Tcp4ConfigData
;
113 AccessPoint
= &(ConfigData
->AccessPoint
);
114 Option
= ConfigData
->ControlOption
;
116 ConfigData
->TypeOfService
= Tcb
->TOS
;
117 ConfigData
->TimeToLive
= Tcb
->TTL
;
119 AccessPoint
->UseDefaultAddress
= Tcb
->UseDefaultAddr
;
121 EFI_IP4 (AccessPoint
->StationAddress
) = Tcb
->LocalEnd
.Ip
;
122 AccessPoint
->SubnetMask
= Tcb
->SubnetMask
;
123 AccessPoint
->StationPort
= NTOHS (Tcb
->LocalEnd
.Port
);
125 EFI_IP4 (AccessPoint
->RemoteAddress
) = Tcb
->RemoteEnd
.Ip
;
126 AccessPoint
->RemotePort
= NTOHS (Tcb
->RemoteEnd
.Port
);
127 AccessPoint
->ActiveFlag
= (BOOLEAN
) (Tcb
->State
!= TCP_LISTEN
);
129 if (Option
!= NULL
) {
130 Option
->ReceiveBufferSize
= GET_RCV_BUFFSIZE (Tcb
->Sk
);
131 Option
->SendBufferSize
= GET_SND_BUFFSIZE (Tcb
->Sk
);
132 Option
->MaxSynBackLog
= GET_BACKLOG (Tcb
->Sk
);
134 Option
->ConnectionTimeout
= Tcb
->ConnectTimeout
/ TCP_TICK_HZ
;
135 Option
->DataRetries
= Tcb
->MaxRexmit
;
136 Option
->FinTimeout
= Tcb
->FinWait2Timeout
/ TCP_TICK_HZ
;
137 Option
->TimeWaitTimeout
= Tcb
->TimeWaitTimeout
/ TCP_TICK_HZ
;
138 Option
->KeepAliveProbes
= Tcb
->MaxKeepAlive
;
139 Option
->KeepAliveTime
= Tcb
->KeepAliveIdle
/ TCP_TICK_HZ
;
140 Option
->KeepAliveInterval
= Tcb
->KeepAlivePeriod
/ TCP_TICK_HZ
;
142 Option
->EnableNagle
= !TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
143 Option
->EnableTimeStamp
= !TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
144 Option
->EnableWindowScaling
= !TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
146 Option
->EnableSelectiveAck
= FALSE
;
147 Option
->EnablePathMtuDiscovery
= FALSE
;
151 Ip
= Tcb
->IpInfo
->Ip
;
154 return Ip
->GetModeData (Ip
, Mode
->Ip4ModeData
, Mode
->MnpConfigData
, Mode
->SnpModeData
);
159 If AP->StationPort isn't zero, check whether the access point
160 is registered, else generate a random station port for this
163 @param AP Pointer to the access point.
165 @retval EFI_SUCCESS The check is passed or the port is assigned.
166 @retval EFI_INVALID_PARAMETER The non-zero station port is already used.
167 @retval EFI_OUT_OF_RESOURCES No port can be allocated.
173 IN EFI_TCP4_ACCESS_POINT
*AP
178 if (0 != AP
->StationPort
) {
180 // check if a same endpoint is bound
182 if (TcpFindTcbByPeer (&AP
->StationAddress
, AP
->StationPort
)) {
184 return EFI_INVALID_PARAMETER
;
188 // generate a random port
192 if (TCP4_PORT_USER_RESERVED
== mTcp4RandomPort
) {
193 mTcp4RandomPort
= TCP4_PORT_KNOWN
;
198 while (TcpFindTcbByPeer (&AP
->StationAddress
, mTcp4RandomPort
)) {
202 if (mTcp4RandomPort
<= TCP4_PORT_KNOWN
) {
205 TCP4_DEBUG_ERROR (("Tcp4Bind: no port can be allocated "
208 return EFI_OUT_OF_RESOURCES
;
211 mTcp4RandomPort
= TCP4_PORT_KNOWN
+ 1;
218 AP
->StationPort
= mTcp4RandomPort
;
226 Flush the Tcb add its associated protocols..
228 @param Tcb Pointer to the TCP_CB to be flushed.
230 @retval EFI_SUCCESS The operation is completed successfully.
240 TCP4_PROTO_DATA
*TcpProto
;
242 IpIoConfigIp (Tcb
->IpInfo
, NULL
);
245 TcpProto
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
247 if (SOCK_IS_CONFIGURED (Sock
)) {
248 NetListRemoveEntry (&Tcb
->List
);
250 TcpSetVariableData (TcpProto
->TcpService
);
253 NetbufFreeList (&Tcb
->SndQue
);
254 NetbufFreeList (&Tcb
->RcvQue
);
264 TCP4_PROTO_DATA
*ProtoData
;
267 Tcb
= NetAllocateZeroPool (sizeof (TCP_CB
));
271 TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: failed to allocate a TCB\n"));
273 return EFI_OUT_OF_RESOURCES
;
276 ProtoData
= (TCP4_PROTO_DATA
*) Sk
->ProtoReserved
;
277 IpIo
= ProtoData
->TcpService
->IpIo
;
280 // Create an IpInfo for this Tcb.
282 Tcb
->IpInfo
= IpIoAddIp (IpIo
);
283 if (Tcb
->IpInfo
== NULL
) {
286 return EFI_OUT_OF_RESOURCES
;
289 NetListInit (&Tcb
->List
);
290 NetListInit (&Tcb
->SndQue
);
291 NetListInit (&Tcb
->RcvQue
);
293 Tcb
->State
= TCP_CLOSED
;
295 ProtoData
->TcpPcb
= Tcb
;
306 TCP4_PROTO_DATA
*ProtoData
;
309 ProtoData
= (TCP4_PROTO_DATA
*) Sk
->ProtoReserved
;
310 Tcb
= ProtoData
->TcpPcb
;
312 ASSERT (Tcb
!= NULL
);
316 IpIoRemoveIp (ProtoData
->TcpService
->IpIo
, Tcb
->IpInfo
);
320 ProtoData
->TcpPcb
= NULL
;
325 Configure the Tcb using CfgData.
327 @param Sk Pointer to the socket of this TCP instance.
328 @param SkTcb Pointer to the TCP_CB of this TCP instance.
329 @param CfgData Pointer to the TCP configuration data.
331 @retval EFI_SUCCESS The operation is completed successfully.
332 @retval EFI_INVALID_PARAMETER A same access point has been configured in
333 another TCP instance.
334 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
341 IN EFI_TCP4_CONFIG_DATA
*CfgData
345 EFI_IP4_CONFIG_DATA IpCfgData
;
347 EFI_TCP4_OPTION
*Option
;
348 TCP4_PROTO_DATA
*TcpProto
;
351 ASSERT (CfgData
&& Sk
&& Sk
->SockHandle
);
353 TcpProto
= (TCP4_PROTO_DATA
*) Sk
->ProtoReserved
;
354 Tcb
= TcpProto
->TcpPcb
;
355 IpIo
= TcpProto
->TcpService
->IpIo
;
357 ASSERT (Tcb
!= NULL
);
360 // Add Ip for send pkt to the peer
362 IpCfgData
= mIpIoDefaultIpConfigData
;
363 IpCfgData
.DefaultProtocol
= EFI_IP_PROTO_TCP
;
364 IpCfgData
.UseDefaultAddress
= CfgData
->AccessPoint
.UseDefaultAddress
;
365 IpCfgData
.StationAddress
= CfgData
->AccessPoint
.StationAddress
;
366 IpCfgData
.SubnetMask
= CfgData
->AccessPoint
.SubnetMask
;
367 IpCfgData
.ReceiveTimeout
= (UINT32
) (-1);
370 // Configure the IP instance this Tcb consumes.
372 Status
= IpIoConfigIp (Tcb
->IpInfo
, &IpCfgData
);
373 if (EFI_ERROR (Status
)) {
378 // Get the default address info if the instance is configured to use default address.
380 if (CfgData
->AccessPoint
.UseDefaultAddress
) {
381 CfgData
->AccessPoint
.StationAddress
= IpCfgData
.StationAddress
;
382 CfgData
->AccessPoint
.SubnetMask
= IpCfgData
.SubnetMask
;
386 // check if we can bind this endpoint in CfgData
388 Status
= Tcp4Bind (&(CfgData
->AccessPoint
));
390 if (EFI_ERROR (Status
)) {
391 TCP4_DEBUG_ERROR (("Tcp4ConfigurePcb: Bind endpoint failed "
392 "with %r\n", Status
));
398 // Initalize the operating information in this Tcb
400 ASSERT (Tcb
->State
== TCP_CLOSED
&&
401 NetListIsEmpty (&Tcb
->SndQue
) &&
402 NetListIsEmpty (&Tcb
->RcvQue
));
404 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
405 Tcb
->State
= TCP_CLOSED
;
408 Tcb
->RcvMss
= TcpGetRcvMss (Sk
);
411 Tcb
->Rto
= 3 * TCP_TICK_HZ
;
413 Tcb
->CWnd
= Tcb
->SndMss
;
414 Tcb
->Ssthresh
= 0xffffffff;
416 Tcb
->CongestState
= TCP_CONGEST_OPEN
;
418 Tcb
->KeepAliveIdle
= TCP_KEEPALIVE_IDLE_MIN
;
419 Tcb
->KeepAlivePeriod
= TCP_KEEPALIVE_PERIOD
;
420 Tcb
->MaxKeepAlive
= TCP_MAX_KEEPALIVE
;
421 Tcb
->MaxRexmit
= TCP_MAX_LOSS
;
422 Tcb
->FinWait2Timeout
= TCP_FIN_WAIT2_TIME
;
423 Tcb
->TimeWaitTimeout
= TCP_TIME_WAIT_TIME
;
424 Tcb
->ConnectTimeout
= TCP_CONNECT_TIME
;
427 // initialize Tcb in the light of CfgData
429 Tcb
->TTL
= CfgData
->TimeToLive
;
430 Tcb
->TOS
= CfgData
->TypeOfService
;
432 Tcb
->LocalEnd
.Ip
= EFI_IP4 (CfgData
->AccessPoint
.StationAddress
);
433 Tcb
->LocalEnd
.Port
= HTONS (CfgData
->AccessPoint
.StationPort
);
434 Tcb
->SubnetMask
= CfgData
->AccessPoint
.SubnetMask
;
436 Tcb
->RemoteEnd
.Ip
= EFI_IP4 (CfgData
->AccessPoint
.RemoteAddress
);
437 Tcb
->RemoteEnd
.Port
= HTONS (CfgData
->AccessPoint
.RemotePort
);
439 Option
= CfgData
->ControlOption
;
441 if (Option
!= NULL
) {
444 TCP_COMP_VAL (TCP_RCV_BUF_SIZE_MIN
,
447 Option
->ReceiveBufferSize
)
451 TCP_COMP_VAL (TCP_SND_BUF_SIZE_MIN
,
454 Option
->SendBufferSize
)
459 TCP_COMP_VAL (TCP_BACKLOG_MIN
,
462 Option
->MaxSynBackLog
)
465 Tcb
->MaxRexmit
= (UINT16
) TCP_COMP_VAL (
471 Tcb
->FinWait2Timeout
= TCP_COMP_VAL (
473 TCP_FIN_WAIT2_TIME_MAX
,
475 Option
->FinTimeout
* TCP_TICK_HZ
478 if (Option
->TimeWaitTimeout
!= 0) {
479 Tcb
->TimeWaitTimeout
= TCP_COMP_VAL (
481 TCP_TIME_WAIT_TIME_MAX
,
483 Option
->TimeWaitTimeout
* TCP_TICK_HZ
486 Tcb
->TimeWaitTimeout
= 0;
489 if (Option
->KeepAliveProbes
!= 0) {
490 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
);
492 Tcb
->MaxKeepAlive
= (UINT8
) TCP_COMP_VAL (
493 TCP_MAX_KEEPALIVE_MIN
,
496 Option
->KeepAliveProbes
498 Tcb
->KeepAliveIdle
= TCP_COMP_VAL (
499 TCP_KEEPALIVE_IDLE_MIN
,
500 TCP_KEEPALIVE_IDLE_MAX
,
501 TCP_KEEPALIVE_IDLE_MIN
,
502 Option
->KeepAliveTime
* TCP_TICK_HZ
504 Tcb
->KeepAlivePeriod
= TCP_COMP_VAL (
505 TCP_KEEPALIVE_PERIOD_MIN
,
506 TCP_KEEPALIVE_PERIOD
,
507 TCP_KEEPALIVE_PERIOD
,
508 Option
->KeepAliveInterval
* TCP_TICK_HZ
512 Tcb
->ConnectTimeout
= TCP_COMP_VAL (
513 TCP_CONNECT_TIME_MIN
,
516 Option
->ConnectionTimeout
* TCP_TICK_HZ
519 if (Option
->EnableNagle
== FALSE
) {
520 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_NAGLE
);
523 if (Option
->EnableTimeStamp
== FALSE
) {
524 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_TS
);
527 if (Option
->EnableWindowScaling
== FALSE
) {
528 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_NO_WS
);
533 // update state of Tcb and socket
535 if (CfgData
->AccessPoint
.ActiveFlag
== FALSE
) {
537 TcpSetState (Tcb
, TCP_LISTEN
);
538 SockSetState (Sk
, SO_LISTENING
);
540 Sk
->ConfigureState
= SO_CONFIGURED_PASSIVE
;
543 Sk
->ConfigureState
= SO_CONFIGURED_ACTIVE
;
555 The procotol handler provided to the socket layer, used to
556 dispatch the socket level requests by calling the corresponding
559 @param Sock Pointer to the socket of this TCP instance.
560 @param Request The code of this operation request.
561 @param Data Pointer to the operation specific data passed in
562 together with the operation request.
564 @retval EFI_SUCCESS The socket request is completed successfully.
565 @retval other The error status returned by the corresponding TCP
572 IN SOCK_REQUEST Request
,
573 IN VOID
*Data OPTIONAL
577 TCP4_PROTO_DATA
*ProtoData
;
578 EFI_IP4_PROTOCOL
*Ip
;
580 ProtoData
= (TCP4_PROTO_DATA
*) Sock
->ProtoReserved
;
581 Tcb
= ProtoData
->TcpPcb
;
585 Ip
= ProtoData
->TcpService
->IpIo
->Ip
;
591 // After user received data from socket buffer, socket will
592 // notify TCP using this message to give it a chance to send out
593 // window update information
596 TcpOnAppConsume (Tcb
);
618 Tcb
->SndPsh
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
);
619 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_PSH
);
624 Tcb
->SndUp
= TcpGetMaxSndNxt (Tcb
) + GET_SND_DATASIZE (Tcb
->Sk
) - 1;
625 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_SND_URG
);
631 TcpOnAppConnect (Tcb
);
637 return Tcp4AttachPcb (Sock
);
649 Tcp4DetachPcb (Sock
);
655 return Tcp4ConfigurePcb (
657 (EFI_TCP4_CONFIG_DATA
*) Data
664 ASSERT (Data
&& Tcb
);
666 return Tcp4GetMode (Tcb
, (TCP4_MODE_DATA
*) Data
);
672 ASSERT (Data
&& Tcb
);
674 return Tcp4Route (Tcb
, (TCP4_ROUTE_INFO
*) Data
);