+ tp->t_timer[TCPT_REXMT] =
+ OFFSET_FROM_START(tp, tp->t_rxtcur);
+ }
+
+ /*
+ * Set tail loss probe timeout if new data is being
+ * transmitted. This will be supported only when
+ * SACK option is enabled on a connection.
+ *
+ * Every time new data is sent PTO will get reset.
+ */
+ if (tcp_enable_tlp && tp->t_state == TCPS_ESTABLISHED &&
+ SACK_ENABLED(tp) && !IN_FASTRECOVERY(tp)
+ && tp->snd_nxt == tp->snd_max
+ && SEQ_GT(tp->snd_nxt, tp->snd_una)
+ && tp->t_rxtshift == 0
+ && (tp->t_flagsext & (TF_SENT_TLPROBE|TF_PKTS_REORDERED)) == 0) {
+ u_int32_t pto, srtt, new_rto = 0;
+
+ /*
+ * Using SRTT alone to set PTO can cause spurious
+ * retransmissions on wireless networks where there
+ * is a lot of variance in RTT. Taking variance
+ * into account will avoid this.
+ */
+ srtt = tp->t_srtt >> TCP_RTT_SHIFT;
+ pto = ((TCP_REXMTVAL(tp)) * 3) >> 1;
+ pto = max (2 * srtt, pto);
+ if ((tp->snd_max - tp->snd_una) == tp->t_maxseg)
+ pto = max(pto,
+ (((3 * pto) >> 2) + tcp_delack * 2));
+ else
+ pto = max(10, pto);
+
+ /* if RTO is less than PTO, choose RTO instead */
+ if (tp->t_rxtcur < pto) {
+ /*
+ * Schedule PTO instead of RTO in favor of
+ * fast recovery.
+ */
+ pto = tp->t_rxtcur;
+
+ /* Reset the next RTO to be after PTO. */
+ TCPT_RANGESET(new_rto,
+ (pto + TCP_REXMTVAL(tp)),
+ max(tp->t_rttmin, tp->t_rttcur + 2),
+ TCPTV_REXMTMAX, 0);
+ tp->t_timer[TCPT_REXMT] =
+ OFFSET_FROM_START(tp, new_rto);
+ }
+ tp->t_timer[TCPT_PTO] = OFFSET_FROM_START(tp, pto);