Commit | Line | Data |
---|---|---|
1e977657 | 1 | /* tcp_timer.c 4.16 82/03/15 */ |
f03530e6 BJ |
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" | |
0974b45c BJ |
9 | #include "../net/in.h" |
10 | #include "../net/in_pcb.h" | |
11 | #include "../net/in_systm.h" | |
f03530e6 | 12 | #include "../net/if.h" |
f03530e6 BJ |
13 | #include "../net/ip.h" |
14 | #include "../net/ip_var.h" | |
15 | #include "../net/tcp.h" | |
16 | #include "../net/tcp_fsm.h" | |
0974b45c BJ |
17 | #include "../net/tcp_seq.h" |
18 | #include "../net/tcp_timer.h" | |
f03530e6 | 19 | #include "../net/tcp_var.h" |
0974b45c | 20 | #include "../net/tcpip.h" |
f1b2fa5b | 21 | #include "../errno.h" |
f03530e6 | 22 | |
8b5a83bb | 23 | int tcpnodelack = 0; |
f03530e6 BJ |
24 | /* |
25 | * Fast timeout routine for processing delayed acks | |
26 | */ | |
27 | tcp_fasttimo() | |
28 | { | |
b8b9174f BJ |
29 | register struct inpcb *inp; |
30 | register struct tcpcb *tp; | |
31 | int s = splnet(); | |
0974b45c | 32 | COUNT(TCP_FASTTIMO); |
b8b9174f | 33 | |
fd5dc5f0 BJ |
34 | inp = tcb.inp_next; |
35 | if (inp) | |
36 | for (; inp != &tcb; inp = inp->inp_next) | |
b8b9174f BJ |
37 | if ((tp = (struct tcpcb *)inp->inp_ppcb) && |
38 | (tp->t_flags & TF_DELACK)) { | |
39 | tp->t_flags &= ~TF_DELACK; | |
40 | tp->t_flags |= TF_ACKNOW; | |
41 | (void) tcp_output(tp); | |
42 | } | |
43 | splx(s); | |
f03530e6 BJ |
44 | } |
45 | ||
46 | /* | |
47 | * Tcp protocol timeout routine called every 500 ms. | |
48 | * Updates the timers in all active tcb's and | |
49 | * causes finite state machine actions if timers expire. | |
50 | */ | |
51 | tcp_slowtimo() | |
52 | { | |
1e977657 | 53 | register struct inpcb *ip, *ipnxt; |
f03530e6 BJ |
54 | register struct tcpcb *tp; |
55 | int s = splnet(); | |
f03530e6 | 56 | register int i; |
0974b45c | 57 | COUNT(TCP_SLOWTIMO); |
f03530e6 BJ |
58 | |
59 | /* | |
60 | * Search through tcb's and update active timers. | |
61 | */ | |
4aed14e3 BJ |
62 | ip = tcb.inp_next; |
63 | if (ip == 0) { | |
64 | splx(s); | |
65 | return; | |
66 | } | |
1e977657 | 67 | while (ip != &tcb) { |
f03530e6 | 68 | tp = intotcpcb(ip); |
37de812c BJ |
69 | if (tp == 0) |
70 | continue; | |
1e977657 | 71 | ipnxt = ip->inp_next; |
a6503abf | 72 | for (i = 0; i < TCPT_NTIMERS; i++) { |
1e977657 | 73 | if (tp->t_timer[i] && --tp->t_timer[i] == 0) { |
f03530e6 BJ |
74 | (void) tcp_usrreq(tp->t_inpcb->inp_socket, |
75 | PRU_SLOWTIMO, (struct mbuf *)0, | |
76 | (caddr_t)i); | |
1e977657 BJ |
77 | if (ipnxt->inp_prev != ip) |
78 | goto tpgone; | |
79 | } | |
f03530e6 | 80 | } |
405c9168 BJ |
81 | tp->t_idle++; |
82 | if (tp->t_rtt) | |
83 | tp->t_rtt++; | |
1e977657 BJ |
84 | tpgone: |
85 | ip = ipnxt; | |
f03530e6 | 86 | } |
a6503abf | 87 | tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ |
f03530e6 BJ |
88 | splx(s); |
89 | } | |
90 | ||
91 | /* | |
a6503abf | 92 | * Cancel all timers for TCP tp. |
f03530e6 | 93 | */ |
0974b45c | 94 | tcp_canceltimers(tp) |
f03530e6 BJ |
95 | struct tcpcb *tp; |
96 | { | |
f03530e6 BJ |
97 | register int i; |
98 | ||
0974b45c | 99 | COUNT(TCP_CANCELTIMERS); |
a6503abf BJ |
100 | for (i = 0; i < TCPT_NTIMERS; i++) |
101 | tp->t_timer[i] = 0; | |
f03530e6 BJ |
102 | } |
103 | ||
d977a479 | 104 | int tcprexmtprint; |
f03530e6 | 105 | /* |
405c9168 | 106 | * TCP timer processing. |
f03530e6 | 107 | */ |
a6503abf | 108 | tcp_timers(tp, timer) |
f03530e6 | 109 | register struct tcpcb *tp; |
a6503abf | 110 | int timer; |
f03530e6 BJ |
111 | { |
112 | ||
113 | COUNT(TCP_TIMERS); | |
0974b45c | 114 | switch (timer) { |
f03530e6 | 115 | |
405c9168 BJ |
116 | /* |
117 | * 2 MSL timeout in shutdown went off. Delete connection | |
118 | * control block. | |
119 | */ | |
a6503abf BJ |
120 | case TCPT_2MSL: |
121 | tcp_close(tp); | |
122 | return; | |
f03530e6 | 123 | |
405c9168 BJ |
124 | /* |
125 | * Retransmission timer went off. Message has not | |
126 | * been acked within retransmit interval. Back off | |
127 | * to a longer retransmit interval and retransmit all | |
128 | * unacknowledged messages in the window. | |
129 | */ | |
a6503abf | 130 | case TCPT_REXMT: |
405c9168 | 131 | tp->t_rxtshift++; |
fd5dc5f0 BJ |
132 | if (tp->t_rxtshift > TCP_MAXRXTSHIFT) { |
133 | tcp_drop(tp, ETIMEDOUT); | |
134 | return; | |
135 | } | |
405c9168 | 136 | TCPT_RANGESET(tp->t_timer[TCPT_REXMT], |
d977a479 | 137 | (int)tp->t_srtt, TCPTV_MIN, TCPTV_MAX); |
b8b9174f BJ |
138 | TCPT_RANGESET(tp->t_timer[TCPT_REXMT], |
139 | tp->t_timer[TCPT_REXMT] << tp->t_rxtshift, | |
140 | TCPTV_MIN, TCPTV_MAX); | |
d977a479 BJ |
141 | if (tcprexmtprint) |
142 | printf("rexmt set to %d\n", tp->t_timer[TCPT_REXMT]); | |
405c9168 BJ |
143 | tp->snd_nxt = tp->snd_una; |
144 | /* this only transmits one segment! */ | |
145 | (void) tcp_output(tp); | |
a6503abf | 146 | return; |
f03530e6 | 147 | |
405c9168 BJ |
148 | /* |
149 | * Persistance timer into zero window. | |
150 | * Force a byte to be output, if possible. | |
151 | */ | |
a6503abf | 152 | case TCPT_PERSIST: |
405c9168 BJ |
153 | tp->t_force = 1; |
154 | (void) tcp_output(tp); | |
155 | tp->t_force = 0; | |
156 | TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], | |
d977a479 | 157 | tcp_beta * tp->t_srtt, TCPTV_PERSMIN, TCPTV_MAX); |
0974b45c | 158 | return; |
f03530e6 | 159 | |
405c9168 BJ |
160 | /* |
161 | * Keep-alive timer went off; send something | |
162 | * or drop connection if idle for too long. | |
163 | */ | |
a6503abf | 164 | case TCPT_KEEP: |
405c9168 BJ |
165 | if (tp->t_state < TCPS_ESTABLISHED || |
166 | tp->t_idle >= TCPTV_MAXIDLE) { | |
167 | tcp_drop(tp, ETIMEDOUT); | |
168 | return; | |
169 | } | |
1e977657 | 170 | if (tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) |
8e65fd66 BJ |
171 | tcp_respond(tp, |
172 | tp->t_template, tp->rcv_nxt, tp->snd_una-1, 0); | |
1e977657 BJ |
173 | else |
174 | tp->t_idle = 0; | |
405c9168 | 175 | tp->t_timer[TCPT_KEEP] = TCPTV_KEEP; |
a6503abf | 176 | return; |
8b5a83bb BJ |
177 | |
178 | #ifdef TCPTRUEOOB | |
179 | /* | |
180 | * Out-of-band data retransmit timer. | |
181 | */ | |
182 | case TCPT_OOBREXMT: | |
183 | if (tp->t_flags & TF_NOOPT) | |
184 | return; | |
185 | (void) tcp_output(tp); | |
186 | TCPT_RANGESET(tp->t_timer[TCPT_OOBREXMT], | |
187 | 2 * tp->t_srtt, TCPTV_MIN, TCPTV_MAX); | |
188 | return; | |
189 | #endif | |
f03530e6 | 190 | } |
f03530e6 | 191 | } |