Annotation of linux/net/tcp/timer.c, revision 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.