|
|
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.