Add copyright
[unix-history] / usr / src / sys / netinet / tcp_timer.c
index 5cf2c77..524d67f 100644 (file)
@@ -1,4 +1,10 @@
-/*     tcp_timer.c     6.3     84/10/18        */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)tcp_timer.c 6.7 (Berkeley) %G%
+ */
 
 #include "param.h"
 #include "systm.h"
 
 #include "param.h"
 #include "systm.h"
@@ -65,11 +71,11 @@ tcp_slowtimo()
                splx(s);
                return;
        }
                splx(s);
                return;
        }
-       while (ip != &tcb) {
+       for (; ip != &tcb; ip = ipnxt) {
+               ipnxt = ip->inp_next;
                tp = intotcpcb(ip);
                if (tp == 0)
                        continue;
                tp = intotcpcb(ip);
                if (tp == 0)
                        continue;
-               ipnxt = ip->inp_next;
                for (i = 0; i < TCPT_NTIMERS; i++) {
                        if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
                                (void) tcp_usrreq(tp->t_inpcb->inp_socket,
                for (i = 0; i < TCPT_NTIMERS; i++) {
                        if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
                                (void) tcp_usrreq(tp->t_inpcb->inp_socket,
@@ -83,7 +89,7 @@ tcp_slowtimo()
                if (tp->t_rtt)
                        tp->t_rtt++;
 tpgone:
                if (tp->t_rtt)
                        tp->t_rtt++;
 tpgone:
-               ip = ipnxt;
+               ;
        }
        tcp_iss += TCP_ISSINCR/PR_SLOWHZ;               /* increment iss */
        splx(s);
        }
        tcp_iss += TCP_ISSINCR/PR_SLOWHZ;               /* increment iss */
        splx(s);
@@ -126,8 +132,7 @@ tcp_timers(tp, timer)
        /*
         * Retransmission timer went off.  Message has not
         * been acked within retransmit interval.  Back off
        /*
         * Retransmission timer went off.  Message has not
         * been acked within retransmit interval.  Back off
-        * to a longer retransmit interval and retransmit all
-        * unacknowledged messages in the window.
+        * to a longer retransmit interval and retransmit one segment.
         */
        case TCPT_REXMT:
                tp->t_rxtshift++;
         */
        case TCPT_REXMT:
                tp->t_rxtshift++;
@@ -135,6 +140,12 @@ tcp_timers(tp, timer)
                        tp = tcp_drop(tp, ETIMEDOUT);
                        break;
                }
                        tp = tcp_drop(tp, ETIMEDOUT);
                        break;
                }
+               /*
+                * If losing, let the lower level know
+                * and try for a better route.
+                */
+               if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 2)
+                       in_rtchange(tp->t_inpcb);
                TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
                    (int)tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
                if (tcpexprexmtbackoff) {
                TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
                    (int)tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
                if (tcpexprexmtbackoff) {
@@ -148,7 +159,13 @@ tcp_timers(tp, timer)
                            TCPTV_MIN, TCPTV_MAX);
                }
                tp->snd_nxt = tp->snd_una;
                            TCPTV_MIN, TCPTV_MAX);
                }
                tp->snd_nxt = tp->snd_una;
-               /* this only transmits one segment! */
+               /*
+                * If timing a segment in this window,
+                * and we have already gotten some timing estimate,
+                * stop the timer.
+                */
+               if (tp->t_rtt && tp->t_srtt)
+                       tp->t_rtt = 0;
                (void) tcp_output(tp);
                break;
 
                (void) tcp_output(tp);
                break;