dcsctp: Allow heartbeats to be disabled
This is useful in tests and in scenarios where the connection is monitored externally and the heartbeat monitoring would be of no use. Bug: webrtc:12614 Change-Id: Ida4f4e2e40fc4d2aa0c27ae9431f434da4cc8313 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/220766 Reviewed-by: Florent Castelli <orphis@webrtc.org> Commit-Queue: Victor Boivie <boivie@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34164}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
02df2eb1de
commit
5429d71022
@ -112,7 +112,7 @@ struct DcSctpOptions {
|
|||||||
// T2-shutdown timeout.
|
// T2-shutdown timeout.
|
||||||
DurationMs t2_shutdown_timeout = DurationMs(1000);
|
DurationMs t2_shutdown_timeout = DurationMs(1000);
|
||||||
|
|
||||||
// Hearbeat interval (on idle connections only).
|
// Hearbeat interval (on idle connections only). Set to zero to disable.
|
||||||
DurationMs heartbeat_interval = DurationMs(30000);
|
DurationMs heartbeat_interval = DurationMs(30000);
|
||||||
|
|
||||||
// The maximum time when a SACK will be sent from the arrival of an
|
// The maximum time when a SACK will be sent from the arrival of an
|
||||||
|
@ -104,10 +104,15 @@ HeartbeatHandler::HeartbeatHandler(absl::string_view log_prefix,
|
|||||||
TimerBackoffAlgorithm::kExponential,
|
TimerBackoffAlgorithm::kExponential,
|
||||||
/*max_restarts=*/0))) {
|
/*max_restarts=*/0))) {
|
||||||
// The interval timer must always be running as long as the association is up.
|
// The interval timer must always be running as long as the association is up.
|
||||||
interval_timer_->Start();
|
RestartTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HeartbeatHandler::RestartTimer() {
|
void HeartbeatHandler::RestartTimer() {
|
||||||
|
if (interval_duration_ == DurationMs(0)) {
|
||||||
|
// Heartbeating has been disabled.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (interval_duration_should_include_rtt_) {
|
if (interval_duration_should_include_rtt_) {
|
||||||
// The RTT should be used, but it's not easy accessible. The RTO will
|
// The RTT should be used, but it's not easy accessible. The RTO will
|
||||||
// suffice.
|
// suffice.
|
||||||
|
@ -30,17 +30,19 @@ using ::testing::NiceMock;
|
|||||||
using ::testing::Return;
|
using ::testing::Return;
|
||||||
using ::testing::SizeIs;
|
using ::testing::SizeIs;
|
||||||
|
|
||||||
DcSctpOptions MakeOptions() {
|
constexpr DurationMs kHeartbeatInterval = DurationMs(30'000);
|
||||||
|
|
||||||
|
DcSctpOptions MakeOptions(DurationMs heartbeat_interval) {
|
||||||
DcSctpOptions options;
|
DcSctpOptions options;
|
||||||
options.heartbeat_interval_include_rtt = false;
|
options.heartbeat_interval_include_rtt = false;
|
||||||
options.heartbeat_interval = DurationMs(30'000);
|
options.heartbeat_interval = heartbeat_interval;
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HeartbeatHandlerTest : public testing::Test {
|
class HeartbeatHandlerTestBase : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
HeartbeatHandlerTest()
|
explicit HeartbeatHandlerTestBase(DurationMs heartbeat_interval)
|
||||||
: options_(MakeOptions()),
|
: options_(MakeOptions(heartbeat_interval)),
|
||||||
context_(&callbacks_),
|
context_(&callbacks_),
|
||||||
timer_manager_([this]() { return callbacks_.CreateTimeout(); }),
|
timer_manager_([this]() { return callbacks_.CreateTimeout(); }),
|
||||||
handler_("log: ", options_, &context_, &timer_manager_) {}
|
handler_("log: ", options_, &context_, &timer_manager_) {}
|
||||||
@ -63,6 +65,31 @@ class HeartbeatHandlerTest : public testing::Test {
|
|||||||
HeartbeatHandler handler_;
|
HeartbeatHandler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class HeartbeatHandlerTest : public HeartbeatHandlerTestBase {
|
||||||
|
protected:
|
||||||
|
HeartbeatHandlerTest() : HeartbeatHandlerTestBase(kHeartbeatInterval) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DisabledHeartbeatHandlerTest : public HeartbeatHandlerTestBase {
|
||||||
|
protected:
|
||||||
|
DisabledHeartbeatHandlerTest() : HeartbeatHandlerTestBase(DurationMs(0)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(HeartbeatHandlerTest, HasRunningHeartbeatIntervalTimer) {
|
||||||
|
AdvanceTime(options_.heartbeat_interval);
|
||||||
|
|
||||||
|
// Validate that a heartbeat request was sent.
|
||||||
|
std::vector<uint8_t> payload = callbacks_.ConsumeSentPacket();
|
||||||
|
ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet, SctpPacket::Parse(payload));
|
||||||
|
ASSERT_THAT(packet.descriptors(), SizeIs(1));
|
||||||
|
|
||||||
|
ASSERT_HAS_VALUE_AND_ASSIGN(
|
||||||
|
HeartbeatRequestChunk request,
|
||||||
|
HeartbeatRequestChunk::Parse(packet.descriptors()[0].data));
|
||||||
|
|
||||||
|
EXPECT_TRUE(request.info().has_value());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(HeartbeatHandlerTest, RepliesToHeartbeatRequests) {
|
TEST_F(HeartbeatHandlerTest, RepliesToHeartbeatRequests) {
|
||||||
uint8_t info_data[] = {1, 2, 3, 4, 5};
|
uint8_t info_data[] = {1, 2, 3, 4, 5};
|
||||||
HeartbeatRequestChunk request(
|
HeartbeatRequestChunk request(
|
||||||
@ -120,5 +147,12 @@ TEST_F(HeartbeatHandlerTest, IncreasesErrorIfNotAckedInTime) {
|
|||||||
AdvanceTime(rto);
|
AdvanceTime(rto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DisabledHeartbeatHandlerTest, IsReallyDisabled) {
|
||||||
|
AdvanceTime(options_.heartbeat_interval);
|
||||||
|
|
||||||
|
// Validate that a request was NOT sent.
|
||||||
|
EXPECT_THAT(callbacks_.ConsumeSentPacket(), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace dcsctp
|
} // namespace dcsctp
|
||||||
|
Reference in New Issue
Block a user