|
|
1.1 root 1: /* tcp_timer.c 6.1 83/07/29 */
2:
3: #include "sys/param.h"
4: #include "sys/stream.h"
5: #include "sys/inet/in.h"
6: #include "sys/inet/ip.h"
7: #include "sys/inet/ip_var.h"
8: #include "sys/inet/tcp.h"
9: #include "sys/inet/tcp_fsm.h"
10: #include "sys/inet/tcp_seq.h"
11: #include "sys/inet/tcp_timer.h"
12: #include "sys/inet/tcp_var.h"
13: #include "sys/inet/tcpip.h"
14:
15: extern struct tcpcb tcpcb[];
16: extern int tcpcnt;
17: int tcpnodelack = 0;
18: /*
19: * Fast timeout routine for processing delayed acks
20: */
21: tcp_fasttimo()
22: {
23: register struct tcpcb *tp;
24: register struct tcpcb *tend;
25: int s = spl6();
26: extern tcp_busy;
27:
28: if(tcp_busy)
29: goto busy;
30: tcp_busy++;
31: tend = &tcpcb[tcpcnt];
32: for(tp = tcpcb; tp < tend; tp++)
33: if ((tp->t_flags & TF_DELACK)) {
34: tp->t_flags &= ~TF_DELACK;
35: tp->t_flags |= TF_ACKNOW;
36: (void) tcp_output(tp);
37: }
38: --tcp_busy;
39: busy:
40: timeout(tcp_fasttimo, (caddr_t) 0, HZ / 5);
41: splx(s);
42: }
43:
44: /*
45: * Tcp protocol timeout routine called every 500 ms.
46: * Updates the timers in all active tcb's and
47: * causes finite state machine actions if timers expire.
48: */
49: tcp_slowtimo()
50: {
51: extern int tcp_busy;
52: register struct tcpcb *tp;
53: register struct tcpcb *tend;
54: int s = spl6();
55: register int i;
56:
57: if(tcp_busy)
58: goto busy;
59: /*
60: * Search through tcb's and update active timers.
61: */
62: tcp_busy++;
63: tend = &tcpcb[tcpcnt];
64: for(tp = tcpcb; tp < tend; tp++){
65: if(tp->t_state == TCPS_CLOSED)
66: continue;
67: for (i = 0; i < TCPT_NTIMERS; i++) {
68: if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
69: tcp_timers(tp, i);
70: }
71: }
72: tp->t_idle++;
73: if (tp->t_rtt)
74: tp->t_rtt++;
75: }
76: --tcp_busy;
77: busy:
78: tcp_iss += TCP_ISSINCR/PR_SLOWHZ;
79: splx(s);
80: timeout(tcp_slowtimo, (caddr_t)0, HZ/PR_SLOWHZ);
81: }
82:
83: /*
84: * Cancel all timers for TCP tp.
85: */
86: tcp_canceltimers(tp)
87: struct tcpcb *tp;
88: {
89: register int i;
90:
91: for (i = 0; i < TCPT_NTIMERS; i++)
92: tp->t_timer[i] = 0;
93: }
94:
95: float tcp_backoff[TCP_MAXRXTSHIFT] =
96: { 1.0, 1.2, 1.4, 1.7, 2.0, 3.0, 5.0, 8.0, 16.0, 32.0, 64.0, 128.0 };
97: int tcpexprexmtbackoff = 0;
98: /*
99: * TCP timer processing.
100: */
101: struct tcpcb *
102: tcp_timers(tp, timer)
103: register struct tcpcb *tp;
104: int timer;
105: {
106:
107: if(tp->t_state == TCPS_ESTABLISHED)
108: tcpstat.tcps_timeouts[timer]++;
109: switch (timer) {
110:
111: /*
112: * 2 MSL timeout in shutdown went off. Delete connection
113: * control block.
114: */
115: case TCPT_2MSL:
116: tp = tcp_close(tp);
117: break;
118:
119: /*
120: * Retransmission timer went off. Message has not
121: * been acked within retransmit interval. Back off
122: * to a longer retransmit interval and retransmit all
123: * unacknowledged messages in the window.
124: */
125: case TCPT_REXMT:
126: tp->t_rxtshift++;
127: if (tp->t_rxtshift > TCP_MAXRXTSHIFT) {
128: tp = tcp_drop(tp);
129: break;
130: }
131: TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
132: (int)tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
133: if (tcpexprexmtbackoff) {
134: TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
135: tp->t_timer[TCPT_REXMT] << tp->t_rxtshift,
136: TCPTV_MIN, TCPTV_MAX);
137: } else {
138: TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
139: tp->t_timer[TCPT_REXMT] *
140: tcp_backoff[tp->t_rxtshift - 1],
141: TCPTV_MIN, TCPTV_MAX);
142: }
143: tp->snd_nxt = tp->snd_una;
144: /* this only transmits one segment! */
145: (void) tcp_output(tp);
146: break;
147:
148: /*
149: * Persistance timer into zero window.
150: * Force a byte to be output, if possible.
151: */
152: case TCPT_PERSIST:
153: tcp_setpersist(tp);
154: tp->t_force = 1;
155: (void) tcp_output(tp);
156: tp->t_force = 0;
157: break;
158:
159: /*
160: * Keep-alive timer went off; send something
161: * or drop connection if idle for too long.
162: */
163: case TCPT_KEEP:
164: if (tp->t_state < TCPS_ESTABLISHED)
165: goto dropit;
166: if (tp->so_options & SO_KEEPALIVE) {
167: if (tp->t_idle >= TCPTV_MAXIDLE)
168: goto dropit;
169: /*
170: * Saying tp->rcv_nxt-1 lies about what
171: * we have received, and by the protocol spec
172: * requires the correspondent TCP to respond.
173: * Saying tp->snd_una-1 causes the transmitted
174: * byte to lie outside the receive window; this
175: * is important because we don't necessarily
176: * have a byte in the window to send (consider
177: * a one-way stream!)
178: */
179: tcp_respond(tp, (struct tcpiphdr *)tp->t_template->rptr,
180: tp->rcv_nxt-1, tp->snd_una-1, 0);
181: } else
182: tp->t_idle = 0;
183: tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
184: break;
185: dropit:
186: tp = tcp_drop(tp);
187: break;
188: }
189: return (tp);
190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.