root/net/tcp/timer.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. delete_timer
  2. reset_timer
  3. net_timer

   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 bir7@leland.stanford.edu 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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 

/* [previous][next][first][last][top][bottom][index][help] */