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:

committed by
Commit Bot

parent
e1d60b0b58
commit
f8476cc02c
@ -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) {
|
if (rtc_include_tests) {
|
||||||
rtc_source_set("mock_send_queue") {
|
rtc_source_set("mock_send_queue") {
|
||||||
testonly = true
|
testonly = true
|
||||||
@ -42,12 +53,16 @@ if (rtc_include_tests) {
|
|||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":fcfs_send_queue",
|
":fcfs_send_queue",
|
||||||
|
":retransmission_error_counter",
|
||||||
"../../../api:array_view",
|
"../../../api:array_view",
|
||||||
"../../../rtc_base:checks",
|
"../../../rtc_base:checks",
|
||||||
"../../../rtc_base:gunit_helpers",
|
"../../../rtc_base:gunit_helpers",
|
||||||
"../../../rtc_base:rtc_base_approved",
|
"../../../rtc_base:rtc_base_approved",
|
||||||
"../../../test:test_support",
|
"../../../test:test_support",
|
||||||
]
|
]
|
||||||
sources = [ "fcfs_send_queue_test.cc" ]
|
sources = [
|
||||||
|
"fcfs_send_queue_test.cc",
|
||||||
|
"retransmission_error_counter_test.cc",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
net/dcsctp/tx/retransmission_error_counter.cc
Normal file
37
net/dcsctp/tx/retransmission_error_counter.cc
Normal 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
|
51
net/dcsctp/tx/retransmission_error_counter.h
Normal file
51
net/dcsctp/tx/retransmission_error_counter.h
Normal 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_
|
76
net/dcsctp/tx/retransmission_error_counter_test.cc
Normal file
76
net/dcsctp/tx/retransmission_error_counter_test.cc
Normal 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
|
Reference in New Issue
Block a user