1 /* tcp_timer.c 4.13 82/01/19 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/socket.h" 7 #include "../h/socketvar.h" 8 #include "../h/protosw.h" 9 #include "../net/in.h" 10 #include "../net/in_pcb.h" 11 #include "../net/in_systm.h" 12 #include "../net/if.h" 13 #include "../net/ip.h" 14 #include "../net/ip_var.h" 15 #include "../net/tcp.h" 16 #include "../net/tcp_fsm.h" 17 #include "../net/tcp_seq.h" 18 #include "../net/tcp_timer.h" 19 #include "../net/tcp_var.h" 20 #include "../net/tcpip.h" 21 #include "../errno.h" 22 23 int tcpnodelack = 0; 24 /* 25 * Fast timeout routine for processing delayed acks 26 */ 27 tcp_fasttimo() 28 { 29 register struct inpcb *inp; 30 register struct tcpcb *tp; 31 int s = splnet(); 32 COUNT(TCP_FASTTIMO); 33 34 for (inp = tcb.inp_next; inp != &tcb; inp = inp->inp_next) 35 if ((tp = (struct tcpcb *)inp->inp_ppcb) && 36 (tp->t_flags & TF_DELACK)) { 37 tp->t_flags &= ~TF_DELACK; 38 tp->t_flags |= TF_ACKNOW; 39 (void) tcp_output(tp); 40 } 41 splx(s); 42 } 43 44 /* 45 * Tcp protocol timeout routine called every 500 ms. 46 * Updates the timers in all active tcb's and 47 * causes finite state machine actions if timers expire. 48 */ 49 tcp_slowtimo() 50 { 51 register struct inpcb *ip; 52 register struct tcpcb *tp; 53 int s = splnet(); 54 register int i; 55 COUNT(TCP_SLOWTIMO); 56 57 /* 58 * Search through tcb's and update active timers. 59 */ 60 ip = tcb.inp_next; 61 if (ip == 0) { 62 splx(s); 63 return; 64 } 65 for (; ip != &tcb; ip = ip->inp_next) { 66 tp = intotcpcb(ip); 67 if (tp == 0) 68 continue; 69 for (i = 0; i < TCPT_NTIMERS; i++) { 70 if (tp->t_timer[i] && --tp->t_timer[i] == 0) 71 (void) tcp_usrreq(tp->t_inpcb->inp_socket, 72 PRU_SLOWTIMO, (struct mbuf *)0, 73 (caddr_t)i); 74 } 75 tp->t_idle++; 76 if (tp->t_rtt) 77 tp->t_rtt++; 78 } 79 tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ 80 splx(s); 81 } 82 83 /* 84 * Cancel all timers for TCP tp. 85 */ 86 tcp_canceltimers(tp) 87 struct tcpcb *tp; 88 { 89 register int i; 90 91 COUNT(TCP_CANCELTIMERS); 92 for (i = 0; i < TCPT_NTIMERS; i++) 93 tp->t_timer[i] = 0; 94 } 95 96 /* 97 * TCP timer processing. 98 */ 99 tcp_timers(tp, timer) 100 register struct tcpcb *tp; 101 int timer; 102 { 103 104 COUNT(TCP_TIMERS); 105 switch (timer) { 106 107 /* 108 * 2 MSL timeout in shutdown went off. Delete connection 109 * control block. 110 */ 111 case TCPT_2MSL: 112 tcp_close(tp); 113 return; 114 115 /* 116 * Retransmission timer went off. Message has not 117 * been acked within retransmit interval. Back off 118 * to a longer retransmit interval and retransmit all 119 * unacknowledged messages in the window. 120 */ 121 case TCPT_REXMT: 122 tp->t_rxtshift++; 123 TCPT_RANGESET(tp->t_timer[TCPT_REXMT], 124 ((int)(2 * tp->t_srtt)), 125 TCPTV_MIN, TCPTV_MAX); 126 TCPT_RANGESET(tp->t_timer[TCPT_REXMT], 127 tp->t_timer[TCPT_REXMT] << tp->t_rxtshift, 128 TCPTV_MIN, TCPTV_MAX); 129 if (tp->t_timer[TCPT_REXMT] > TCPTV_MAXIDLE / 2) { 130 tcp_drop(tp, ETIMEDOUT); 131 return; 132 } 133 /* printf("rexmt set to %d\n", tp->t_timer[TCPT_REXMT]); */ 134 tp->snd_nxt = tp->snd_una; 135 /* this only transmits one segment! */ 136 (void) tcp_output(tp); 137 return; 138 139 /* 140 * Persistance timer into zero window. 141 * Force a byte to be output, if possible. 142 */ 143 case TCPT_PERSIST: 144 tp->t_force = 1; 145 (void) tcp_output(tp); 146 tp->t_force = 0; 147 TCPT_RANGESET(tp->t_timer[TCPT_PERSIST], 148 2 * tp->t_srtt, TCPTV_PERSMIN, TCPTV_MAX); 149 return; 150 151 /* 152 * Keep-alive timer went off; send something 153 * or drop connection if idle for too long. 154 */ 155 case TCPT_KEEP: 156 if (tp->t_state < TCPS_ESTABLISHED || 157 tp->t_idle >= TCPTV_MAXIDLE) { 158 tcp_drop(tp, ETIMEDOUT); 159 return; 160 } 161 if (tp->t_inpcb->inp_socket->so_options & SO_NOKEEPALIVE) 162 tp->t_idle = 0; 163 else 164 tcp_respond(tp, 165 tp->t_template, tp->rcv_nxt, tp->snd_una-1, 0); 166 tp->t_timer[TCPT_KEEP] = TCPTV_KEEP; 167 return; 168 169 #ifdef TCPTRUEOOB 170 /* 171 * Out-of-band data retransmit timer. 172 */ 173 case TCPT_OOBREXMT: 174 if (tp->t_flags & TF_NOOPT) 175 return; 176 (void) tcp_output(tp); 177 TCPT_RANGESET(tp->t_timer[TCPT_OOBREXMT], 178 2 * tp->t_srtt, TCPTV_MIN, TCPTV_MAX); 179 return; 180 #endif 181 } 182 } 183