/* * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "net/dcsctp/tx/retransmission_timeout.h" #include #include "api/units/time_delta.h" #include "net/dcsctp/public/dcsctp_options.h" namespace dcsctp { // https://datatracker.ietf.org/doc/html/rfc4960#section-15. constexpr double kRtoAlpha = 0.125; constexpr double kRtoBeta = 0.25; // A factor that the `min_rtt_variance` configuration option will be divided by // (before later multiplied with K, which is 4 according to RFC6298). When this // value was introduced, it was unintentionally divided by 8 since that code // worked with scaled numbers (to avoid floating point math). That behavior is // kept as downstream users have measured good values for their use-cases. constexpr double kHeuristicVarianceAdjustment = 8.0; RetransmissionTimeout::RetransmissionTimeout(const DcSctpOptions& options) : min_rto_(options.rto_min.ToTimeDelta()), max_rto_(options.rto_max.ToTimeDelta()), max_rtt_(options.rtt_max.ToTimeDelta()), min_rtt_variance_(options.min_rtt_variance.ToTimeDelta() / kHeuristicVarianceAdjustment), srtt_(options.rto_initial.ToTimeDelta()), rto_(options.rto_initial.ToTimeDelta()) {} void RetransmissionTimeout::ObserveRTT(webrtc::TimeDelta rtt) { // Unrealistic values will be skipped. If a wrongly measured (or otherwise // corrupt) value was processed, it could change the state in a way that would // take a very long time to recover. if (rtt < webrtc::TimeDelta::Zero() || rtt > max_rtt_) { return; } // https://tools.ietf.org/html/rfc4960#section-6.3.1. if (first_measurement_) { srtt_ = rtt; rtt_var_ = rtt / 2; first_measurement_ = false; } else { webrtc::TimeDelta rtt_diff = (srtt_ - rtt).Abs(); rtt_var_ = (1 - kRtoBeta) * rtt_var_ + kRtoBeta * rtt_diff; srtt_ = (1 - kRtoAlpha) * srtt_ + kRtoAlpha * rtt; } if (rtt_var_ < min_rtt_variance_) { rtt_var_ = min_rtt_variance_; } rto_ = srtt_ + 4 * rtt_var_; rto_ = std::clamp(rto_, min_rto_, max_rto_); } } // namespace dcsctp