lsquic_rtt.c revision 06b2a236
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2/*
3 * lsquic_rtt.c -- RTT calculation
4 */
5
6#include <stdlib.h>
7#include <string.h>
8#ifndef WIN32
9#include <sys/time.h>
10#endif
11
12#include "lsquic_int_types.h"
13#include "lsquic_rtt.h"
14
15/* See RFC 2988 */
16
17#define ALPHA_SHIFT 3   /* Alpha is 1/8 */
18#define BETA_SHIFT  2   /* Beta is 1/4 */
19
20
21void
22lsquic_rtt_stats_update (struct lsquic_rtt_stats *stats,
23                         lsquic_time_t send_delta, lsquic_time_t lack_delta)
24{
25    if (send_delta > lack_delta)
26        send_delta -= lack_delta;
27    if (stats->srtt) {
28        stats->rttvar -= stats->rttvar >> BETA_SHIFT;
29        // FIXED: subtracting unsigned (the (int) cast gets repromoted to uint64_t
30        // made abs() irrelevant and allowed overflow. instead cast the difference
31        // to a signed int64 and use labs() to get abs val.
32        stats->rttvar += (llabs((int64_t) (send_delta - stats->srtt)))
33                                                            >> BETA_SHIFT;
34        stats->srtt -= stats->srtt >> ALPHA_SHIFT;
35        stats->srtt += send_delta >> ALPHA_SHIFT;
36        if (send_delta < stats->min_rtt)
37            stats->min_rtt = send_delta;
38    } else {
39        /* First measurement */
40        stats->srtt   = send_delta;
41        stats->rttvar = send_delta >> 1;
42        stats->min_rtt = send_delta;
43    }
44}
45