private-octopus / picoquic

Minimal implementation of the QUIC protocol
MIT License
523 stars 153 forks source link

Proposition of feature: Ability to bootstrap congestion algo with some values to avoid long training #1695

Closed fbussery closed 1 month ago

fbussery commented 1 month ago

In some cases, I have good estimations for upload/download bandwidth and rtt before starting a quic connexion. One simple example is a quick reboot of a device. An other case is a peer to peer mesh where all peers knows capacities from others. In such cases, I would like to avoid a long training of the bbr and start the communications at an optimal speed.

So, I'm wondering if you consider that this is feasible? If may be some bootstrap of the congestion algo could be the good entry point for such feature? Or possibly set the values directly to the path_x (i.e. set the cwin & rtt_smooth to the target value)?

huitema commented 1 month ago

Yes, that's doable. In principle, it is very close to the careful resume work. There are APIs available for use at the beginning of the connection.

joergdeutschmann-i7 commented 1 month ago

See also #1654

fbussery commented 1 month ago

Thanks a lot for your comments. I will try to understand deeper the careful resume work. Just to explain exactly our use case:

We're working on a peer to peer mesh network. For the moment, we have about 100 peers connecting together that can transfer each other some content. (peers are mostly on fiber/adsl)

We're using 2 quic instance per peer (one as client and one as server). Each peer does at early stages an estimation of its upload bandwidth & rtt using only one or two connexions among the 100 (we use the quic estimation for that). These informations are shared to all other peers. So, after a very small delay and without much transfers, we have quicky an overall view of all peers capabilities. My assumption was that it could have been possible, knowing our own caractéristics and the remote peer characteristic to bootstrap correctly the connexion path_x. I will then have a look on your "careful resume" implementation which I agree seems very close to what I expect.

wondering in fact if an easy way to seed the congestion algo would be done this way

      picoquic_path_t* path_x            = cnx->path[path_id];
      picoquic_per_ack_state_t ack_state = {0};
      cnx->seed_rtt_min                  = rtt;
      cnx->seed_cwin                     = bandwidth * rtt / 1000000;
      ack_state.nb_bytes_acknowledged    = (uint64_t)cnx->seed_cwin;
      cnx->cwin_notified_from_seed       = 1;
      picoquic_bbr1_algorithm->alg_notify(
          cnx, path_x, picoquic_congestion_notification_seed_cwin, &ack_state, current_time);
huitema commented 1 month ago

We have a preliminary implementation of careful resume in the current builds. It is an internal API, defined in picoquic_internal.h -- which means, "use at your own risks, it may change in the future. The API is:

/* seed the rtt and bandwidth discovery */
void picoquic_seed_bandwidth(picoquic_cnx_t* cnx, uint64_t rtt_min, uint64_t cwin,
    const uint8_t* ip_addr, uint8_t ip_addr_length);

The rtt_min is in microseconds, the cwin in bytes. The ipaddress, length 4 or 20 bytes, is that of the destination.

@joergdeutschmann-i7 and his teammates are working an a new version of the API, and more importantly an implementation that matches the current draft and incorporates improvements like "careful retreat" if the seeding proved to be wrong.

fbussery commented 1 month ago

But seems that picoquic_seed_bandwidth is working only during the connexion state. It is not possible to use it after. In my use case, the connexion is already established for a long time, but not used.

fbussery commented 1 month ago

Just for info. In fact I was on bbr1 and it was quite difficult for me find a way to makes thing working with this algo. I manage finally to make it with newreno.

So, I manage to seed the bandwidth/rtt on an ongoing connexion in the following way:

      picoquic_newreno_algorithm->alg_notify(
          cnx, path_x, picoquic_congestion_notification_reset, &ack_state, current_time);
      picoquic_newreno_algorithm->alg_notify(
          cnx, path_x, picoquic_congestion_notification_seed_cwin, &ack_state, current_time);

May be we can close the ticket.

huitema commented 1 month ago

The seed CWIN process is also tested with BBRv3 (what you get if you set the CC algo to BBR). But yes, it is designed to only work on a new connection, because if the connection has been going on for some time it has already sensed the appropriate value of CWIN. There is an exception if the connection was "application limited" all that time, and I suppose that was your case.