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