Skip to content

Commit 2ddd271

Browse files
committed
Add option string for CC algo
1 parent f97146b commit 2ddd271

File tree

15 files changed

+270
-116
lines changed

15 files changed

+270
-116
lines changed

picoquic/bbr.c

Lines changed: 128 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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
144160
typedef 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

470584
static 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

picoquic/bbr1.c

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ typedef struct st_picoquic_bbr1_state_t {
278278
uint64_t congestion_sequence; /* sequence number after congestion notification */
279279
uint64_t cwin_before_suspension; /* So it can be restored if suspension stops. */
280280

281+
const char* option_string;
281282
uint64_t wifi_shadow_rtt; /* Shadow RTT used for wifi connections. */
282283
double quantum_ratio;
283284

@@ -368,13 +369,89 @@ void BBR1UpdateTargetCwnd(picoquic_bbr1_state_t* bbr1_state)
368369
bbr1_state->target_cwnd = BBR1Inflight(bbr1_state, bbr1_state->cwnd_gain);
369370
}
370371

371-
static void picoquic_bbr1_reset(picoquic_bbr1_state_t* bbr1_state, picoquic_path_t* path_x, uint64_t current_time, uint64_t wifi_shadow_rtt)
372+
373+
/* Initialization of optional variables defined in text string
374+
* Syntax:
375+
* T999999999: wifi_shadow_rtt, microseconds
376+
* Q99999.999: quantum_ratio,
377+
*
378+
*/
379+
static void picoquic_bbr1_set_options(picoquic_bbr1_state_t* bbr1_state)
380+
{
381+
const char* x = bbr1_state->option_string;
382+
383+
if (x != NULL) {
384+
char c;
385+
while ((c = *x) != 0) {
386+
x++;
387+
switch (c) {
388+
case 'T': {
389+
/* Reading digits into an uint64_t */
390+
uint64_t u = 0;
391+
while ((c = *x) != 0) {
392+
if (c >= '0' && c <= '9') {
393+
u *= 10;
394+
u += c - '0';
395+
x++;
396+
}
397+
else {
398+
break;
399+
}
400+
}
401+
bbr1_state->wifi_shadow_rtt = u;
402+
break;
403+
}
404+
case 'Q': {
405+
/* Reading digits ad one dot into a double */
406+
while ((c = *x) != 0) {
407+
double d = 0;
408+
double div = 1.0;
409+
int dotted = 0;
410+
while ((c = *x) != 0) {
411+
if (c >= '0' && c <= '9') {
412+
if (!dotted) {
413+
d *= 10;
414+
d += c - '0';
415+
}
416+
else {
417+
div /= 10.0;
418+
d += div * (c - '0');
419+
}
420+
x++;
421+
}
422+
else if (c == '.') {
423+
if (dotted) {
424+
break;
425+
}
426+
else {
427+
dotted = 1;
428+
x++;
429+
}
430+
}
431+
else {
432+
break;
433+
}
434+
}
435+
bbr1_state->quantum_ratio = d;
436+
break;
437+
}
438+
}
439+
case ':':
440+
/* Ignore */
441+
break;
442+
default:
443+
break;
444+
}
445+
}
446+
}
447+
}
448+
449+
static void picoquic_bbr1_reset(picoquic_bbr1_state_t* bbr1_state, picoquic_path_t* path_x, uint64_t current_time)
372450
{
373451
memset(bbr1_state, 0, sizeof(picoquic_bbr1_state_t));
374452
path_x->cwin = PICOQUIC_CWIN_INITIAL;
375-
bbr1_state->rt_prop = UINT64_MAX;
376-
bbr1_state->wifi_shadow_rtt = path_x->cnx->quic->wifi_shadow_rtt;
377-
bbr1_state->quantum_ratio = path_x->cnx->quic->bbr_quantum_ratio;
453+
bbr1_state->rt_prop = UINT64_MAX;
454+
picoquic_bbr1_set_options(bbr1_state);
378455
if (bbr1_state->quantum_ratio == 0) {
379456
bbr1_state->quantum_ratio = 0.001;
380457
}
@@ -389,14 +466,15 @@ static void picoquic_bbr1_reset(picoquic_bbr1_state_t* bbr1_state, picoquic_path
389466
BBR1UpdateTargetCwnd(bbr1_state);
390467
}
391468

392-
static void picoquic_bbr1_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, uint64_t current_time)
469+
static void picoquic_bbr1_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, char const* option_string, uint64_t current_time)
393470
{
394471
/* Initialize the state of the congestion control algorithm */
395472
picoquic_bbr1_state_t* bbr1_state = (picoquic_bbr1_state_t*)malloc(sizeof(picoquic_bbr1_state_t));
396473

397474
path_x->congestion_alg_state = (void*)bbr1_state;
398475
if (bbr1_state != NULL) {
399-
picoquic_bbr1_reset(bbr1_state, path_x, current_time, cnx->quic->wifi_shadow_rtt);
476+
bbr1_state->option_string = option_string;
477+
picoquic_bbr1_reset(bbr1_state, path_x, current_time);
400478
}
401479
}
402480

@@ -1210,7 +1288,7 @@ static void picoquic_bbr1_notify(
12101288
case picoquic_congestion_notification_cwin_blocked:
12111289
break;
12121290
case picoquic_congestion_notification_reset:
1213-
picoquic_bbr1_reset(bbr1_state, path_x, current_time, cnx->quic->wifi_shadow_rtt);
1291+
picoquic_bbr1_reset(bbr1_state, path_x, current_time);
12141292
break;
12151293
case picoquic_congestion_notification_seed_cwin:
12161294
if (bbr1_state->state == picoquic_bbr1_alg_startup_long_rtt) {

picoquic/config.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ static option_table_line_t option_table[] = {
6666
{ picoquic_option_SOLUTION_DIR, 'S', "solution_dir", 1, "folder", "Set the path to the source files to find the default files" },
6767
{ picoquic_option_CC_ALGO, 'G', "cc_algo", 1, "cc_algorithm",
6868
"Use the specified congestion control algorithm. Defaults to bbr. Supported values are:" },
69+
{ picoquic_option_CC_OPTION, 'H', "cco", 1, "option", "Set option string if required by congestion control algorithm."},
6970
{ picoquic_option_SPINBIT, 'P', "spinbit", 1, "number", "Set the default spinbit policy" },
7071
{ picoquic_option_LOSSBIT, 'O', "lossbit", 1, "number", "Set the default lossbit policy" },
7172
{ picoquic_option_MULTIPATH, 'M', "multipath", 0, "", "Enable QUIC multipath extension" },
@@ -292,6 +293,9 @@ static int config_set_option(option_table_line_t* option_desc, option_param_t* p
292293
case picoquic_option_CC_ALGO:
293294
ret = config_set_string_param(&config->cc_algo_id, params, nb_params, 0);
294295
break;
296+
case picoquic_option_CC_OPTION:
297+
ret = config_set_string_param(&config->cc_algo_option_string, params, nb_params, 0);
298+
break;
295299
case picoquic_option_SPINBIT: {
296300
int v = config_atoi(params, nb_params, 0, &ret);
297301
if (ret != 0 || v < 0 || v > (int)picoquic_spinbit_on) {
@@ -807,7 +811,7 @@ picoquic_quic_t* picoquic_create_and_configure(picoquic_quic_config_t* config,
807811
cc_algo = picoquic_bbr_algorithm;
808812
}
809813

810-
picoquic_set_default_congestion_algorithm(quic, cc_algo);
814+
picoquic_set_default_congestion_algorithm_ex(quic, cc_algo, config->cc_algo_option_string);
811815

812816
picoquic_set_default_spinbit_policy(quic, config->spinbit_policy);
813817
picoquic_set_default_lossbit_policy(quic, config->lossbit_policy);

picoquic/cubic.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,13 @@ static void cubic_reset(picoquic_cubic_state_t* cubic_state, picoquic_path_t* pa
6161
path_x->cwin = PICOQUIC_CWIN_INITIAL;
6262
}
6363

64-
static void cubic_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, uint64_t current_time)
64+
static void cubic_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, char const* option_string, uint64_t current_time)
6565
{
6666
/* Initialize the state of the congestion control algorithm */
6767
picoquic_cubic_state_t* cubic_state = (picoquic_cubic_state_t*)malloc(sizeof(picoquic_cubic_state_t));
6868
#ifdef _WINDOWS
6969
UNREFERENCED_PARAMETER(cnx);
70+
UNREFERENCED_PARAMETER(option_string);
7071
#endif
7172
path_x->congestion_alg_state = (void*)cubic_state;
7273
if (cubic_state != NULL) {

picoquic/fastcc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ void picoquic_fastcc_seed_cwin(picoquic_fastcc_state_t* fastcc_state, picoquic_p
9191
}
9292
}
9393

94-
void picoquic_fastcc_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, uint64_t current_time)
94+
void picoquic_fastcc_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, char const* option_string, uint64_t current_time)
9595
{
9696
/* Initialize the state of the congestion control algorithm */
9797
picoquic_fastcc_state_t* fastcc_state = path_x->congestion_alg_state;
9898
#ifdef _WINDOWS
9999
UNREFERENCED_PARAMETER(cnx);
100+
UNREFERENCED_PARAMETER(option_string);
100101
#endif
101102

102103
if (fastcc_state == NULL) {

picoquic/newreno.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,13 @@ static void picoquic_newreno_reset(picoquic_newreno_state_t* nr_state, picoquic_
186186
path_x->cwin = nr_state->nrss.cwin;
187187
}
188188

189-
static void picoquic_newreno_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, uint64_t current_time)
189+
static void picoquic_newreno_init(picoquic_cnx_t * cnx, picoquic_path_t* path_x, char const *option_string, uint64_t current_time)
190190
{
191191
/* Initialize the state of the congestion control algorithm */
192192
picoquic_newreno_state_t* nr_state = (picoquic_newreno_state_t*)malloc(sizeof(picoquic_newreno_state_t));
193193
#ifdef _WINDOWS
194194
UNREFERENCED_PARAMETER(current_time);
195+
UNREFERENCED_PARAMETER(option_string);
195196
UNREFERENCED_PARAMETER(cnx);
196197
#endif
197198

0 commit comments

Comments
 (0)