|
|
1.1 ! root 1: /* tcp_timer.c 6.1 83/07/29 */ ! 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 "../h/errno.h" ! 10: ! 11: #include "../net/if.h" ! 12: #include "../net/route.h" ! 13: ! 14: #include "../netinet/in.h" ! 15: #include "../netinet/in_pcb.h" ! 16: #include "../netinet/in_systm.h" ! 17: #include "../netinet/ip.h" ! 18: #include "../netinet/ip_var.h" ! 19: #include "../netinet/tcp.h" ! 20: #include "../netinet/tcp_fsm.h" ! 21: #include "../netinet/tcp_seq.h" ! 22: #include "../netinet/tcp_timer.h" ! 23: #include "../netinet/tcp_var.h" ! 24: #include "../netinet/tcpip.h" ! 25: ! 26: int tcpnodelack = 0; ! 27: /* ! 28: * Fast timeout routine for processing delayed acks ! 29: */ ! 30: tcp_fasttimo() ! 31: { ! 32: register struct inpcb *inp; ! 33: register struct tcpcb *tp; ! 34: int s = splnet(); ! 35: ! 36: inp = tcb.inp_next; ! 37: if (inp) ! 38: for (; inp != &tcb; inp = inp->inp_next) ! 39: if ((tp = (struct tcpcb *)inp->inp_ppcb) && ! 40: (tp->t_flags & TF_DELACK)) { ! 41: tp->t_flags &= ~TF_DELACK; ! 42: tp->t_flags |= TF_ACKNOW; ! 43: (void) tcp_output(tp); ! 44: } ! 45: splx(s); ! 46: } ! 47: ! 48: /* ! 49: * Tcp protocol timeout routine called every 500 ms. ! 50: * Updates the timers in all active tcb's and ! 51: * causes finite state machine actions if timers expire. ! 52: */ ! 53: tcp_slowtimo() ! 54: { ! 55: register struct inpcb *ip, *ipnxt; ! 56: register struct tcpcb *tp; ! 57: int s = splnet(); ! 58: register int i; ! 59: ! 60: /* ! 61: * Search through tcb's and update active timers. ! 62: */ ! 63: ip = tcb.inp_next; ! 64: if (ip == 0) { ! 65: splx(s); ! 66: return; ! 67: } ! 68: while (ip != &tcb) { ! 69: tp = intotcpcb(ip); ! 70: if (tp == 0) ! 71: continue; ! 72: ipnxt = ip->inp_next; ! 73: for (i = 0; i < TCPT_NTIMERS; i++) { ! 74: if (tp->t_timer[i] && --tp->t_timer[i] == 0) { ! 75: (void) tcp_usrreq(tp->t_inpcb->inp_socket, ! 76: PRU_SLOWTIMO, (struct mbuf *)0, ! 77: (struct mbuf *)i, (struct mbuf *)0); ! 78: if (ipnxt->inp_prev != ip) ! 79: goto tpgone; ! 80: } ! 81: } ! 82: tp->t_idle++; ! 83: if (tp->t_rtt) ! 84: tp->t_rtt++; ! 85: tpgone: ! 86: ip = ipnxt; ! 87: } ! 88: tcp_iss += TCP_ISSINCR/PR_SLOWHZ; /* increment iss */ ! 89: splx(s); ! 90: } ! 91: ! 92: /* ! 93: * Cancel all timers for TCP tp. ! 94: */ ! 95: tcp_canceltimers(tp) ! 96: struct tcpcb *tp; ! 97: { ! 98: register int i; ! 99: ! 100: for (i = 0; i < TCPT_NTIMERS; i++) ! 101: tp->t_timer[i] = 0; ! 102: } ! 103: ! 104: float tcp_backoff[TCP_MAXRXTSHIFT] = ! 105: { 1.0, 1.2, 1.4, 1.7, 2.0, 3.0, 5.0, 8.0, 16.0, 32.0 }; ! 106: int tcpexprexmtbackoff = 0; ! 107: /* ! 108: * TCP timer processing. ! 109: */ ! 110: struct tcpcb * ! 111: tcp_timers(tp, timer) ! 112: register struct tcpcb *tp; ! 113: int timer; ! 114: { ! 115: ! 116: switch (timer) { ! 117: ! 118: /* ! 119: * 2 MSL timeout in shutdown went off. Delete connection ! 120: * control block. ! 121: */ ! 122: case TCPT_2MSL: ! 123: tp = tcp_close(tp); ! 124: break; ! 125: ! 126: /* ! 127: * Retransmission timer went off. Message has not ! 128: * been acked within retransmit interval. Back off ! 129: * to a longer retransmit interval and retransmit all ! 130: * unacknowledged messages in the window. ! 131: */ ! 132: case TCPT_REXMT: ! 133: tp->t_rxtshift++; ! 134: if (tp->t_rxtshift > TCP_MAXRXTSHIFT) { ! 135: tp = tcp_drop(tp, ETIMEDOUT); ! 136: break; ! 137: } ! 138: TCPT_RANGESET(tp->t_timer[TCPT_REXMT], ! 139: (int)tp->t_srtt, TCPTV_MIN, TCPTV_MAX); ! 140: if (tcpexprexmtbackoff) { ! 141: TCPT_RANGESET(tp->t_timer[TCPT_REXMT], ! 142: tp->t_timer[TCPT_REXMT] << tp->t_rxtshift, ! 143: TCPTV_MIN, TCPTV_MAX); ! 144: } else { ! 145: TCPT_RANGESET(tp->t_timer[TCPT_REXMT], ! 146: tp->t_timer[TCPT_REXMT] * ! 147: tcp_backoff[tp->t_rxtshift - 1], ! 148: TCPTV_MIN, TCPTV_MAX); ! 149: } ! 150: tp->snd_nxt = tp->snd_una; ! 151: /* this only transmits one segment! */ ! 152: (void) tcp_output(tp); ! 153: break; ! 154: ! 155: /* ! 156: * Persistance timer into zero window. ! 157: * Force a byte to be output, if possible. ! 158: */ ! 159: case TCPT_PERSIST: ! 160: tcp_setpersist(tp); ! 161: tp->t_force = 1; ! 162: (void) tcp_output(tp); ! 163: tp->t_force = 0; ! 164: break; ! 165: ! 166: /* ! 167: * Keep-alive timer went off; send something ! 168: * or drop connection if idle for too long. ! 169: */ ! 170: case TCPT_KEEP: ! 171: if (tp->t_state < TCPS_ESTABLISHED) ! 172: goto dropit; ! 173: if (tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) { ! 174: if (tp->t_idle >= TCPTV_MAXIDLE) ! 175: goto dropit; ! 176: /* ! 177: * Saying tp->rcv_nxt-1 lies about what ! 178: * we have received, and by the protocol spec ! 179: * requires the correspondent TCP to respond. ! 180: * Saying tp->snd_una-1 causes the transmitted ! 181: * byte to lie outside the receive window; this ! 182: * is important because we don't necessarily ! 183: * have a byte in the window to send (consider ! 184: * a one-way stream!) ! 185: */ ! 186: tcp_respond(tp, ! 187: tp->t_template, tp->rcv_nxt-1, tp->snd_una-1, 0); ! 188: } else ! 189: tp->t_idle = 0; ! 190: tp->t_timer[TCPT_KEEP] = TCPTV_KEEP; ! 191: break; ! 192: dropit: ! 193: tp = tcp_drop(tp, ETIMEDOUT); ! 194: break; ! 195: } ! 196: return (tp); ! 197: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.