if (tcp_opts_tstamp (&tc->rcv_opts))
{
opts->flags |= TCP_OPTS_FLAG_TSTAMP;
- opts->tsval = tcp_time_now_w_thread (tc->c_thread_index);
+ opts->tsval = tcp_tstamp (tc);
opts->tsecr = tc->tsval_recent;
len += TCP_OPTION_LEN_TIMESTAMP;
}
if (tc->flags & TCP_CONN_RATE_SAMPLE)
tc->flags |= TCP_CONN_TRACK_BURST;
+
+ if (tc->snd_una == tc->snd_nxt)
+ tcp_cc_event (tc, TCP_CC_EVT_START_TX);
}
void
* Reset congestion control, switch cwnd to loss window and try again.
*/
static void
-tcp_rxt_timeout_cc (tcp_connection_t * tc)
+tcp_cc_init_rxt_timeout (tcp_connection_t * tc)
{
TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 6);
tc->prev_ssthresh = tc->ssthresh;
tc->prev_cwnd = tc->cwnd;
- /* Cleanly recover cc (also clears up fast retransmit) */
+ /* Clear fast recovery state if needed */
if (tcp_in_fastrecovery (tc))
- {
- /* TODO be less aggressive about this */
- scoreboard_clear (&tc->sack_sb);
- tcp_cc_fastrecovery_exit (tc);
- }
- else
- tc->rcv_dupacks = 0;
+ tcp_cc_fastrecovery_clear (tc);
+
+ /* Let cc algo decide loss cwnd and ssthresh */
+ tcp_cc_loss (tc);
/* Start again from the beginning */
- tc->cc_algo->congestion (tc);
- tc->cwnd = tcp_loss_wnd (tc);
tc->snd_congestion = tc->snd_nxt;
+ tc->rcv_dupacks = 0;
tc->rtt_ts = 0;
tc->cwnd_acc_bytes = 0;
tcp_connection_tx_pacer_reset (tc, tc->cwnd, 2 * tc->snd_mss);
* to first un-acked byte */
tc->rto_boff += 1;
+ /* TODO be less aggressive about clearing scoreboard */
+ scoreboard_clear (&tc->sack_sb);
+
/* First retransmit timeout */
if (tc->rto_boff == 1)
- tcp_rxt_timeout_cc (tc);
- else
- scoreboard_clear (&tc->sack_sb);
+ tcp_cc_init_rxt_timeout (tc);
if (tc->flags & TCP_CONN_RATE_SAMPLE)
tcp_bt_flush_samples (tc);
/* For first retransmit, record timestamp (Eifel detection RFC3522) */
if (tc->rto_boff == 1)
- tc->snd_rxt_ts = tcp_time_now_w_thread (tc->c_thread_index);
+ tc->snd_rxt_ts = tcp_tstamp (tc);
tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
tcp_retransmit_timer_force_update (tc);