|
|
1.1 root 1: /* timer.c */
2: /*
3: Copyright (C) 1992 Ross Biro
4:
5: This program is free software; you can redistribute it and/or modify
6: it under the terms of the GNU General Public License as published by
7: the Free Software Foundation; either version 1, or (at your option)
8: any later version.
9:
10: This program is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18:
19: The Author may be reached as [email protected] or
20: C/O Department of Mathematics; Stanford University; Stanford, CA 94305
21: */
22: #include <linux/types.h>
23: #include <linux/errno.h>
24: #include <linux/socket.h>
25: #include <netinet/in.h>
26: #include <linux/kernel.h>
27: #include <linux/sched.h>
28: #include <linux/timer.h>
29: #include <asm/system.h>
30: #include "timer.h"
31: #include "ip.h"
32: #include "tcp.h"
33: #include "sock.h"
34: #include "arp.h"
35: #include "../kern_sock.h"
36:
37: static struct timer *timer_base=NULL;
38: unsigned long seq_offset;
39:
40: void
41: delete_timer (struct timer *t)
42: {
43: struct timer *tm;
44: PRINTK ("delete_timer (t=%X)\n",t);
45: if (timer_base == NULL) return;
46: cli();
47: if (t == timer_base)
48: {
49: timer_base = t->next;
50: if (timer_base != NULL)
51: {
52: timer_table[NET_TIMER].expires = timer_base->when;
53: timer_active |= 1 << NET_TIMER;
54: }
55: else
56: {
57: timer_active &= ~(1 << NET_TIMER);
58: }
59: sti();
60: return;
61: }
62: for (tm = timer_base;tm->next != NULL ;tm=tm->next)
63: {
64: if (tm->next == t)
65: {
66: tm->next = t->next;
67: sti();
68: return;
69: }
70: }
71: sti();
72: }
73:
74:
75: void
76: reset_timer (struct timer *t)
77: {
78: struct timer *tm;
79:
80: delete_timer (t);
81: t->when = timer_seq + t->len;
82: PRINTK ("reset_timer (t=%X) when = %d jiffies = %d\n",t, t->when, jiffies);
83: if (t == NULL)
84: {
85: printk ("*** reset timer NULL timer\n");
86: __asm__ ("\t int $3\n"::);
87: }
88: /* first see if it goes at the beginning. */
89: cli();
90: if (timer_base == NULL)
91: {
92: t->next = NULL;
93: timer_base = t;
94: timer_table[NET_TIMER].expires = t->when;
95: timer_active |= 1 << NET_TIMER;
96: sti();
97: return;
98: }
99: if (before (t->when, timer_base->when))
100: {
101: t->next = timer_base;
102: timer_base = t;
103: timer_table[NET_TIMER].expires = t->when;
104: timer_active |= 1 << NET_TIMER;
105: sti();
106: return;
107: }
108: for (tm = timer_base; ; tm=tm->next)
109: {
110: if (tm->next == NULL || before (t->when,tm->next->when))
111: {
112: t->next = tm->next;
113: tm->next = t;
114: sti();
115: return;
116: }
117: }
118: }
119:
120: void
121: net_timer (void)
122: {
123: volatile struct sock *sk;
124:
125: /* now we will only be called whenever we need to do something, but
126: we must be sure to process all of the sockets that need it. */
127:
128: while (timer_base != NULL && after (timer_seq+1 ,timer_base->when))
129: {
130: int why;
131: sk = timer_base->sk;
132: cli();
133: if (sk->inuse)
134: {
135: sti();
136: break;
137: }
138: sk->inuse = 1;
139: sti();
140: PRINTK ("net_timer: found sk=%X\n",sk);
141: why = sk->timeout;
142:
143: if (sk->keepopen)
144: {
145: sk->time_wait.len = TCP_TIMEOUT_LEN;
146: sk->timeout = TIME_KEEPOPEN;
147: reset_timer (timer_base);
148: }
149: else
150: {
151: sk->timeout = 0;
152: delete_timer(timer_base);
153: }
154:
155: /* always see if we need to send an ack. */
156: if (sk->ack_backlog)
157: {
158: sk->prot->read_wakeup(sk);
159: if (!sk->dead) wake_up (sk->sleep);
160: }
161:
162: /* now we need to figure out why the socket was on the timer. */
163: switch (why)
164: {
165:
166: case TIME_DONE:
167: if (!sk->dead || sk->state != TCP_CLOSE)
168: {
169: printk ("non dead socket in time_done\n");
170: release_sock (sk);
171: break;
172: }
173: destroy_sock (sk);
174: break;
175:
176: case TIME_DESTROY: /* we've waited for a while for all
177: the memory assosiated with the
178: socket to be freed. We need to
179: print an error message. */
180: PRINTK ("possible memory leak. sk = %X\n", sk);
181: print_sk (sk);
182: reset_timer ((struct timer *)&sk->time_wait);
183: sk->inuse = 0;
184: break;
185:
186: case TIME_CLOSE: /* we've waited long enough, close the
187: socket. */
188:
189: sk->state = TCP_CLOSE;
190: delete_timer ((struct timer *)&sk->time_wait);
191: /* kill the arp entry
192: in case the hardware has changed. */
193: arp_destroy (sk->daddr);
194: if (!sk->dead)
195: wake_up (sk->sleep);
196: release_sock(sk);
197: break;
198:
199: case TIME_WRITE: /* try to retransmit. */
200: if (sk->send_head != NULL)
201: {
202: sk->retransmits ++;
203: if (sk->retransmits > TCP_RETR1)
204: {
205: arp_destroy (sk->daddr);
206: ip_route_check (sk->daddr);
207: }
208:
209: if (sk->retransmits > TCP_RETR2)
210: {
211: sk->err = ETIMEDOUT;
212: arp_destroy (sk->daddr);
213: if (sk->state == TCP_FIN_WAIT1 ||
214: sk->state == TCP_FIN_WAIT2 ||
215: sk->state == TCP_LAST_ACK)
216: {
217: sk->state = TCP_TIME_WAIT;
218: sk->timeout = TIME_CLOSE;
219: sk->time_wait.len = TCP_TIMEWAIT_LEN;
220: reset_timer ((struct timer *)&sk->time_wait);
221: release_sock(sk);
222: break;
223: }
224: else /* sk->state == ... */
225: {
226: sk->prot->close (sk,1);
227: break;
228: }
229: }
230: else /* sk->retransmites .. */
231: {
232: sk->prot->retransmit (sk, 1);
233: release_sock (sk);
234: }
235: break;
236: }
237: /* if we have stuff which hasn't been written because the
238: window is too small, fall throught to TIME_KEEPOPEN */
239: if (sk->wfront == NULL)
240: {
241: release_sock (sk);
242: break;
243: }
244:
245: /* this basically assumes tcp here. */
246: /* exponential fall back. */
247: sk->rtt *= 2;
248: sk->time_wait.len = sk->rtt*2;
249: sk->timeout = TIME_WRITE;
250: reset_timer ((struct timer *)&sk->time_wait);
251:
252: case TIME_KEEPOPEN: /* send something to keep the
253: connection open. */
254: sk->retransmits ++;
255: if (sk->retransmits > TCP_RETR1)
256: {
257: arp_destroy (sk->daddr);
258: ip_route_check (sk->daddr);
259:
260: }
261: if (sk->retransmits > TCP_RETR2)
262: {
263: arp_destroy (sk->daddr);
264: sk->err = ETIMEDOUT;
265: if (sk->state == TCP_FIN_WAIT1 ||
266: sk->state == TCP_FIN_WAIT2)
267: {
268: sk->state = TCP_TIME_WAIT;
269: if (!sk->dead)
270: wake_up (sk->sleep);
271: release_sock(sk);
272: }
273: else /* sk->state == */
274: {
275: sk->prot->close (sk, 1);
276: }
277: break;
278: }
279: else /* sk->retransmits. */
280: {
281: if (sk->prot->write_wakeup != NULL)
282: sk->prot->write_wakeup(sk);
283: release_sock (sk);
284: break;
285: }
286:
287: default:
288: release_sock(sk);
289: break;
290: } /* switch */
291: } /* while (timer_base != ... */
292:
293: /* Now we need to reset the timer. */
294: if (timer_base != NULL)
295: {
296: timer_table[NET_TIMER].expires = timer_base->when;
297: timer_active |= 1 << NET_TIMER;
298: }
299: }
300:
301:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.