delete OURFINNOTACKED
[unix-history] / usr / src / sys / netinet / tcp_timer.c
index 34b8e5d..24d24ae 100644 (file)
@@ -1,4 +1,4 @@
-/* tcp_timer.c 4.1 81/11/24 */
+/* tcp_timer.c 4.9 81/12/20 */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -6,17 +6,19 @@
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
-#include "../net/inet.h"
-#include "../net/inet_pcb.h"
-#include "../net/inet_systm.h"
+#include "../net/in.h"
+#include "../net/in_pcb.h"
+#include "../net/in_systm.h"
 #include "../net/if.h"
 #include "../net/if.h"
-#include "../net/imp.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 #include "../net/tcp.h"
 #include "../net/tcp_fsm.h"
 #include "../net/ip.h"
 #include "../net/ip_var.h"
 #include "../net/tcp.h"
 #include "../net/tcp_fsm.h"
+#include "../net/tcp_seq.h"
+#include "../net/tcp_timer.h"
 #include "../net/tcp_var.h"
 #include "../net/tcp_var.h"
-#include "/usr/include/errno.h"
+#include "../net/tcpip.h"
+#include "../errno.h"
 
 /*
  * Fast timeout routine for processing delayed acks
 
 /*
  * Fast timeout routine for processing delayed acks
@@ -24,6 +26,7 @@
 tcp_fasttimo()
 {
 
 tcp_fasttimo()
 {
 
+COUNT(TCP_FASTTIMO);
 }
 
 /*
 }
 
 /*
@@ -36,105 +39,108 @@ tcp_slowtimo()
        register struct inpcb *ip;
        register struct tcpcb *tp;
        int s = splnet();
        register struct inpcb *ip;
        register struct tcpcb *tp;
        int s = splnet();
-       register short *tmp;
        register int i;
        register int i;
-COUNT(TCP_TIMEO);
+COUNT(TCP_SLOWTIMO);
 
        /*
         * Search through tcb's and update active timers.
         */
 
        /*
         * Search through tcb's and update active timers.
         */
-       for (ip = tcb.inp_next; ip != &tcb; ip = ip->inp_next) {
+       ip = tcb.inp_next;
+       if (ip == 0) {
+               splx(s);
+               return;
+       }
+       for (; ip != &tcb; ip = ip->inp_next) {
                tp = intotcpcb(ip);
                tp = intotcpcb(ip);
-               tmp = &tp->t_init;
-               for (i = 0; i < TNTIMERS; i++) {
-                       if (*tmp && --*tmp == 0)
+               if (tp == 0)
+                       continue;
+               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,
                                    PRU_SLOWTIMO, (struct mbuf *)0,
                                    (caddr_t)i);
                                (void) tcp_usrreq(tp->t_inpcb->inp_socket,
                                    PRU_SLOWTIMO, (struct mbuf *)0,
                                    (caddr_t)i);
-                       tmp++;
                }
                }
-               tp->t_xmt++;
+               tp->t_idle++;
+               if (tp->t_rtt)
+                       tp->t_rtt++;
        }
        }
-       tcp_iss += ISSINCR/2;           /* increment iss */
+       tcp_iss += TCP_ISSINCR/PR_SLOWHZ;               /* increment iss */
        splx(s);
 }
 
 /*
        splx(s);
 }
 
 /*
- * Cancel all timers for tcp tp.
+ * Cancel all timers for TCP tp.
  */
  */
-tcp_tcancel(tp)
+tcp_canceltimers(tp)
        struct tcpcb *tp;
 {
        struct tcpcb *tp;
 {
-       register short *tmp = &tp->t_init;
        register int i;
 
        register int i;
 
-       for (i = 0; i < TNTIMERS; i++)
-               *tmp++ = 0;
+COUNT(TCP_CANCELTIMERS);
+       for (i = 0; i < TCPT_NTIMERS; i++)
+               tp->t_timer[i] = 0;
 }
 
 /*
 }
 
 /*
- * TCP timer went off processing.
+ * TCP timer processing.
  */
  */
-tcp_timers(tp, timertype)
+tcp_timers(tp, timer)
        register struct tcpcb *tp;
        register struct tcpcb *tp;
-       int timertype;
+       int timer;
 {
 
 COUNT(TCP_TIMERS);
 {
 
 COUNT(TCP_TIMERS);
-       switch (timertype) {
-
-       case TFINACK:           /* fin-ack timer */
-               switch (tp->t_state) {
+       switch (timer) {
 
 
-               case TIME_WAIT:
-                       /*
-                        * We can be sure our ACK of foreign FIN was rcvd,
-                        * and can close if no data left for user.
-                        */
-                       if (rcv_empty(tp)) {
-                               tcp_disconnect(tp);
-                               return (CLOSED);
-                       }
-                       return (RCV_WAIT);                      /* 17 */
-
-               case CLOSING:
-                       tp->tc_flags |= TC_WAITED_2_ML;
-                       return (SAME);
+       /*
+        * 2 MSL timeout in shutdown went off.  Delete connection
+        * control block.
+        */
+       case TCPT_2MSL:
+               tcp_close(tp);
+               return;
 
 
-               default:
-                       return (SAME);
-               }
+       /*
+        * 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.
+        */
+       case TCPT_REXMT:
+               tp->t_rxtshift++;
+               TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
+                   ((int)(2 * tp->t_srtt)) << tp->t_rxtshift,
+                   TCPTV_MIN, TCPTV_MAX);
+printf("rexmt set to %d\n", tp->t_timer[TCPT_REXMT]);
+               tp->snd_nxt = tp->snd_una;
+               /* this only transmits one segment! */
+               (void) tcp_output(tp);
+               return;
 
 
-       case TREXMT:            /* retransmission timer */
-               if (tp->t_rexmt_val > tp->snd_una) {            /* 34 */
-                       /*
-                        * Set so for a retransmission, increase rexmt time
-                        * in case of multiple retransmissions.
-                        */
-                       tp->snd_nxt = tp->snd_una;
-                       tp->tc_flags |= TC_REXMT;
-                       tp->t_xmtime = tp->t_xmtime << 1;
-                       if (tp->t_xmtime > T_REMAX)
-                               tp->t_xmtime = T_REMAX;
-                       (void) tcp_send(tp);
-               }
-               return (SAME);
+       /*
+        * Persistance timer into zero window.
+        * Force a byte to be output, if possible.
+        */
+       case TCPT_PERSIST:
+               tp->t_force = 1;
+               (void) tcp_output(tp);
+               tp->t_force = 0;
+               TCPT_RANGESET(tp->t_timer[TCPT_PERSIST],
+                   2 * tp->t_srtt, TCPTV_PERSMIN, TCPTV_MAX);
+               return;
 
 
-       case TREXMTTL:          /* retransmit too long */
-               if (tp->t_rtl_val > tp->snd_una) {              /* 36 */
-                       tcp_error(tp, ETIMEDOUT);
-                       return (CLOSED);
+       /*
+        * Keep-alive timer went off; send something
+        * or drop connection if idle for too long.
+        */
+       case TCPT_KEEP:
+               if (tp->t_state < TCPS_ESTABLISHED ||
+                   tp->t_idle >= TCPTV_MAXIDLE) {
+                       tcp_drop(tp, ETIMEDOUT);
+                       return;
                }
                }
-               return (SAME);
-
-       case TPERSIST:          /* persist timer */
-               /*
-                * Force a byte send through closed window.
-                */
-               tp->tc_flags |= TC_FORCE_ONE;
-               (void) tcp_send(tp);
-               return (SAME);
+               tcp_respond(tp->t_template, tp->rcv_nxt, tp->snd_una-1, 0);
+               tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
+               return;
        }
        }
-       panic("tcp_timers");
-       /*NOTREACHED*/
 }
 }