Home | History | Annotate | Line # | Download | only in quic
      1 /*
      2  * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include "internal/quic_statm.h"
     11 
     12 void ossl_statm_update_rtt(OSSL_STATM *statm,
     13     OSSL_TIME ack_delay,
     14     OSSL_TIME override_latest_rtt)
     15 {
     16     OSSL_TIME adjusted_rtt, latest_rtt = override_latest_rtt;
     17 
     18     /* Use provided RTT value, or else last RTT value. */
     19     if (ossl_time_is_zero(latest_rtt))
     20         latest_rtt = statm->latest_rtt;
     21     else
     22         statm->latest_rtt = latest_rtt;
     23 
     24     if (!statm->have_first_sample) {
     25         statm->min_rtt = latest_rtt;
     26         statm->smoothed_rtt = latest_rtt;
     27         statm->rtt_variance = ossl_time_divide(latest_rtt, 2);
     28         statm->have_first_sample = 1;
     29         return;
     30     }
     31 
     32     /* Update minimum RTT. */
     33     if (ossl_time_compare(latest_rtt, statm->min_rtt) < 0)
     34         statm->min_rtt = latest_rtt;
     35 
     36     /*
     37      * Enforcement of max_ack_delay is the responsibility of
     38      * the caller as it is context-dependent.
     39      */
     40 
     41     adjusted_rtt = latest_rtt;
     42     if (ossl_time_compare(latest_rtt, ossl_time_add(statm->min_rtt, ack_delay)) >= 0)
     43         adjusted_rtt = ossl_time_subtract(latest_rtt, ack_delay);
     44 
     45     statm->rtt_variance = ossl_time_divide(ossl_time_add(ossl_time_multiply(statm->rtt_variance, 3),
     46                                                ossl_time_abs_difference(statm->smoothed_rtt,
     47                                                    adjusted_rtt)),
     48         4);
     49     statm->smoothed_rtt = ossl_time_divide(ossl_time_add(ossl_time_multiply(statm->smoothed_rtt, 7),
     50                                                adjusted_rtt),
     51         8);
     52 }
     53 
     54 /* RFC 9002 kInitialRtt value. RFC recommended value. */
     55 #define K_INITIAL_RTT ossl_ms2time(333)
     56 
     57 int ossl_statm_init(OSSL_STATM *statm)
     58 {
     59     statm->smoothed_rtt = K_INITIAL_RTT;
     60     statm->latest_rtt = ossl_time_zero();
     61     statm->min_rtt = ossl_time_infinite();
     62     statm->rtt_variance = ossl_time_divide(K_INITIAL_RTT, 2);
     63     statm->have_first_sample = 0;
     64     return 1;
     65 }
     66 
     67 void ossl_statm_destroy(OSSL_STATM *statm)
     68 {
     69     /* No-op. */
     70 }
     71 
     72 void ossl_statm_get_rtt_info(OSSL_STATM *statm, OSSL_RTT_INFO *rtt_info)
     73 {
     74     rtt_info->min_rtt = statm->min_rtt;
     75     rtt_info->latest_rtt = statm->latest_rtt;
     76     rtt_info->smoothed_rtt = statm->smoothed_rtt;
     77     rtt_info->rtt_variance = statm->rtt_variance;
     78 }
     79