New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for 0RTT-BDP extension #1209
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work. We are on the right track. You will find lots of detailed comments in the review, but the main one is that this should be a "bdp_frame_option", leaving the current code that remembers data at the server side unchanged.
I appreciate that you added the tests!
@@ -92,6 +92,7 @@ static option_table_line_t option_table[] = { | |||
{ picoquic_option_Preemptive_Repeat, 'V', "preemptive_repeat", 0, "", "enable preemptive repeat" }, | |||
{ picoquic_option_Version_Upgrade, 'U', "version_upgrade", 1, "", "Version upgrade if server agrees, e.g. -U 00000002" }, | |||
{ picoquic_option_No_GSO, '0', "no_gso", 0, "", "Do not use UDP GSO or equivalent" }, | |||
{ picoquic_option_BDP, 'j', "bdp", 1, "number", "bdp_option: disable bdp extension(0), store bdp parameters locally(1), use bdp extension frame(2). Default=0" }, | |||
{ picoquic_option_HELP, 'h', "help", 0, "This help message" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure that this triple choice works. Over time, the "local" option can well evolve, for example to set a max delay after the previous connection, or to specify the maximum size of the LRU lists. When we do that, we will need to set a specific API and option. I would much rather keep the local store unchanged for now, and focus the present PR on just the BDP frame.
How about renaming the option to something like "picoquic_option_BDP_frame", to be more specific?
config->bdp_option = v; | ||
} | ||
break; | ||
} | ||
case picoquic_option_HELP: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above, simplify to 1 (support BDP frame) and 0 (don't).
@@ -828,6 +840,8 @@ picoquic_quic_t* picoquic_create_and_configure(picoquic_quic_config_t* config, | |||
} | |||
} | |||
|
|||
picoquic_set_default_bdp_option(quic, config->bdp_option); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue, make that specific to the bdp frame.
@@ -2217,7 +2217,7 @@ void picoquic_update_path_rtt(picoquic_cnx_t* cnx, picoquic_path_t* old_path, pi | |||
} | |||
|
|||
/* On first update, validate seeed data */ | |||
if (is_first && cnx->seed_cwin != 0){ | |||
if (is_first && cnx->seed_cwin != 0 && cnx->quic->default_bdp_option > 0){ | |||
if (cnx->seed_rtt_min <= path_x->smoothed_rtt && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather leave the current code unchanged.
if ((bytes = picoquic_parse_bdp_frame(cnx, bytes, bytes_max, &lifetime, &recon_bytes_in_flight, &recon_min_rtt)) != NULL) { | ||
/* Store received BDP */ | ||
if (cnx->quic->default_bdp_option == 2) { | ||
if (cnx->client_mode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify to yes or no test.
@@ -549,6 +552,7 @@ typedef uint64_t picoquic_tp_enum; | |||
#define picoquic_tp_enable_multipath 0xbaba | |||
#define picoquic_tp_enable_simple_multipath 0xbab5 | |||
#define picoquic_tp_version_negotiation 0x73db | |||
#define picoquic_tp_enable_bdp 0xbaba4 /* per draft-kuhn-quic-0rtt-bdp-09 */ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment on picoquic_frame_type_enum_t
. But really we should not be using the data type picoquic_frame_type_enum_t
any more, because there is no real guarantee in C on the size and sign of the integer to which an enum is mapped.
@@ -1110,6 +1115,7 @@ void picoquic_init_transport_parameters(picoquic_tp_t* tp, int client_mode) | |||
tp->enable_loss_bit = 2; | |||
tp->min_ack_delay = PICOQUIC_ACK_DELAY_MIN; | |||
tp->enable_time_stamp = 0; | |||
tp->enable_bdp = 0; | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, please change to bdp_frame option.
if (cnx->quic->default_bdp_option == 2 && (cnx->local_parameters.enable_bdp == 1 || cnx->local_parameters.enable_bdp == 3)) { | ||
bytes_next = picoquic_format_bdp_frame(cnx, bytes_next, bytes_max, path_x, &more_data, &is_pure_ack); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a test that the server sent a BDP frame in the previous session. Also, do you really intent to add a BDP frame in every 0-RTT packet?
if(!cnx->client_mode && cnx->quic->default_bdp_option == 2 && (cnx->remote_parameters.enable_bdp == 2 || cnx->remote_parameters.enable_bdp == 3)) { | ||
bytes_next = picoquic_format_bdp_frame(cnx, bytes_next, bytes_max, path_x, &more_data, &is_pure_ack); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too soon for the server -- server cannot possibly have a good value of RTT and CWIN before reaching the "ready" state. On the other hand, it might be a good idea to do that on the client, if the client did not yet have a chance to send the frame.
if(!cnx->client_mode && cnx->quic->default_bdp_option == 2 && (cnx->remote_parameters.enable_bdp == 2 || cnx->remote_parameters.enable_bdp == 3)) { | ||
bytes_next = picoquic_format_bdp_frame(cnx, bytes_next, bytes_max, path_x, &more_data, &is_pure_ack); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a better way to do that. Inside picoquic_seed_ticket
, when new values of the CWIN are learned, the code places them in the server ticket hash table. At the same time, it could post a miscellaneous frame
to queue transmission of the BDP frame.
Now that we have added the IP parameters, there are only a few issues left:
|
The logical tests are now all working, but there is was a flow control issue. The rate was limited by the value of the initial flow control parameter, which prevented taking full advantage of the increased window. I am doing a test in which this initial flow control parameter is set to a large value, but then I find another issue. The CWIN is set at a value that is too large, which causes a lot of losses and in turn slows the link: |
Added a check of the CWIN value before storing it for BDP frame transmission. The CWIN value can overshoot by the end of slow start. Using that value will cause a wild overshoot during the next connection. Instead, we cap it to estimated_bandwidth*rtt_min, which produces better results. But there is still a significant overshot. |
Fixed the overshot issues for RENO and BBR. There are still too many losses in the case of Cubic, but that investigation will have to happen later. |
This PR implements the 0RTT BDP draft. It extends this PR Remember RTT and CWIn from previous connections to allow server to offload previous connections data on the client as defined by the draft.
The BDP option added to picoquicdemo ("-j") and picoquic API ("bdp_option" ) allows to choose :
The TP enable_bdp is defined at both client and server side to negociate the extension behavior
The BDP Frame is added to carry BDP parameters
Other related mecanisms especially to hold BDP parameters and to store them, to verify that the parameters have not changed and to interact with CCs are reused from Remember RTT and CWIn from previous connections
Testing with 250 Mpbs satellite connection, the simulation shows that a 100MB upload time with bdp_option = 0 drops from just under 6 seconds to just under 4.8 seconds when remembering the CWIN and RTT (bdp_option = 1 or 2).
Since the draft is still in progress, we (@NicoKos : https://github.com/NicoKos) thought this PR can be useful.