/* tcp_timer.c 4.32 83/05/27 */
#include "../h/socketvar.h"
#include "../h/protosw.h"
#include "../net/route.h"
#include "../netinet/in.h"
#include "../netinet/in_pcb.h"
#include "../netinet/in_systm.h"
#include "../netinet/ip.h"
#include "../netinet/ip_var.h"
#include "../netinet/tcp.h"
#include "../netinet/tcp_fsm.h"
#include "../netinet/tcp_seq.h"
#include "../netinet/tcp_timer.h"
#include "../netinet/tcp_var.h"
#include "../netinet/tcpip.h"
* Fast timeout routine for processing delayed acks
register struct inpcb
*inp
;
register struct tcpcb
*tp
;
for (; inp
!= &tcb
; inp
= inp
->inp_next
)
if ((tp
= (struct tcpcb
*)inp
->inp_ppcb
) &&
(tp
->t_flags
& TF_DELACK
)) {
tp
->t_flags
&= ~TF_DELACK
;
tp
->t_flags
|= TF_ACKNOW
;
* Tcp protocol timeout routine called every 500 ms.
* Updates the timers in all active tcb's and
* causes finite state machine actions if timers expire.
register struct inpcb
*ip
, *ipnxt
;
register struct tcpcb
*tp
;
* Search through tcb's and update active timers.
for (i
= 0; i
< TCPT_NTIMERS
; i
++) {
if (tp
->t_timer
[i
] && --tp
->t_timer
[i
] == 0) {
(void) tcp_usrreq(tp
->t_inpcb
->inp_socket
,
PRU_SLOWTIMO
, (struct mbuf
*)0,
(struct mbuf
*)i
, (struct mbuf
*)0);
if (ipnxt
->inp_prev
!= ip
)
tcp_iss
+= TCP_ISSINCR
/PR_SLOWHZ
; /* increment iss */
* Cancel all timers for TCP tp.
for (i
= 0; i
< TCPT_NTIMERS
; i
++)
float tcp_backoff
[TCP_MAXRXTSHIFT
] =
{ 1.0, 1.2, 1.4, 1.7, 2.0, 3.0, 5.0, 8.0, 16.0, 32.0 };
int tcpexprexmtbackoff
= 0;
register struct tcpcb
*tp
;
* 2 MSL timeout in shutdown went off. Delete connection
* Retransmission timer went off. Message has not
* been acked within retransmit interval. Back off
* to a longer retransmit interval and retransmit all
* unacknowledged messages in the window.
if (tp
->t_rxtshift
> TCP_MAXRXTSHIFT
) {
tp
= tcp_drop(tp
, ETIMEDOUT
);
TCPT_RANGESET(tp
->t_timer
[TCPT_REXMT
],
(int)tp
->t_srtt
, TCPTV_MIN
, TCPTV_MAX
);
if (tcpexprexmtbackoff
) {
TCPT_RANGESET(tp
->t_timer
[TCPT_REXMT
],
tp
->t_timer
[TCPT_REXMT
] << tp
->t_rxtshift
,
TCPT_RANGESET(tp
->t_timer
[TCPT_REXMT
],
tp
->t_timer
[TCPT_REXMT
] *
tcp_backoff
[tp
->t_rxtshift
- 1],
tp
->snd_nxt
= tp
->snd_una
;
/* this only transmits one segment! */
* Persistance timer into zero window.
* Force a byte to be output, if possible.
* Keep-alive timer went off; send something
* or drop connection if idle for too long.
if (tp
->t_state
< TCPS_ESTABLISHED
)
if (tp
->t_inpcb
->inp_socket
->so_options
& SO_KEEPALIVE
) {
if (tp
->t_idle
>= TCPTV_MAXIDLE
)
* Saying tp->rcv_nxt-1 lies about what
* we have received, and by the protocol spec
* requires the correspondent TCP to respond.
* Saying tp->snd_una-1 causes the transmitted
* byte to lie outside the receive window; this
* is important because we don't necessarily
* have a byte in the window to send (consider
tp
->t_template
, tp
->rcv_nxt
-1, tp
->snd_una
-1, 0);
tp
->t_timer
[TCPT_KEEP
] = TCPTV_KEEP
;
tp
= tcp_drop(tp
, ETIMEDOUT
);