3 Copyright (c) 2005 - 2007, 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.
18 TCP timer related functions.
25 UINT32 mTcpTick
= 1000;
28 Connect timeout handler.
30 @param Tcb Pointer to the TCP_CB of this TCP instance.
39 Timeout handler for TCP retransmission timer.
41 @param Tcb Pointer to the TCP_CB of this TCP instance.
50 Timeout handler for window probe timer.
52 @param Tcb Pointer to the TCP_CB of this TCP instance.
61 Timeout handler for keepalive timer.
63 @param Tcb Pointer to the TCP_CB of this TCP instance.
72 Timeout handler for FIN_WAIT_2 timer.
74 @param Tcb Pointer to the TCP_CB of this TCP instance.
83 Timeout handler for 2MSL timer.
85 @param Tcb Pointer to the TCP_CB of this TCP instance.
93 TCP_TIMER_HANDLER mTcpTimerHandler
[TCP_TIMER_NUMBER
] = {
103 Close the TCP connection.
105 @param Tcb Pointer to the TCP_CB of this TCP instance.
113 NetbufFreeList (&Tcb
->SndQue
);
114 NetbufFreeList (&Tcb
->RcvQue
);
116 TcpSetState (Tcb
, TCP_CLOSED
);
121 Connect timeout handler.
123 @param Tcb Pointer to the TCP_CB of this TCP instance.
131 if (!TCP_CONNECTED (Tcb
->State
)) {
132 DEBUG ((EFI_D_ERROR
, "TcpConnectTimeout: connection closed "
133 "because conenction timer timeout for TCB %p\n", Tcb
));
135 if (EFI_ABORTED
== Tcb
->Sk
->SockError
) {
136 SOCK_ERROR (Tcb
->Sk
, EFI_TIMEOUT
);
139 if (TCP_SYN_RCVD
== Tcb
->State
) {
140 DEBUG ((EFI_D_WARN
, "TcpConnectTimeout: send reset because "
141 "connection timer timeout for TCB %p\n", Tcb
));
143 TcpResetConnection (Tcb
);
153 Timeout handler for TCP retransmission timer.
155 @param Tcb Pointer to the TCP_CB of this TCP instance.
165 DEBUG ((EFI_D_WARN
, "TcpRexmitTimeout: transmission "
166 "timeout for TCB %p\n", Tcb
));
169 // Set the congestion window. FlightSize is the
170 // amount of data that has been sent but not
173 FlightSize
= TCP_SUB_SEQ (Tcb
->SndNxt
, Tcb
->SndUna
);
174 Tcb
->Ssthresh
= MAX ((UINT32
) (2 * Tcb
->SndMss
), FlightSize
/ 2);
176 Tcb
->CWnd
= Tcb
->SndMss
;
177 Tcb
->LossRecover
= Tcb
->SndNxt
;
180 if ((Tcb
->LossTimes
> Tcb
->MaxRexmit
) &&
181 !TCP_TIMER_ON (Tcb
->EnabledTimer
, TCP_TIMER_CONNECT
)) {
183 DEBUG ((EFI_D_ERROR
, "TcpRexmitTimeout: connection closed "
184 "because too many timeouts for TCB %p\n", Tcb
));
186 if (EFI_ABORTED
== Tcb
->Sk
->SockError
) {
187 SOCK_ERROR (Tcb
->Sk
, EFI_TIMEOUT
);
195 TcpRetransmit (Tcb
, Tcb
->SndUna
);
196 TcpSetTimer (Tcb
, TCP_TIMER_REXMIT
, Tcb
->Rto
);
198 Tcb
->CongestState
= TCP_CONGEST_LOSS
;
199 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_RTT_ON
);
204 Timeout handler for window probe timer.
206 @param Tcb Pointer to the TCP_CB of this TCP instance.
215 // This is the timer for sender's SWSA. RFC1122 requires
216 // a timer set for sender's SWSA, and suggest combine it
217 // with window probe timer. If data is sent, don't set
218 // the probe timer, since retransmit timer is on.
220 if ((TcpDataToSend (Tcb
, 1) != 0) && (TcpToSendData (Tcb
, 1) > 0)) {
222 ASSERT (TCP_TIMER_ON (Tcb
->EnabledTimer
, TCP_TIMER_REXMIT
));
226 TcpSendZeroProbe (Tcb
);
227 TcpSetProbeTimer (Tcb
);
232 Timeout handler for keepalive timer.
234 @param Tcb Pointer to the TCP_CB of this TCP instance.
238 TcpKeepaliveTimeout (
242 Tcb
->KeepAliveProbes
++;
245 // Too many Keep-alive probes, drop the connection
247 if (Tcb
->KeepAliveProbes
> Tcb
->MaxKeepAlive
) {
249 if (EFI_ABORTED
== Tcb
->Sk
->SockError
) {
250 SOCK_ERROR (Tcb
->Sk
, EFI_TIMEOUT
);
257 TcpSendZeroProbe (Tcb
);
258 TcpSetKeepaliveTimer (Tcb
);
263 Timeout handler for FIN_WAIT_2 timer.
265 @param Tcb Pointer to the TCP_CB of this TCP instance.
273 DEBUG ((EFI_D_WARN
, "TcpFinwait2Timeout: connection closed "
274 "because FIN_WAIT2 timer timeouts for TCB %p\n", Tcb
));
281 Timeout handler for 2MSL timer.
283 @param Tcb Pointer to the TCP_CB of this TCP instance.
291 DEBUG ((EFI_D_WARN
, "Tcp2MSLTimeout: connection closed "
292 "because TIME_WAIT timer timeouts for TCB %p\n", Tcb
));
299 Update the timer status and the next expire time according to the timers
300 to expire in a specific future time slot.
302 @param Tcb Pointer to the TCP_CB of this TCP instance.
313 // Don't use a too large value to init NextExpire
314 // since mTcpTick wraps around as sequence no does.
316 Tcb
->NextExpire
= 65535;
317 TCP_CLEAR_FLG (Tcb
->CtrlFlag
, TCP_CTRL_TIMER_ON
);
319 for (Index
= 0; Index
< TCP_TIMER_NUMBER
; Index
++) {
321 if (TCP_TIMER_ON (Tcb
->EnabledTimer
, Index
) &&
322 TCP_TIME_LT (Tcb
->Timer
[Index
], mTcpTick
+ Tcb
->NextExpire
)) {
324 Tcb
->NextExpire
= TCP_SUB_TIME (Tcb
->Timer
[Index
], mTcpTick
);
325 TCP_SET_FLG (Tcb
->CtrlFlag
, TCP_CTRL_TIMER_ON
);
334 @param Tcb Pointer to the TCP_CB of this TCP instance.
335 @param Timer The index of the timer to be enabled.
336 @param TimeOut The timeout value of this timer.
346 TCP_SET_TIMER (Tcb
->EnabledTimer
, Timer
);
347 Tcb
->Timer
[Timer
] = mTcpTick
+ TimeOut
;
349 TcpUpdateTimer (Tcb
);
356 @param Tcb Pointer to the TCP_CB of this TCP instance.
357 @param Timer The index of the timer to be cleared.
366 TCP_CLEAR_TIMER (Tcb
->EnabledTimer
, Timer
);
367 TcpUpdateTimer (Tcb
);
372 Clear all TCP timers.
374 @param Tcb Pointer to the TCP_CB of this TCP instance.
382 Tcb
->EnabledTimer
= 0;
383 TcpUpdateTimer (Tcb
);
388 Enable the window prober timer and set the timeout value.
390 @param Tcb Pointer to the TCP_CB of this TCP instance.
398 if (!TCP_TIMER_ON (Tcb
->EnabledTimer
, TCP_TIMER_PROBE
)) {
399 Tcb
->ProbeTime
= Tcb
->Rto
;
402 Tcb
->ProbeTime
<<= 1;
405 if (Tcb
->ProbeTime
< TCP_RTO_MIN
) {
407 Tcb
->ProbeTime
= TCP_RTO_MIN
;
408 } else if (Tcb
->ProbeTime
> TCP_RTO_MAX
) {
410 Tcb
->ProbeTime
= TCP_RTO_MAX
;
413 TcpSetTimer (Tcb
, TCP_TIMER_PROBE
, Tcb
->ProbeTime
);
418 Enable the keepalive timer and set the timeout value.
420 @param Tcb Pointer to the TCP_CB of this TCP instance.
424 TcpSetKeepaliveTimer (
428 if (TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_NO_KEEPALIVE
)) {
434 // Set the timer to KeepAliveIdle if either
435 // 1. the keepalive timer is off
436 // 2. The keepalive timer is on, but the idle
437 // is less than KeepAliveIdle, that means the
438 // connection is alive since our last probe.
440 if (!TCP_TIMER_ON (Tcb
->EnabledTimer
, TCP_TIMER_KEEPALIVE
) ||
441 (Tcb
->Idle
< Tcb
->KeepAliveIdle
)) {
443 TcpSetTimer (Tcb
, TCP_TIMER_KEEPALIVE
, Tcb
->KeepAliveIdle
);
444 Tcb
->KeepAliveProbes
= 0;
448 TcpSetTimer (Tcb
, TCP_TIMER_KEEPALIVE
, Tcb
->KeepAlivePeriod
);
456 @param Tcb Pointer to the TCP_CB of this TCP instance.
465 // Fold the RTT estimate if too many times, the estimate
466 // may be wrong, fold it. So the next time a valid
467 // measurement is sampled, we can start fresh.
469 if ((Tcb
->LossTimes
>= TCP_FOLD_RTT
) && (Tcb
->SRtt
!= 0)) {
470 Tcb
->RttVar
+= Tcb
->SRtt
>> 2;
476 if (Tcb
->Rto
< TCP_RTO_MIN
) {
478 Tcb
->Rto
= TCP_RTO_MIN
;
479 } else if (Tcb
->Rto
> TCP_RTO_MAX
) {
481 Tcb
->Rto
= TCP_RTO_MAX
;
487 Heart beat timer handler.
489 @param Context Context of the timer event, ignored.
504 mTcpGlobalIss
+= 100;
507 // Don't use LIST_FOR_EACH, which isn't delete safe.
509 for (Entry
= mTcpRunQue
.ForwardLink
; Entry
!= &mTcpRunQue
; Entry
= Next
) {
511 Next
= Entry
->ForwardLink
;
513 Tcb
= NET_LIST_USER_STRUCT (Entry
, TCP_CB
, List
);
515 if (Tcb
->State
== TCP_CLOSED
) {
519 // The connection is doing RTT measurement.
521 if (TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_RTT_ON
)) {
527 if (Tcb
->DelayedAck
!= 0) {
532 // No timer is active or no timer expired
534 if (!TCP_FLG_ON (Tcb
->CtrlFlag
, TCP_CTRL_TIMER_ON
) ||
535 ((--Tcb
->NextExpire
) > 0)) {
541 // Call the timeout handler for each expired timer.
543 for (Index
= 0; Index
< TCP_TIMER_NUMBER
; Index
++) {
545 if (TCP_TIMER_ON (Tcb
->EnabledTimer
, Index
) &&
546 TCP_TIME_LEQ (Tcb
->Timer
[Index
], mTcpTick
)) {
548 // disable the timer before calling the handler
549 // in case the handler enables it again.
551 TCP_CLEAR_TIMER (Tcb
->EnabledTimer
, Index
);
552 mTcpTimerHandler
[Index
](Tcb
);
555 // The Tcb may have been deleted by the timer, or
556 // no other timer is set.
558 if ((Next
->BackLink
!= Entry
) ||
559 (Tcb
->EnabledTimer
== 0)) {
566 TcpUpdateTimer (Tcb
);
573 Heart beat timer handler, queues the DPC at TPL_CALLBACK.
575 @param Event Timer event signaled, ignored.
576 @param Context Context of the timer event, ignored.
586 NetLibQueueDpc (TPL_CALLBACK
, TcpTickingDpc
, Context
);