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)), 4); 48 statm->smoothed_rtt = ossl_time_divide(ossl_time_add(ossl_time_multiply(statm->smoothed_rtt, 7), 49 adjusted_rtt), 8); 50 } 51 52 /* RFC 9002 kInitialRtt value. RFC recommended value. */ 53 #define K_INITIAL_RTT ossl_ms2time(333) 54 55 int ossl_statm_init(OSSL_STATM *statm) 56 { 57 statm->smoothed_rtt = K_INITIAL_RTT; 58 statm->latest_rtt = ossl_time_zero(); 59 statm->min_rtt = ossl_time_infinite(); 60 statm->rtt_variance = ossl_time_divide(K_INITIAL_RTT, 2); 61 statm->have_first_sample = 0; 62 return 1; 63 } 64 65 void ossl_statm_destroy(OSSL_STATM *statm) 66 { 67 /* No-op. */ 68 } 69 70 void ossl_statm_get_rtt_info(OSSL_STATM *statm, OSSL_RTT_INFO *rtt_info) 71 { 72 rtt_info->min_rtt = statm->min_rtt; 73 rtt_info->latest_rtt = statm->latest_rtt; 74 rtt_info->smoothed_rtt = statm->smoothed_rtt; 75 rtt_info->rtt_variance = statm->rtt_variance; 76 } 77