Annotation of linux/net/tcp/timer.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.