dcsctp: Add Retransmission Error Counter

This is just a simple SCTP variable, but wrapped in its own object
for convenience.

Bug: webrtc:12614
Change-Id: I0c45c356488d21b71c72a936e4ceeee5ed0ec96d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/214047
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33827}
This commit is contained in:
Victor Boivie
2021-04-05 21:53:56 +02:00
committed by Commit Bot
parent e1d60b0b58
commit f8476cc02c
4 changed files with 180 additions and 1 deletions

View File

@ -30,6 +30,17 @@ rtc_library("fcfs_send_queue") {
]
}
rtc_library("retransmission_error_counter") {
deps = [
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base_approved",
]
sources = [
"retransmission_error_counter.cc",
"retransmission_error_counter.h",
]
}
if (rtc_include_tests) {
rtc_source_set("mock_send_queue") {
testonly = true
@ -42,12 +53,16 @@ if (rtc_include_tests) {
deps = [
":fcfs_send_queue",
":retransmission_error_counter",
"../../../api:array_view",
"../../../rtc_base:checks",
"../../../rtc_base:gunit_helpers",
"../../../rtc_base:rtc_base_approved",
"../../../test:test_support",
]
sources = [ "fcfs_send_queue_test.cc" ]
sources = [
"fcfs_send_queue_test.cc",
"retransmission_error_counter_test.cc",
]
}
}

View File

@ -0,0 +1,37 @@
/*
* 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_error_counter.h"
#include "absl/strings/string_view.h"
#include "rtc_base/logging.h"
namespace dcsctp {
bool RetransmissionErrorCounter::Increment(absl::string_view reason) {
++counter_;
if (counter_ > limit_) {
RTC_DLOG(INFO) << log_prefix_ << reason
<< ", too many retransmissions, counter=" << counter_;
return false;
}
RTC_DLOG(LS_VERBOSE) << log_prefix_ << reason << ", new counter=" << counter_
<< ", max=" << limit_;
return true;
}
void RetransmissionErrorCounter::Clear() {
if (counter_ > 0) {
RTC_DLOG(LS_VERBOSE) << log_prefix_
<< "recovered from counter=" << counter_;
counter_ = 0;
}
}
} // namespace dcsctp

View File

@ -0,0 +1,51 @@
/*
* 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.
*/
#ifndef NET_DCSCTP_TX_RETRANSMISSION_ERROR_COUNTER_H_
#define NET_DCSCTP_TX_RETRANSMISSION_ERROR_COUNTER_H_
#include <functional>
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "net/dcsctp/public/dcsctp_options.h"
namespace dcsctp {
// The RetransmissionErrorCounter is a simple counter with a limit, and when
// the limit is exceeded, the counter is exhausted and the connection will
// be closed. It's incremented on retransmission errors, such as the T3-RTX
// timer expiring, but also missing heartbeats and stream reset requests.
class RetransmissionErrorCounter {
public:
RetransmissionErrorCounter(absl::string_view log_prefix,
const DcSctpOptions& options)
: log_prefix_(std::string(log_prefix) + "rtx-errors: "),
limit_(options.max_retransmissions) {}
// Increments the retransmission timer. If the maximum error count has been
// reached, `false` will be returned.
bool Increment(absl::string_view reason);
bool IsExhausted() const { return counter_ > limit_; }
// Clears the retransmission errors.
void Clear();
// Returns its current value
int value() const { return counter_; }
private:
const std::string log_prefix_;
const int limit_;
int counter_ = 0;
};
} // namespace dcsctp
#endif // NET_DCSCTP_TX_RETRANSMISSION_ERROR_COUNTER_H_

View File

@ -0,0 +1,76 @@
/*
* 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_error_counter.h"
#include "net/dcsctp/public/dcsctp_options.h"
#include "rtc_base/gunit.h"
#include "test/gmock.h"
namespace dcsctp {
namespace {
TEST(RetransmissionErrorCounterTest, HasInitialValue) {
DcSctpOptions options;
RetransmissionErrorCounter counter("log: ", options);
EXPECT_EQ(counter.value(), 0);
}
TEST(RetransmissionErrorCounterTest, ReturnsFalseAtMaximumValue) {
DcSctpOptions options;
options.max_retransmissions = 5;
RetransmissionErrorCounter counter("log: ", options);
EXPECT_TRUE(counter.Increment("test")); // 1
EXPECT_TRUE(counter.Increment("test")); // 2
EXPECT_TRUE(counter.Increment("test")); // 3
EXPECT_TRUE(counter.Increment("test")); // 4
EXPECT_TRUE(counter.Increment("test")); // 5
EXPECT_FALSE(counter.Increment("test")); // Too many retransmissions
}
TEST(RetransmissionErrorCounterTest, CanHandleZeroRetransmission) {
DcSctpOptions options;
options.max_retransmissions = 0;
RetransmissionErrorCounter counter("log: ", options);
EXPECT_FALSE(counter.Increment("test")); // One is too many.
}
TEST(RetransmissionErrorCounterTest, IsExhaustedAtMaximum) {
DcSctpOptions options;
options.max_retransmissions = 3;
RetransmissionErrorCounter counter("log: ", options);
EXPECT_TRUE(counter.Increment("test")); // 1
EXPECT_FALSE(counter.IsExhausted());
EXPECT_TRUE(counter.Increment("test")); // 2
EXPECT_FALSE(counter.IsExhausted());
EXPECT_TRUE(counter.Increment("test")); // 3
EXPECT_FALSE(counter.IsExhausted());
EXPECT_FALSE(counter.Increment("test")); // Too many retransmissions
EXPECT_TRUE(counter.IsExhausted());
EXPECT_FALSE(counter.Increment("test")); // One after too many
EXPECT_TRUE(counter.IsExhausted());
}
TEST(RetransmissionErrorCounterTest, ClearingCounter) {
DcSctpOptions options;
options.max_retransmissions = 3;
RetransmissionErrorCounter counter("log: ", options);
EXPECT_TRUE(counter.Increment("test")); // 1
EXPECT_TRUE(counter.Increment("test")); // 2
counter.Clear();
EXPECT_TRUE(counter.Increment("test")); // 1
EXPECT_TRUE(counter.Increment("test")); // 2
EXPECT_TRUE(counter.Increment("test")); // 3
EXPECT_FALSE(counter.IsExhausted());
EXPECT_FALSE(counter.Increment("test")); // Too many retransmissions
EXPECT_TRUE(counter.IsExhausted());
}
} // namespace
} // namespace dcsctp