1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_rtt.c -- RTT calculation
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#include <stdlib.h>
750aadb33SDmitri Tikhonov#include <string.h>
8461e84d8SAmol Deshpande#ifndef WIN32
950aadb33SDmitri Tikhonov#include <sys/time.h>
10461e84d8SAmol Deshpande#endif
1150aadb33SDmitri Tikhonov
1250aadb33SDmitri Tikhonov#include "lsquic_int_types.h"
1350aadb33SDmitri Tikhonov#include "lsquic_rtt.h"
1450aadb33SDmitri Tikhonov
1550aadb33SDmitri Tikhonov/* See RFC 2988 */
1650aadb33SDmitri Tikhonov
1750aadb33SDmitri Tikhonov#define ALPHA_SHIFT 3   /* Alpha is 1/8 */
1850aadb33SDmitri Tikhonov#define BETA_SHIFT  2   /* Beta is 1/4 */
1950aadb33SDmitri Tikhonov
2050aadb33SDmitri Tikhonov
2150aadb33SDmitri Tikhonovvoid
2250aadb33SDmitri Tikhonovlsquic_rtt_stats_update (struct lsquic_rtt_stats *stats,
2350aadb33SDmitri Tikhonov                         lsquic_time_t send_delta, lsquic_time_t lack_delta)
2450aadb33SDmitri Tikhonov{
2550aadb33SDmitri Tikhonov    if (send_delta > lack_delta)
2650aadb33SDmitri Tikhonov        send_delta -= lack_delta;
2750aadb33SDmitri Tikhonov    if (stats->srtt) {
2850aadb33SDmitri Tikhonov        stats->rttvar -= stats->rttvar >> BETA_SHIFT;
2950aadb33SDmitri Tikhonov        // FIXED: subtracting unsigned (the (int) cast gets repromoted to uint64_t
3050aadb33SDmitri Tikhonov        // made abs() irrelevant and allowed overflow. instead cast the difference
3150aadb33SDmitri Tikhonov        // to a signed int64 and use labs() to get abs val.
3250aadb33SDmitri Tikhonov        stats->rttvar += (llabs((int64_t) (send_delta - stats->srtt)))
3350aadb33SDmitri Tikhonov                                                            >> BETA_SHIFT;
3450aadb33SDmitri Tikhonov        stats->srtt -= stats->srtt >> ALPHA_SHIFT;
3550aadb33SDmitri Tikhonov        stats->srtt += send_delta >> ALPHA_SHIFT;
365392f7a3SLiteSpeed Tech        if (send_delta < stats->min_rtt)
375392f7a3SLiteSpeed Tech            stats->min_rtt = send_delta;
3850aadb33SDmitri Tikhonov    } else {
3950aadb33SDmitri Tikhonov        /* First measurement */
4050aadb33SDmitri Tikhonov        stats->srtt   = send_delta;
4150aadb33SDmitri Tikhonov        stats->rttvar = send_delta >> 1;
425392f7a3SLiteSpeed Tech        stats->min_rtt = send_delta;
4350aadb33SDmitri Tikhonov    }
4450aadb33SDmitri Tikhonov}
45