@@ -230,6 +230,10 @@ typedef struct st_picoquic_bbr_state_t {
230
230
uint64_t recovery_packet_number ;
231
231
uint64_t recovery_delivered ;
232
232
233
+ /* Management of lost feedback */
234
+ unsigned int is_handling_lost_feedback ;
235
+ uint64_t cwin_before_lost_feedback ;
236
+
233
237
/* Management of ECN marks */
234
238
uint64_t ecn_ect1_last_round ;
235
239
uint64_t ecn_ce_last_round ;
@@ -607,6 +611,31 @@ static void BBROnEnterFastRecovery(picoquic_bbr_state_t* bbr_state, picoquic_pat
607
611
bbr_state -> recovery_delivered = path_x -> delivered ;
608
612
}
609
613
614
+ /* Handling of the "lost feedback" state.
615
+ */
616
+ static void BBREnterLostFeedback (picoquic_bbr_state_t * bbr_state , picoquic_path_t * path_x )
617
+ {
618
+ if ((IsInAProbeBWState (bbr_state ) || bbr_state -> state == picoquic_bbr_alg_drain ) &&
619
+ !bbr_state -> is_handling_lost_feedback &&
620
+ path_x -> cnx -> cnx_state == picoquic_state_ready ) {
621
+ /* Remembering the old cwin, so the state can be restored when the
622
+ * condition is lifted. */
623
+ bbr_state -> cwin_before_lost_feedback = path_x -> cwin ;
624
+ /* setting the congestion window to exactly the bytes in transit, thus
625
+ * preventing any further transmission until the condition is lifted */
626
+ path_x -> cwin = path_x -> bytes_in_transit ;
627
+ bbr_state -> is_handling_lost_feedback = 1 ;
628
+ }
629
+ }
630
+
631
+ static void BBRExitLostFeedback (picoquic_bbr_state_t * bbr_state , picoquic_path_t * path_x )
632
+ {
633
+ if (bbr_state -> is_handling_lost_feedback ) {
634
+ path_x -> cwin = bbr_state -> cwin_before_lost_feedback ;
635
+ bbr_state -> is_handling_lost_feedback = 0 ;
636
+ }
637
+ }
638
+
610
639
/* In picoquic, the arrival of an RTO maps to a "timer based" packet loss.
611
640
* Question: do we want this on a loss signal, or simply when observing
612
641
* loss data in ack notification?
@@ -2177,18 +2206,29 @@ static void picoquic_bbr_notify(
2177
2206
BBRUpdateRecoveryOnLoss (bbr_state , path_x , ack_state -> nb_bytes_newly_lost );
2178
2207
break ;
2179
2208
case picoquic_congestion_notification_timeout :
2209
+ BBRExitLostFeedback (bbr_state , path_x );
2180
2210
/* if loss is PTO, we should start the OnPto processing */
2181
2211
BBROnEnterRTO (bbr_state , path_x , ack_state -> lost_packet_number );
2182
2212
break ;
2183
2213
case picoquic_congestion_notification_spurious_repeat :
2184
2214
/* handling of suspension */
2185
2215
BBROnSpuriousLoss (bbr_state , path_x , ack_state -> lost_packet_number , current_time );
2186
2216
break ;
2217
+ case picoquic_congestion_notification_lost_feedback :
2218
+ /* Feedback has been lost. It will be restored at the next notification. */
2219
+ #if 1
2220
+ if (current_time > 4000000 && current_time < 4300000 ) {
2221
+ DBG_PRINTF ("%s" , "Bug" );
2222
+ }
2223
+ #endif
2224
+ BBREnterLostFeedback (bbr_state , path_x );
2225
+ break ;
2187
2226
case picoquic_congestion_notification_rtt_measurement :
2188
2227
/* TODO: this call is subsumed by the acknowledgement notification.
2189
2228
* Consider removing it from the API once other CC algorithms are updated. */
2190
2229
break ;
2191
- case picoquic_congestion_notification_acknowledgement :
2230
+ case picoquic_congestion_notification_acknowledgement :
2231
+ BBRExitLostFeedback (bbr_state , path_x );
2192
2232
picoquic_bbr_notify_ack (bbr_state , path_x , ack_state , current_time );
2193
2233
if (bbr_state -> state == picoquic_bbr_alg_startup_long_rtt ) {
2194
2234
picoquic_update_pacing_data (cnx , path_x , 1 );
0 commit comments