1 /* tcp_timer.c 4.1 81/11/24 */ 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/inet.h" 10 #include "../net/inet_pcb.h" 11 #include "../net/inet_systm.h" 12 #include "../net/if.h" 13 #include "../net/imp.h" 14 #include "../net/ip.h" 15 #include "../net/ip_var.h" 16 #include "../net/tcp.h" 17 #include "../net/tcp_fsm.h" 18 #include "../net/tcp_var.h" 19 #include "/usr/include/errno.h" 20 21 /* 22 * Fast timeout routine for processing delayed acks 23 */ 24 tcp_fasttimo() 25 { 26 27 } 28 29 /* 30 * Tcp protocol timeout routine called every 500 ms. 31 * Updates the timers in all active tcb's and 32 * causes finite state machine actions if timers expire. 33 */ 34 tcp_slowtimo() 35 { 36 register struct inpcb *ip; 37 register struct tcpcb *tp; 38 int s = splnet(); 39 register short *tmp; 40 register int i; 41 COUNT(TCP_TIMEO); 42 43 /* 44 * Search through tcb's and update active timers. 45 */ 46 for (ip = tcb.inp_next; ip != &tcb; ip = ip->inp_next) { 47 tp = intotcpcb(ip); 48 tmp = &tp->t_init; 49 for (i = 0; i < TNTIMERS; i++) { 50 if (*tmp && --*tmp == 0) 51 (void) tcp_usrreq(tp->t_inpcb->inp_socket, 52 PRU_SLOWTIMO, (struct mbuf *)0, 53 (caddr_t)i); 54 tmp++; 55 } 56 tp->t_xmt++; 57 } 58 tcp_iss += ISSINCR/2; /* increment iss */ 59 splx(s); 60 } 61 62 /* 63 * Cancel all timers for tcp tp. 64 */ 65 tcp_tcancel(tp) 66 struct tcpcb *tp; 67 { 68 register short *tmp = &tp->t_init; 69 register int i; 70 71 for (i = 0; i < TNTIMERS; i++) 72 *tmp++ = 0; 73 } 74 75 /* 76 * TCP timer went off processing. 77 */ 78 tcp_timers(tp, timertype) 79 register struct tcpcb *tp; 80 int timertype; 81 { 82 83 COUNT(TCP_TIMERS); 84 switch (timertype) { 85 86 case TFINACK: /* fin-ack timer */ 87 switch (tp->t_state) { 88 89 case TIME_WAIT: 90 /* 91 * We can be sure our ACK of foreign FIN was rcvd, 92 * and can close if no data left for user. 93 */ 94 if (rcv_empty(tp)) { 95 tcp_disconnect(tp); 96 return (CLOSED); 97 } 98 return (RCV_WAIT); /* 17 */ 99 100 case CLOSING: 101 tp->tc_flags |= TC_WAITED_2_ML; 102 return (SAME); 103 104 default: 105 return (SAME); 106 } 107 108 case TREXMT: /* retransmission timer */ 109 if (tp->t_rexmt_val > tp->snd_una) { /* 34 */ 110 /* 111 * Set so for a retransmission, increase rexmt time 112 * in case of multiple retransmissions. 113 */ 114 tp->snd_nxt = tp->snd_una; 115 tp->tc_flags |= TC_REXMT; 116 tp->t_xmtime = tp->t_xmtime << 1; 117 if (tp->t_xmtime > T_REMAX) 118 tp->t_xmtime = T_REMAX; 119 (void) tcp_send(tp); 120 } 121 return (SAME); 122 123 case TREXMTTL: /* retransmit too long */ 124 if (tp->t_rtl_val > tp->snd_una) { /* 36 */ 125 tcp_error(tp, ETIMEDOUT); 126 return (CLOSED); 127 } 128 return (SAME); 129 130 case TPERSIST: /* persist timer */ 131 /* 132 * Force a byte send through closed window. 133 */ 134 tp->tc_flags |= TC_FORCE_ONE; 135 (void) tcp_send(tp); 136 return (SAME); 137 } 138 panic("tcp_timers"); 139 /*NOTREACHED*/ 140 } 141