LCOV - code coverage report
Current view: top level - waltz - fd_rtt_est.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 15 15 100.0 %
Date: 2025-07-01 05:00:49 Functions: 2 39 5.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_waltz_fd_rtt_est_h
       2             : #define HEADER_fd_waltz_fd_rtt_est_h
       3             : 
       4             : /* fd_rtt_est.h provides an API to estimate RTT (round trip time) for
       5             :    packet transmissions to a single destination.  The 'duration' unit in
       6             :    this file is arbitrary.  Typically, it is measured in TSC ticks or
       7             :    nanoseconds. */
       8             : 
       9             : #include "../util/bits/fd_bits.h"
      10             : #include <math.h>
      11             : 
      12             : /* fd_rtt_estimate_t calculates RTT from samples according to RFC 9002
      13             :    Section 5: https://datatracker.ietf.org/doc/html/rfc9002#section-5 */
      14             : 
      15             : struct fd_rtt_estimate {
      16             :   /* Nanoseconds */
      17             :   float latest_rtt;    /* Latest sample */
      18             :   float min_rtt;       /* Smallest end-to-end RTT (trusted) */
      19             :   float smoothed_rtt;  /* EMA of last few samples */
      20             :   float var_rtt;       /* EMA of sample variance */
      21             : 
      22             :   /* is_rtt_valid indicates at least one proper sample exists of rtt */
      23             :   int is_rtt_valid;
      24             : };
      25             : 
      26             : typedef struct fd_rtt_estimate fd_rtt_estimate_t;
      27             : 
      28             : FD_PROTOTYPES_BEGIN
      29             : 
      30             : /* fd_rtt_sample adds a RTT sample to the estimate.
      31             : 
      32             :    latest_rtt is the duration elapsed since a request was sent and a
      33             :    corresponding reply was received (this value originates from local
      34             :    timestamping).  ack_delay is the duration that the peer delayed the
      35             :    reply by after receiving the request (this value is reported by the
      36             :    peer in the response).  Outside of QUIC, ack_delay is typically
      37             :    zero/unknown.
      38             : 
      39             :    est->{latest_rtt,min_rtt,smoothed_rtt,var_rtt} are updated on return.
      40             :    fd_rtt_sample is robust against a maliciously chosen ack_delay.
      41             :    smoothed_rtt and latest_rtt are bounded by the smallest end-to-end
      42             :    RTT observation _before_ adjusting by ack_delay (min_rtt). */
      43             : 
      44             : static inline void
      45             : fd_rtt_sample( fd_rtt_estimate_t * est,
      46             :                float               latest_rtt,
      47      243810 :                float               ack_delay ) {
      48      243810 :   float prev_min_rtt = fd_float_if( est->is_rtt_valid, est->min_rtt, FLT_MAX );
      49             : 
      50             :   /* min_rtt is estimated from rtt_ticks without adjusting for ack_delay */
      51      243810 :   est->min_rtt = fminf( prev_min_rtt, latest_rtt );
      52             : 
      53             :   /* smoothed_rtt is calculated from adjusted rtt_ticks
      54             :      except: ack_delay must not be subtracted if the result would be less than minrtt */
      55      243810 :   float adj_rtt = fmaxf( est->min_rtt, latest_rtt - ack_delay );
      56             : 
      57      243810 :   est->latest_rtt = adj_rtt;
      58             : 
      59             :   /* Taken directly from RFC 9002 Section 5.3 */
      60      243810 :   if( FD_UNLIKELY( !est->is_rtt_valid ) ) {
      61          30 :     est->smoothed_rtt = adj_rtt;
      62          30 :     est->var_rtt      = adj_rtt * 0.5f;
      63          30 :     est->is_rtt_valid = 1;
      64      243780 :   } else {
      65      243780 :     est->smoothed_rtt = (7.f/8.f) * est->smoothed_rtt + (1.f/8.f) * adj_rtt;
      66      243780 :     float var_rtt_sample = fabsf( est->smoothed_rtt - adj_rtt );
      67      243780 :     est->var_rtt = (3.f/4.f) * est->var_rtt + (1.f/4.f) * var_rtt_sample;
      68      243780 :   }
      69      243810 : }
      70             : 
      71             : FD_PROTOTYPES_END
      72             : 
      73             : #endif /* HEADER_fd_waltz_fd_rtt_est_h */

Generated by: LCOV version 1.14