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