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