xref: /aosp_15_r20/external/webrtc/net/dcsctp/tx/retransmission_timeout.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "net/dcsctp/tx/retransmission_timeout.h"
11 
12 #include <algorithm>
13 #include <cstdint>
14 
15 #include "net/dcsctp/public/dcsctp_options.h"
16 
17 namespace dcsctp {
18 
RetransmissionTimeout(const DcSctpOptions & options)19 RetransmissionTimeout::RetransmissionTimeout(const DcSctpOptions& options)
20     : min_rto_(*options.rto_min),
21       max_rto_(*options.rto_max),
22       max_rtt_(*options.rtt_max),
23       min_rtt_variance_(*options.min_rtt_variance),
24       scaled_srtt_(*options.rto_initial << kRttShift),
25       rto_(*options.rto_initial) {}
26 
ObserveRTT(DurationMs measured_rtt)27 void RetransmissionTimeout::ObserveRTT(DurationMs measured_rtt) {
28   const int32_t rtt = *measured_rtt;
29 
30   // Unrealistic values will be skipped. If a wrongly measured (or otherwise
31   // corrupt) value was processed, it could change the state in a way that would
32   // take a very long time to recover.
33   if (rtt < 0 || rtt > max_rtt_) {
34     return;
35   }
36 
37   // From https://tools.ietf.org/html/rfc4960#section-6.3.1, but avoiding
38   // floating point math by implementing algorithm from "V. Jacobson: Congestion
39   // avoidance and control", but adapted for SCTP.
40   if (first_measurement_) {
41     scaled_srtt_ = rtt << kRttShift;
42     scaled_rtt_var_ = (rtt / 2) << kRttVarShift;
43     first_measurement_ = false;
44   } else {
45     int32_t rtt_diff = rtt - (scaled_srtt_ >> kRttShift);
46     scaled_srtt_ += rtt_diff;
47     if (rtt_diff < 0) {
48       rtt_diff = -rtt_diff;
49     }
50     rtt_diff -= (scaled_rtt_var_ >> kRttVarShift);
51     scaled_rtt_var_ += rtt_diff;
52   }
53 
54   if (scaled_rtt_var_ < min_rtt_variance_) {
55     scaled_rtt_var_ = min_rtt_variance_;
56   }
57 
58   rto_ = (scaled_srtt_ >> kRttShift) + scaled_rtt_var_;
59 
60   // Clamp RTO between min and max.
61   rto_ = std::min(std::max(rto_, min_rto_), max_rto_);
62 }
63 }  // namespace dcsctp
64