dcsctp: Add timer safeguards and sanity checks

Ensuring that timer durations never go beyond a safe maximum duration
and that timer IDs are not re-used.

Bug: webrtc:12614
Change-Id: I227a2e9933da16669dc6ea0a39c570892010ba2c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215063
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33860}
diff --git a/net/dcsctp/timer/timer_test.cc b/net/dcsctp/timer/timer_test.cc
index 9533234..719d73e 100644
--- a/net/dcsctp/timer/timer_test.cc
+++ b/net/dcsctp/timer/timer_test.cc
@@ -310,5 +310,41 @@
   AdvanceTimeAndRunTimers(DurationMs(1000));
 }
 
+TEST_F(TimerTest, TimersHaveMaximumDuration) {
+  std::unique_ptr<Timer> t1 = manager_.CreateTimer(
+      "t1", on_expired_.AsStdFunction(),
+      TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential));
+
+  t1->set_duration(DurationMs(2 * *Timer::kMaxTimerDuration));
+  EXPECT_EQ(t1->duration(), Timer::kMaxTimerDuration);
+}
+
+TEST_F(TimerTest, TimersHaveMaximumBackoffDuration) {
+  std::unique_ptr<Timer> t1 = manager_.CreateTimer(
+      "t1", on_expired_.AsStdFunction(),
+      TimerOptions(DurationMs(1000), TimerBackoffAlgorithm::kExponential));
+
+  t1->Start();
+
+  int max_exponent = static_cast<int>(log2(*Timer::kMaxTimerDuration / 1000));
+  for (int i = 0; i < max_exponent; ++i) {
+    EXPECT_CALL(on_expired_, Call).Times(1);
+    AdvanceTimeAndRunTimers(DurationMs(1000 * (1 << i)));
+  }
+
+  // Reached the maximum duration.
+  EXPECT_CALL(on_expired_, Call).Times(1);
+  AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
+
+  EXPECT_CALL(on_expired_, Call).Times(1);
+  AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
+
+  EXPECT_CALL(on_expired_, Call).Times(1);
+  AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
+
+  EXPECT_CALL(on_expired_, Call).Times(1);
+  AdvanceTimeAndRunTimers(Timer::kMaxTimerDuration);
+}
+
 }  // namespace
 }  // namespace dcsctp