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->backoff++;
  74         sk->rto = min(sk->rto << 1, 120*HZ);
  75         tcp_reset_xmit_timer(sk, TIME_WRITE, sk->rto);
  76 }
  77 
  78 /*
  79  *      POLICY:
  80  *              Congestion control.
  81  *
  82  *      A timer event has trigger a tcp retransmit timeout. The
  83  *      socket xmit queue is ready and set up to send. Because
  84  *      the ack receive code keeps the queue straight we do
  85  *      nothing clever here.
  86  */
  87 
  88 void tcp_retransmit(struct sock *sk, int all)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90         if (all) 
  91         {
  92                 tcp_retransmit_time(sk, all);
  93                 return;
  94         }
  95 
  96         sk->ssthresh = sk->cong_window >> 1; /* remember window where we lost */
  97         /* sk->ssthresh in theory can be zero.  I guess that's OK */
  98         sk->cong_count = 0;
  99 
 100         sk->cong_window = 1;
 101 
 102         /* Do the actual retransmit. */
 103         tcp_retransmit_time(sk, all);
 104 }
 105 
 106 /*
 107  *      A write timeout has occurred. Process the after effects. BROKEN (badly)
 108  */
 109 
 110 static int tcp_write_timeout(struct sock *sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         /*
 113          *      Look for a 'soft' timeout.
 114          */
 115         if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
 116                 || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) 
 117         {
 118                 /*
 119                  *      Attempt to recover if arp has changed (unlikely!) or
 120                  *      a route has shifted (not supported prior to 1.3).
 121                  */
 122                 ip_rt_advice(&sk->ip_route_cache, 0);
 123         }
 124         
 125         /*
 126          *      Have we tried to SYN too many times (repent repent 8))
 127          */
 128          
 129         if(sk->retransmits > TCP_SYN_RETRIES && sk->state==TCP_SYN_SENT)
 130         {
 131                 if(sk->err_soft)
 132                         sk->err=sk->err_soft;
 133                 else
 134                         sk->err=ETIMEDOUT;
 135                 sk->error_report(sk);
 136                 del_timer(&sk->retransmit_timer);
 137                 tcp_statistics.TcpAttemptFails++;       /* Is this right ??? - FIXME - */
 138                 tcp_set_state(sk,TCP_CLOSE);
 139                 /* Don't FIN, we got nothing back */
 140                 return 0;
 141         }
 142         /*
 143          *      Has it gone just too far ?
 144          */
 145         if (sk->retransmits > TCP_RETR2) 
 146         {
 147                 if(sk->err_soft)
 148                         sk->err = sk->err_soft;
 149                 else
 150                         sk->err = ETIMEDOUT;
 151                 sk->error_report(sk);
 152                 del_timer(&sk->retransmit_timer);
 153                 /*
 154                  *      Time wait the socket 
 155                  */
 156                 if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2 || sk->state == TCP_CLOSING ) 
 157                 {
 158                         tcp_set_state(sk,TCP_TIME_WAIT);
 159                         tcp_reset_msl_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
 160                 }
 161                 else
 162                 {
 163                         /*
 164                          *      Clean up time.
 165                          */
 166                         tcp_set_state(sk, TCP_CLOSE);
 167                         return 0;
 168                 }
 169         }
 170         return 1;
 171 }
 172 
 173 /*
 174  *      It could be we got here because we needed to send an ack,
 175  *      so we need to check for that and not just normal retransmit.
 176  */
 177 static void tcp_time_write_timeout(struct sock * sk)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         struct sk_buff *skb;
 180         unsigned long flags;
 181 
 182         save_flags(flags);
 183         cli();
 184         skb = sk->send_head;
 185         if (!skb) {
 186                 if (sk->ack_backlog)
 187                         tcp_read_wakeup(sk);
 188                 restore_flags(flags);
 189                 return;
 190         } 
 191 
 192         /*
 193          *      Kicked by a delayed ack. Reset timer
 194          *      correctly now
 195          */
 196         if (jiffies < skb->when + sk->rto) 
 197         {
 198                 if (sk->ack_backlog)
 199                         tcp_read_wakeup(sk);
 200                 tcp_reset_xmit_timer (sk, TIME_WRITE, skb->when + sk->rto - jiffies);
 201                 restore_flags(flags);
 202                 return;
 203         }
 204 
 205         restore_flags(flags);
 206         /*
 207          *      Retransmission
 208          */
 209         sk->prot->retransmit (sk, 0);
 210         tcp_write_timeout(sk);
 211 }
 212 
 213 
 214 /*
 215  *      The TCP retransmit timer. This lacks a few small details.
 216  *
 217  *      1.      An initial rtt timeout on the probe0 should cause what we can
 218  *              of the first write queue buffer to be split and sent.
 219  *      2.      On a 'major timeout' as defined by RFC1122 we shouldn't report
 220  *              ETIMEDOUT if we know an additional 'soft' error caused this.
 221  *              tcp_err should save a 'soft error' for us.
 222  */
 223 
 224 void tcp_retransmit_timer(unsigned long data)
     /* [previous][next][first][last][top][bottom][index][help] */
 225 {
 226         struct sock *sk = (struct sock*)data;
 227         int why = sk->ip_xmit_timeout;
 228 
 229         /*
 230          *      We are reset. We will send no more retransmits.
 231          */
 232          
 233         if(sk->zapped)
 234                 return;
 235                 
 236         /* 
 237          *      Only process if socket is not in use
 238          */
 239 
 240         if (sk->users) 
 241         {
 242                 /* Try again in 1 second */
 243                 sk->retransmit_timer.expires = jiffies+HZ;
 244                 add_timer(&sk->retransmit_timer);
 245                 return;
 246         }
 247 
 248         if (sk->ack_backlog && !sk->dead) 
 249                 sk->data_ready(sk,0);
 250 
 251         /* Now we need to figure out why the socket was on the timer. */
 252 
 253         switch (why) 
 254         {
 255         /* Window probing */
 256         case TIME_PROBE0:
 257                 tcp_send_probe0(sk);
 258                 tcp_write_timeout(sk);
 259                 break;
 260 
 261         /* Retransmitting */
 262         case TIME_WRITE:
 263                 tcp_time_write_timeout(sk);
 264                 break;
 265 
 266         /* Sending Keepalives */
 267         case TIME_KEEPOPEN:
 268                 /* 
 269                  * this reset_timer() call is a hack, this is not
 270                  * how KEEPOPEN is supposed to work.
 271                  */
 272                 tcp_reset_xmit_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);
 273                 /* Send something to keep the connection open. */
 274                 if (sk->prot->write_wakeup)
 275                           sk->prot->write_wakeup (sk);
 276                 sk->retransmits++;
 277                 sk->prot->retransmits++;
 278                 tcp_write_timeout(sk);
 279                 break;
 280 
 281         default:
 282                 printk ("rexmit_timer: timer expired - reason unknown\n");
 283                 break;
 284         }
 285 }

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