@@ -141,6 +141,22 @@ typedef enum {
141141
142142#define BBRExcessiveEcnCE 0.2
143143
144+ /* Temporary code, do define a set of BBR flags that
145+ * turn on and off individual extensions. We want to use that
146+ * to do "before/after" measurements.
147+ */
148+ #define BBRExperiment on
149+ #ifdef BBRExperiment
150+ /* Control flags for BBR improvements */
151+ typedef struct st_bbr_exp {
152+ unsigned int do_early_exit : 1 ;
153+ unsigned int do_rapid_start : 1 ;
154+ unsigned int do_handle_suspension : 1 ;
155+ unsigned int do_control_lost : 1 ;
156+ unsigned int do_exit_probeBW_up_on_delay : 1 ;
157+ unsigned int do_enter_probeBW_after_limited : 1 ;
158+ } bbr_exp ;
159+ #endif
144160typedef struct st_picoquic_bbr_state_t {
145161 /* Algorithm state: */
146162 picoquic_bbr_alg_state_t state ;
@@ -260,13 +276,13 @@ typedef struct st_picoquic_bbr_state_t {
260276 unsigned int probe_bdp_seed ;
261277
262278 /* Experimental extensions, may or maynot be a good idea. */
279+ char const * option_string ;
263280 uint64_t wifi_shadow_rtt ; /* Shadow RTT used for wifi connections. */
264281 double quantum_ratio ; /* allow application to use a different default than 0.1% of bandwidth (or 1ms of traffic) */
265282#ifdef BBRExperiment
266283 /* Control flags for BBR improvements */
267284 bbr_exp exp_flags ;
268285#endif
269-
270286} picoquic_bbr_state_t ;
271287
272288/* BBR v3 assumes that there is state associated with the acknowledgements.
@@ -422,13 +438,118 @@ static void BBRInitFullPipe(picoquic_bbr_state_t* bbr_state)
422438 bbr_state -> full_bw_count = 0 ;
423439}
424440
441+ /* Initialization of optional variables defined in text string
442+ * Syntax:
443+ * - Single letter options, all optional:
444+ * E: do_early_exit
445+ * R: do_rapid_start
446+ * H: do_handle_suspension
447+ * L: do_control_lost
448+ * D: do_exit_probeBW_up_on_delay
449+ * A: do_enter_probeBW_after_limited
450+ * - Complex options, ends with ':'
451+ * T999999999: wifi_shadow_rtt, microseconds
452+ * Q99999.999: quantum_ratio, %
453+ *
454+ */
455+ static void BBRSetOptions (picoquic_bbr_state_t * bbr_state )
456+ {
457+ const char * x = bbr_state -> option_string ;
458+
459+ if (x != NULL ) {
460+ char c ;
461+ while ((c = * x ) != 0 ) {
462+ x ++ ;
463+ switch (c ) {
464+ #ifdef BBRExperiment
465+ case 'E' :
466+ bbr_state -> exp_flags .do_early_exit = 1 ;
467+ break ;
468+ case 'R' :
469+ bbr_state -> exp_flags .do_rapid_start = 1 ;
470+ break ;
471+ case 'H' :
472+ bbr_state -> exp_flags .do_handle_suspension = 1 ;
473+ break ;
474+ case 'L' :
475+ bbr_state -> exp_flags .do_control_lost = 1 ;
476+ break ;
477+ case 'D' :
478+ bbr_state -> exp_flags .do_exit_probeBW_up_on_delay = 1 ;
479+ break ;
480+ case 'A' :
481+ bbr_state -> exp_flags .do_enter_probeBW_after_limited = 1 ;
482+ break ;
483+ #endif
484+ case 'T' : {
485+ /* Reading digits into an uint64_t */
486+ uint64_t u = 0 ;
487+ while ((c = * x ) != 0 ) {
488+ if (c >= '0' && c <= '9' ) {
489+ u *= 10 ;
490+ u += c - '0' ;
491+ x ++ ;
492+ }
493+ else {
494+ break ;
495+ }
496+ }
497+ bbr_state -> wifi_shadow_rtt = u ;
498+ break ;
499+ }
500+ case 'Q' : {
501+ /* Reading digits ad one dot into a double */
502+ while ((c = * x ) != 0 ) {
503+ double d = 0 ;
504+ double div = 1.0 ;
505+ int dotted = 0 ;
506+ while ((c = * x ) != 0 ) {
507+ if (c >= '0' && c <= '9' ) {
508+ if (!dotted ) {
509+ d *= 10 ;
510+ d += c - '0' ;
511+ }
512+ else {
513+ div /= 10.0 ;
514+ d += div * (c - '0' );
515+ }
516+ x ++ ;
517+ }
518+ else if (c == '.' ) {
519+ if (dotted ) {
520+ break ;
521+ }
522+ else {
523+ dotted = 1 ;
524+ x ++ ;
525+ }
526+ }
527+ else {
528+ break ;
529+ }
530+ }
531+ bbr_state -> quantum_ratio = d ;
532+ break ;
533+ }
534+ }
535+ case ':' :
536+ /* Ignore */
537+ break ;
538+ default :
539+ break ;
540+ }
541+ }
542+ }
543+ }
544+
425545/* Initialization of the BBR state */
426- static void BBROnInit (picoquic_bbr_state_t * bbr_state , picoquic_path_t * path_x , uint64_t current_time )
546+ static void BBROnInit (picoquic_bbr_state_t * bbr_state , picoquic_path_t * path_x , uint64_t current_time , char const * option_string )
427547{
428548 /* TODO:
429549 init_windowed_max_filter(filter = BBR.MaxBwFilter, value = 0, time = 0)
430550 */
431551 memset (bbr_state , 0 , sizeof (picoquic_bbr_state_t ));
552+ bbr_state -> option_string = option_string ;
432553 BBRInitRandom (bbr_state , path_x , current_time );
433554 /* If RTT was already sampled, use it, other wise set min RTT to infinity */
434555 if (path_x -> smoothed_rtt == PICOQUIC_INITIAL_RTT
@@ -446,15 +567,8 @@ static void BBROnInit(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x,
446567 bbr_state -> min_rtt_stamp = current_time ;
447568 bbr_state -> extra_acked_interval_start = current_time ;
448569 bbr_state -> extra_acked_delivered = 0 ;
449- /* Support for the wifi_shadow_rtt hack */
450- bbr_state -> wifi_shadow_rtt = path_x -> cnx -> quic -> wifi_shadow_rtt ;
451-
452- #ifdef BBRExperiment
453- /* Support for BBR Experiment */
454- bbr_state -> exp_flags = path_x -> cnx -> quic -> bbr_exp_flags ;
455- #endif
456- /* Support for experimenting with the send_quantum ratio */
457- bbr_state -> quantum_ratio = path_x -> cnx -> quic -> bbr_quantum_ratio ;
570+ /* Support for the experimental options */
571+ BBRSetOptions (bbr_state );
458572 if (bbr_state -> quantum_ratio == 0 ) {
459573 bbr_state -> quantum_ratio = 0.001 ;
460574 }
@@ -469,17 +583,17 @@ static void BBROnInit(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x,
469583
470584static void picoquic_bbr_reset (picoquic_bbr_state_t * bbr_state , picoquic_path_t * path_x , uint64_t current_time )
471585{
472- BBROnInit (bbr_state , path_x , current_time );
586+ BBROnInit (bbr_state , path_x , current_time , bbr_state -> option_string );
473587}
474588
475- static void picoquic_bbr_init (picoquic_cnx_t * cnx , picoquic_path_t * path_x , uint64_t current_time )
589+ static void picoquic_bbr_init (picoquic_cnx_t * cnx , picoquic_path_t * path_x , char const * option_string , uint64_t current_time )
476590{
477591 /* Initialize the state of the congestion control algorithm */
478592 picoquic_bbr_state_t * bbr_state = (picoquic_bbr_state_t * )malloc (sizeof (picoquic_bbr_state_t ));
479593
480594 path_x -> congestion_alg_state = (void * )bbr_state ;
481595 if (bbr_state != NULL ) {
482- BBROnInit (bbr_state , path_x , current_time );
596+ BBROnInit (bbr_state , path_x , current_time , option_string );
483597 }
484598}
485599
0 commit comments