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