BBR: add picoquic's cwin validation mechanism for the long-RTT hystart and avoid updating the bottleneck bandwidth when the cwin was not fully probed
@@ -157,6 +157,7 @@ typedef struct st_picoquic_bbr_state_t {
uint64_t send_quantum;
picoquic_min_max_rtt_t rtt_filter;
uint64_t target_cwnd;
+ uint64_t last_sequence_blocked;
double pacing_gain;
double cwnd_gain;
double pacing_rate;
@@ -234,6 +235,10 @@ static void picoquic_bbr_init(picoquic_cnx_t *cnx, picoquic_path_t* path_x)
memset(bbr_state, 0, sizeof(picoquic_bbr_state_t));
path_x->cwin = PICOQUIC_CWIN_INITIAL;
bbr_state->rt_prop = UINT64_MAX;
+ uint64_t current_time = picoquic_current_time();
+ bbr_state->rt_prop_stamp = current_time;
+ bbr_state->cycle_stamp = current_time;
+
BBREnterStartup(bbr_state);
BBRSetSendQuantum(bbr_state, path_x);
BBRUpdateTargetCwnd(bbr_state);
@@ -258,7 +263,10 @@ static void picoquic_bbr_delete(picoquic_cnx_t *cnx, picoquic_path_t* path_x)
void BBRUpdateBtlBw(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x)
{
uint64_t bandwidth_estimate = path_x->bandwidth_estimate;
-
+ if (bbr_state->last_sequence_blocked == 0 || !picoquic_cc_was_cwin_blocked(path_x, bbr_state->last_sequence_blocked)) {
+ // the estimation is not reliable because the CWIN was not probed entirely
+ return;
+ }
if (path_x->delivered_last_packet >= bbr_state->next_round_delivered)
{
bbr_state->next_round_delivered = path_x->delivered;
@@ -693,8 +701,9 @@ static void picoquic_bbr_notify(
bbr_state->rt_prop = rtt_measurement;
bbr_state->rt_prop_stamp = current_time;
}
-
+ if (picoquic_cc_was_cwin_blocked(path_x, bbr_state->last_sequence_blocked)) {
picoquic_hystart_increase(path_x, &bbr_state->rtt_filter, bbr_state->bytes_delivered);
+ }
bbr_state->bytes_delivered = 0;
picoquic_update_pacing_data(path_x);
@@ -714,7 +723,7 @@ static void picoquic_bbr_notify(
}
break;
case picoquic_congestion_notification_cwin_blocked:
- break;
+ bbr_state->last_sequence_blocked = picoquic_cc_get_sequence_number(path_x);
default:
/* ignore */
break;
