date and time created 81/11/24 17:35:58 by wnj
[unix-history] / usr / src / sys / netinet / tcp_timer.c
CommitLineData
f03530e6
BJ
1/* tcp_timer.c 4.1 81/11/24 */
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/mbuf.h"
6#include "../h/socket.h"
7#include "../h/socketvar.h"
8#include "../h/protosw.h"
9#include "../net/inet.h"
10#include "../net/inet_pcb.h"
11#include "../net/inet_systm.h"
12#include "../net/if.h"
13#include "../net/imp.h"
14#include "../net/ip.h"
15#include "../net/ip_var.h"
16#include "../net/tcp.h"
17#include "../net/tcp_fsm.h"
18#include "../net/tcp_var.h"
19#include "/usr/include/errno.h"
20
21/*
22 * Fast timeout routine for processing delayed acks
23 */
24tcp_fasttimo()
25{
26
27}
28
29/*
30 * Tcp protocol timeout routine called every 500 ms.
31 * Updates the timers in all active tcb's and
32 * causes finite state machine actions if timers expire.
33 */
34tcp_slowtimo()
35{
36 register struct inpcb *ip;
37 register struct tcpcb *tp;
38 int s = splnet();
39 register short *tmp;
40 register int i;
41COUNT(TCP_TIMEO);
42
43 /*
44 * Search through tcb's and update active timers.
45 */
46 for (ip = tcb.inp_next; ip != &tcb; ip = ip->inp_next) {
47 tp = intotcpcb(ip);
48 tmp = &tp->t_init;
49 for (i = 0; i < TNTIMERS; i++) {
50 if (*tmp && --*tmp == 0)
51 (void) tcp_usrreq(tp->t_inpcb->inp_socket,
52 PRU_SLOWTIMO, (struct mbuf *)0,
53 (caddr_t)i);
54 tmp++;
55 }
56 tp->t_xmt++;
57 }
58 tcp_iss += ISSINCR/2; /* increment iss */
59 splx(s);
60}
61
62/*
63 * Cancel all timers for tcp tp.
64 */
65tcp_tcancel(tp)
66 struct tcpcb *tp;
67{
68 register short *tmp = &tp->t_init;
69 register int i;
70
71 for (i = 0; i < TNTIMERS; i++)
72 *tmp++ = 0;
73}
74
75/*
76 * TCP timer went off processing.
77 */
78tcp_timers(tp, timertype)
79 register struct tcpcb *tp;
80 int timertype;
81{
82
83COUNT(TCP_TIMERS);
84 switch (timertype) {
85
86 case TFINACK: /* fin-ack timer */
87 switch (tp->t_state) {
88
89 case TIME_WAIT:
90 /*
91 * We can be sure our ACK of foreign FIN was rcvd,
92 * and can close if no data left for user.
93 */
94 if (rcv_empty(tp)) {
95 tcp_disconnect(tp);
96 return (CLOSED);
97 }
98 return (RCV_WAIT); /* 17 */
99
100 case CLOSING:
101 tp->tc_flags |= TC_WAITED_2_ML;
102 return (SAME);
103
104 default:
105 return (SAME);
106 }
107
108 case TREXMT: /* retransmission timer */
109 if (tp->t_rexmt_val > tp->snd_una) { /* 34 */
110 /*
111 * Set so for a retransmission, increase rexmt time
112 * in case of multiple retransmissions.
113 */
114 tp->snd_nxt = tp->snd_una;
115 tp->tc_flags |= TC_REXMT;
116 tp->t_xmtime = tp->t_xmtime << 1;
117 if (tp->t_xmtime > T_REMAX)
118 tp->t_xmtime = T_REMAX;
119 (void) tcp_send(tp);
120 }
121 return (SAME);
122
123 case TREXMTTL: /* retransmit too long */
124 if (tp->t_rtl_val > tp->snd_una) { /* 36 */
125 tcp_error(tp, ETIMEDOUT);
126 return (CLOSED);
127 }
128 return (SAME);
129
130 case TPERSIST: /* persist timer */
131 /*
132 * Force a byte send through closed window.
133 */
134 tp->tc_flags |= TC_FORCE_ONE;
135 (void) tcp_send(tp);
136 return (SAME);
137 }
138 panic("tcp_timers");
139 /*NOTREACHED*/
140}