diff options
Diffstat (limited to 'ssl/quic/quic_statm.c')
-rw-r--r-- | ssl/quic/quic_statm.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/ssl/quic/quic_statm.c b/ssl/quic/quic_statm.c new file mode 100644 index 0000000000..35f5722735 --- /dev/null +++ b/ssl/quic/quic_statm.c @@ -0,0 +1,83 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_statm.h" + +void ossl_statm_update_rtt(OSSL_STATM *statm, + OSSL_TIME ack_delay, + OSSL_TIME override_latest_rtt) +{ + OSSL_TIME adjusted_rtt, latest_rtt = override_latest_rtt; + + /* Use provided RTT value, or else last RTT value. */ + if (ossl_time_is_zero(latest_rtt)) + latest_rtt = statm->latest_rtt; + else + statm->latest_rtt = latest_rtt; + + if (!statm->have_first_sample) { + statm->min_rtt = latest_rtt; + statm->smoothed_rtt = latest_rtt; + statm->rtt_variance = ossl_time_divide(latest_rtt, 2); + statm->have_first_sample = 1; + return; + } + + /* Update minimum RTT. */ + if (ossl_time_compare(latest_rtt, statm->min_rtt) < 0) + statm->min_rtt = latest_rtt; + + /* + * Enforcement of max_ack_delay is the responsibility of + * the caller as it is context-dependent. + */ + + adjusted_rtt = latest_rtt; + if (ossl_time_compare(latest_rtt, ossl_time_add(statm->min_rtt, ack_delay)) >= 0) + adjusted_rtt = ossl_time_subtract(latest_rtt, ack_delay); + + statm->rtt_variance = ossl_time_divide(ossl_time_add(ossl_time_multiply(3, statm->rtt_variance), + ossl_time_abs_difference(statm->smoothed_rtt, + adjusted_rtt)), 4); + statm->smoothed_rtt = ossl_time_divide(ossl_time_add(ossl_time_multiply(7, statm->smoothed_rtt), + adjusted_rtt), 8); +} + +/* RFC 9002 kInitialRtt value. RFC recommended value. */ +#define K_INITIAL_RTT (ossl_time_multiply(OSSL_TIME_MS, 333)) + +int ossl_statm_init(OSSL_STATM *statm) +{ + statm->smoothed_rtt = K_INITIAL_RTT; + statm->latest_rtt = OSSL_TIME_ZERO; + statm->min_rtt = OSSL_TIME_INFINITY; + statm->rtt_variance = ossl_time_divide(K_INITIAL_RTT, 2); + statm->have_first_sample = 0; + statm->max_ack_delay = OSSL_TIME_INFINITY; + return 1; +} + +void ossl_statm_destroy(OSSL_STATM *statm) +{ + /* No-op. */ +} + +void ossl_statm_set_max_ack_delay(OSSL_STATM *statm, OSSL_TIME max_ack_delay) +{ + statm->max_ack_delay = max_ack_delay; +} + +void ossl_statm_get_rtt_info(OSSL_STATM *statm, OSSL_RTT_INFO *rtt_info) +{ + rtt_info->min_rtt = statm->min_rtt; + rtt_info->latest_rtt = statm->latest_rtt; + rtt_info->smoothed_rtt = statm->smoothed_rtt; + rtt_info->rtt_variance = statm->rtt_variance; + rtt_info->max_ack_delay = statm->max_ack_delay; +} |