- TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
- (int)tp->t_srtt, TCPTV_MIN, TCPTV_MAX);
- if (tcpexprexmtbackoff) {
- TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
- tp->t_timer[TCPT_REXMT] << tp->t_rxtshift,
- TCPTV_MIN, TCPTV_MAX);
- } else {
- TCPT_RANGESET(tp->t_timer[TCPT_REXMT],
- tp->t_timer[TCPT_REXMT] *
- tcp_backoff[tp->t_rxtshift - 1],
- TCPTV_MIN, TCPTV_MAX);
+ tcpstat.tcps_rexmttimeo++;
+ rexmt = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1;
+ rexmt *= tcp_backoff[tp->t_rxtshift];
+ TCPT_RANGESET(tp->t_rxtcur, rexmt, TCPTV_MIN, TCPTV_REXMTMAX);
+ tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
+ /*
+ * If losing, let the lower level know and try for
+ * a better route. Also, if we backed off this far,
+ * our srtt estimate is probably bogus. Clobber it
+ * so we'll take the next rtt measurement as our srtt;
+ * move the current srtt into rttvar to keep the current
+ * retransmit times until then.
+ */
+ if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
+ in_losing(tp->t_inpcb);
+ tp->t_rttvar += (tp->t_srtt >> 2);
+ tp->t_srtt = 0;