+ tp = intotcpcb(inp);
+
+ if (tp == 0 || tp->t_state == TCPS_LISTEN)
+ goto tpgone;
+
+#if TRAFFIC_MGT
+ if (so->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BACKGROUND &&
+ bg_cnt > BG_COUNTER_MAX) {
+ u_int32_t curr_recvtotal = tcpstat.tcps_rcvtotal;
+ u_int32_t curr_bg_recvtotal = tcpstat.tcps_bg_rcvtotal;
+ u_int32_t bg_recvdiff = curr_bg_recvtotal - tp->bg_recv_snapshot;
+ u_int32_t tot_recvdiff = curr_recvtotal - tp->tot_recv_snapshot;
+ u_int32_t fg_recv_change = tot_recvdiff - bg_recvdiff;
+ u_int32_t recv_change;
+
+ if (!(so->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BG_SUPPRESSED)) {
+ if (tot_recvdiff)
+ recv_change = (fg_recv_change * 100) / tot_recvdiff;
+ else
+ recv_change = 0;
+
+ if (recv_change > background_io_trigger) {
+ so->so_traffic_mgt_flags |= TRAFFIC_MGT_SO_BG_SUPPRESSED;
+ }
+
+ tp->tot_recv_snapshot = curr_recvtotal;
+ tp->bg_recv_snapshot = curr_bg_recvtotal;
+ }
+ else { // SUPPRESSED
+ // this allows for bg traffic to subside before we start measuring total traffic change
+ if (tot_recvdiff)
+ recv_change = (bg_recvdiff * 100) / tot_recvdiff;
+ else
+ recv_change = 0;
+
+ if (recv_change < background_io_trigger) {
+ // Draconian for now: if there is any change at all, keep suppressed
+ if (!tot_recvdiff) {
+ so->so_traffic_mgt_flags &= ~TRAFFIC_MGT_SO_BG_SUPPRESSED;
+ tp->t_unacksegs = 0;
+ (void) tcp_output(tp); // open window
+ }
+ }
+
+ tp->tot_recv_snapshot = curr_recvtotal;
+ tp->bg_recv_snapshot = curr_bg_recvtotal;
+ }
+ }
+#endif /* TRAFFIC_MGT */
+
+ for (i = 1; i < TCPT_NTIMERS; i++) {
+ if (tp->t_timer[i] != 0) {
+ tp->t_timer[i] -= TCP_RETRANSHZ/PR_SLOWHZ;
+ if (tp->t_timer[i] <= 0) {