root/net/ipv4/tcp_timer.c

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

DEFINITIONS

This source file includes following definitions.
  1. tcp_reset_xmit_timer
  2. tcp_retransmit_time
  3. tcp_retransmit
  4. tcp_write_timeout
  5. tcp_time_write_timeout
  6. tcp_retransmit_timer

   1 /*
   2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3  *              operating system.  INET is implemented using the  BSD Socket
   4  *              interface as the means of communication with the user level.
   5  *
   6  *              Implementation of the Transmission Control Protocol(TCP).
   7  *
   8  * Version:     @(#)tcp.c       1.0.16  05/25/93
   9  *
  10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12  *              Mark Evans, <evansmp@uhura.aston.ac.uk>
  13  *              Corey Minyard <wf-rch!minyard@relay.EU.net>
  14  *              Florian La Roche, <flla@stud.uni-sb.de>
  15  *              Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
  16  *              Linus Torvalds, <torvalds@cs.helsinki.fi>
  17  *              Alan Cox, <gw4pts@gw4pts.ampr.org>
  18  *              Matthew Dillon, <dillon@apollo.west.oic.com>
  19  *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  20  *              Jorge Cwik, <jorge@laser.satlink.net>
  21  */
  22 
  23 #include <net/tcp.h>
  24 
  25 /*
  26  *      Reset the retransmission timer
  27  */
  28  
  29 void tcp_reset_xmit_timer(struct sock *sk, int why, unsigned long when)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31         del_timer(&sk->retransmit_timer);
  32         sk->ip_xmit_timeout = why;
  33         if((long)when < 0)
  34         {
  35                 when=3;
  36                 printk("Error: Negative timer in xmit_timer\n");
  37         }
  38         sk->retransmit_timer.expires=jiffies+when;
  39         add_timer(&sk->retransmit_timer);
  40 }
  41 
  42 /*
  43  *      POLICY:
  44  *
  45  *      This is the normal code called for timeouts.  It does the retransmission
  46  *      and then does backoff.  tcp_do_retransmit is separated out because
  47  *      tcp_ack needs to send stuff from the retransmit queue without
  48  *      initiating a backoff.
  49  */
  50 
  51 
  52 static void tcp_retransmit_time(struct sock *sk, int all)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54         tcp_do_retransmit(sk, all);
  55 
  56         /*
  57          * Increase the timeout each time we retransmit.  Note that
  58          * we do not increase the rtt estimate.  rto is initialized
  59          * from rtt, but increases here.  Jacobson (SIGCOMM 88) suggests
  60          * that doubling rto each time is the least we can get away with.
  61          * In KA9Q, Karn uses this for the first few times, and then
  62          * goes to quadratic.  netBSD doubles, but only goes up to *64,
  63          * and clamps at 1 to 64 sec afterwards.  Note that 120 sec is
  64          * defined in the protocol as the maximum possible RTT.  I guess
  65          * we'll have to use something other than TCP to talk to the
  66          * University of Mars.
  67          *
  68          * PAWS allows us longer timeouts and large windows, so once
  69          * implemented ftp to mars will work nicely. We will have to fix
  70          * the 120 second clamps though!
  71          */
  72 
  73         sk->retransmits++;
  74         sk->prot->retransmits++;
  75         sk->backoff++;
  76         sk->rto = min(sk->rto << 1, 120*HZ);
  77         tcp_reset_xmit_timer(sk, TIME_WRITE, sk->rto);
  78 }
  79 
  80 /*
  81  *      POLICY:
  82  *              Congestion control.
  83  *
  84  *      A timer event has trigger a tcp retransmit timeout. The
  85  *      socket xmit queue is ready and set up to send. Because
  86  *      the ack receive code keeps the queue straight we do
  87  *      nothing clever here.
  88  */
  89 
  90 void tcp_retransmit(struct sock *sk, int all)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         if (all) 
  93         {
  94                 tcp_retransmit_time(sk, all);
  95                 return;
  96         }
  97 
  98         sk->ssthresh = sk->cong_window >> 1; /* remember window where we lost */
  99         /* sk->ssthresh in theory can be zero.  I guess that's OK */
 100         sk->cong_count = 0;
 101 
 102         sk->cong_window = 1;
 103 
 104         /* Do the actual retransmit. */
 105         tcp_retransmit_time(sk, all);
 106 }
 107 
 108 /*
 109  *      A write timeout has occurred. Process the after effects. BROKEN (badly)
 110  */
 111 
 112 static int tcp_write_timeout(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 113 {
 114         /*
 115          *      Look for a 'soft' timeout.
 116          */
 117         if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
 118                 || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) 
 119         {
 120                 /*
 121                  *      Attempt to recover if arp has changed (unlikely!) or
 122                  *      a route has shifted (not supported prior to 1.3).
 123                  */
 124                 ip_rt_advice(&sk->ip_route_cache, 0);
 125         }
 126         
 127         /*
 128          *      Have we tried to SYN too many times (repent repent 8))
 129          */
 130          
 131         if(sk->retransmits > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT)
 132         {
 133                 if(sk->err_soft)
 134                         sk->err=sk->err_soft;
 135                 else
 136                         sk->err=ETIMEDOUT;
 137                 sk->error_report(sk);
 138                 del_timer(&sk->retransmit_timer);
 139                 tcp_statistics.TcpAttemptFails++;       /* Is this right ??? - FIXME - */
 140                 tcp_set_state(sk,TCP_CLOSE);
 141                 /* Don't FIN, we got nothing back */
 142                 return 0;
 143         }
 144         /*
 145          *      Has it gone just too far ?
 146          */
 147         if (sk->retransmits > TCP_RETR2) 
 148         {
 149                 if(sk->err_soft)
 150                         sk->err = sk->err_soft;
 151                 else
 152                         sk->err = ETIMEDOUT;
 153                 sk->error_report(sk);
 154                 del_timer(&sk->retransmit_timer);
 155                 /*
 156                  *      Time wait the socket 
 157                  */
 158                 if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING ) 
 159                 {
 160                         tcp_set_state(sk,TCP_TIME_WAIT);
 161                         tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
 162                 }
 163                 else
 164                 {
 165                         /*
 166                          *      Clean up time.
 167                          */
 168                         tcp_set_state(sk, TCP_CLOSE);
 169                         return 0;
 170                 }
 171         }
 172         return 1;
 173 }
 174 
 175 /*
 176  *      It could be we got here because we needed to send an ack,
 177  *      so we need to check for that and not just normal retransmit.
 178  */
 179 static void tcp_time_write_timeout(struct sock * sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         struct sk_buff *skb;
 182         unsigned long flags;
 183 
 184         save_flags(flags);
 185         cli();
 186         skb = sk->send_head;
 187         if (!skb) {
 188                 if (sk->ack_backlog)
 189                         tcp_read_wakeup(sk);
 190                 restore_flags(flags);
 191                 return;
 192         } 
 193 
 194         /*
 195          *      Kicked by a delayed ack. Reset timer
 196          *      correctly now
 197          */
 198         if (jiffies < skb->when + sk->rto) 
 199         {
 200                 if (sk->ack_backlog)
 201                         tcp_read_wakeup(sk);
 202                 tcp_reset_xmit_timer (sk, TIME_WRITE, skb->when + sk->rto - jiffies);
 203                 restore_flags(flags);
 204                 return;
 205         }
 206 
 207         restore_flags(flags);
 208         /*
 209          *      Retransmission
 210          */
 211         sk->retransmits++;
 212         sk->prot->retransmits++;
 213         sk->prot->retransmit (sk, 0);
 214         tcp_write_timeout(sk);
 215 }
 216 
 217 
 218 /*
 219  *      The TCP retransmit timer. This lacks a few small details.
 220  *
 221  *      1.      An initial rtt timeout on the probe0 should cause what we can
 222  *              of the first write queue buffer to be split and sent.
 223  *      2.      On a 'major timeout' as defined by RFC1122 we shouldn't report
 224  *              ETIMEDOUT if we know an additional 'soft' error caused this.
 225  *              tcp_err should save a 'soft error' for us.
 226  */
 227 
 228 void tcp_retransmit_timer(unsigned long data)
     /* [previous][next][first][last][top][bottom][index][help] */
 229 {
 230         struct sock *sk = (struct sock*)data;
 231         int why = sk->ip_xmit_timeout;
 232 
 233         /*
 234          *      We are reset. We will send no more retransmits.
 235          */
 236          
 237         if(sk->zapped)
 238                 return;
 239                 
 240         /* 
 241          *      Only process if socket is not in use
 242          */
 243 
 244         if (sk->users) 
 245         {
 246                 /* Try again in 1 second */
 247                 sk->retransmit_timer.expires = jiffies+HZ;
 248                 add_timer(&sk->retransmit_timer);
 249                 return;
 250         }
 251 
 252         if (sk->ack_backlog && !sk->dead) 
 253                 sk->data_ready(sk,0);
 254 
 255         /* Now we need to figure out why the socket was on the timer. */
 256 
 257         switch (why) 
 258         {
 259         /* Window probing */
 260         case TIME_PROBE0:
 261                 tcp_send_probe0(sk);
 262                 tcp_write_timeout(sk);
 263                 break;
 264 
 265         /* Retransmitting */
 266         case TIME_WRITE:
 267                 tcp_time_write_timeout(sk);
 268                 break;
 269 
 270         /* Sending Keepalives */
 271         case TIME_KEEPOPEN:
 272                 /* 
 273                  * this reset_timer() call is a hack, this is not
 274                  * how KEEPOPEN is supposed to work.
 275                  */
 276                 tcp_reset_xmit_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
 277                 /* Send something to keep the connection open. */
 278                 if (sk->prot->write_wakeup)
 279                           sk->prot->write_wakeup (sk);
 280                 sk->retransmits++;
 281                 sk->prot->retransmits++;
 282                 tcp_write_timeout(sk);
 283                 break;
 284 
 285         default:
 286                 printk ("rexmit_timer: timer expired - reason unknown\n");
 287                 break;
 288         }
 289 }

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