dcsctp: Fix post-review comments for DataTracker

These are some fixes that were added after submission of
https://webrtc-review.googlesource.com/c/src/+/213664

Mainly:

 * Don't accept TSNs that have a too large difference from expected
 * Renaming of member variable (to confirm to style guidelines)

Bug: webrtc:12614
Change-Id: I06e11ab2acf5d307b68c3cbc135fde2c038ee690
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/215070
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33721}
diff --git a/net/dcsctp/rx/data_tracker.cc b/net/dcsctp/rx/data_tracker.cc
index b95cb44..3e03dfe 100644
--- a/net/dcsctp/rx/data_tracker.cc
+++ b/net/dcsctp/rx/data_tracker.cc
@@ -26,9 +26,30 @@
 
 namespace dcsctp {
 
+bool DataTracker::IsTSNValid(TSN tsn) const {
+  UnwrappedTSN unwrapped_tsn = tsn_unwrapper_.PeekUnwrap(tsn);
+
+  // Note that this method doesn't return `false` for old DATA chunks, as those
+  // are actually valid, and receiving those may affect the generated SACK
+  // response (by setting "duplicate TSNs").
+
+  uint32_t difference =
+      UnwrappedTSN::Difference(unwrapped_tsn, last_cumulative_acked_tsn_);
+  if (difference > kMaxAcceptedOutstandingFragments) {
+    return false;
+  }
+  return true;
+}
+
 void DataTracker::Observe(TSN tsn,
                           AnyDataChunk::ImmediateAckFlag immediate_ack) {
   UnwrappedTSN unwrapped_tsn = tsn_unwrapper_.Unwrap(tsn);
+
+  // IsTSNValid must be called prior to calling this method.
+  RTC_DCHECK(
+      UnwrappedTSN::Difference(unwrapped_tsn, last_cumulative_acked_tsn_) <=
+      kMaxAcceptedOutstandingFragments);
+
   // Old chunk already seen before?
   if (unwrapped_tsn <= last_cumulative_acked_tsn_) {
     // TODO(boivie) Set duplicate TSN, even if it's not used in SCTP yet.
@@ -38,14 +59,14 @@
   if (unwrapped_tsn == last_cumulative_acked_tsn_.next_value()) {
     last_cumulative_acked_tsn_ = unwrapped_tsn;
     // The cumulative acked tsn may be moved even further, if a gap was filled.
-    while (!additional_tsns.empty() &&
-           *additional_tsns.begin() ==
+    while (!additional_tsns_.empty() &&
+           *additional_tsns_.begin() ==
                last_cumulative_acked_tsn_.next_value()) {
       last_cumulative_acked_tsn_.Increment();
-      additional_tsns.erase(additional_tsns.begin());
+      additional_tsns_.erase(additional_tsns_.begin());
     }
   } else {
-    additional_tsns.insert(unwrapped_tsn);
+    additional_tsns_.insert(unwrapped_tsn);
   }
 
   // https://tools.ietf.org/html/rfc4960#section-6.7
@@ -54,7 +75,7 @@
   // the received DATA chunk sequence, it SHOULD send a SACK with Gap Ack
   // Blocks immediately.  The data receiver continues sending a SACK after
   // receipt of each SCTP packet that doesn't fill the gap."
-  if (!additional_tsns.empty()) {
+  if (!additional_tsns_.empty()) {
     UpdateAckState(AckState::kImmediate, "packet loss");
   }
 
@@ -119,15 +140,15 @@
   // now overlapping with the new value, remove them.
   last_cumulative_acked_tsn_ = unwrapped_tsn;
   int erased_additional_tsns = std::distance(
-      additional_tsns.begin(), additional_tsns.upper_bound(unwrapped_tsn));
-  additional_tsns.erase(additional_tsns.begin(),
-                        additional_tsns.upper_bound(unwrapped_tsn));
+      additional_tsns_.begin(), additional_tsns_.upper_bound(unwrapped_tsn));
+  additional_tsns_.erase(additional_tsns_.begin(),
+                         additional_tsns_.upper_bound(unwrapped_tsn));
 
   // See if the `last_cumulative_acked_tsn_` can be moved even further:
-  while (!additional_tsns.empty() &&
-         *additional_tsns.begin() == last_cumulative_acked_tsn_.next_value()) {
+  while (!additional_tsns_.empty() &&
+         *additional_tsns_.begin() == last_cumulative_acked_tsn_.next_value()) {
     last_cumulative_acked_tsn_.Increment();
-    additional_tsns.erase(additional_tsns.begin());
+    additional_tsns_.erase(additional_tsns_.begin());
     ++erased_additional_tsns;
   }
 
@@ -179,17 +200,17 @@
 
   auto flush = [&]() {
     if (first_tsn_in_block.has_value()) {
-      int start_diff = UnwrappedTSN::Difference(*first_tsn_in_block,
-                                                last_cumulative_acked_tsn_);
-      int end_diff = UnwrappedTSN::Difference(*last_tsn_in_block,
-                                              last_cumulative_acked_tsn_);
+      auto start_diff = UnwrappedTSN::Difference(*first_tsn_in_block,
+                                                 last_cumulative_acked_tsn_);
+      auto end_diff = UnwrappedTSN::Difference(*last_tsn_in_block,
+                                               last_cumulative_acked_tsn_);
       gap_ack_blocks.emplace_back(static_cast<uint16_t>(start_diff),
                                   static_cast<uint16_t>(end_diff));
       first_tsn_in_block = absl::nullopt;
       last_tsn_in_block = absl::nullopt;
     }
   };
-  for (UnwrappedTSN tsn : additional_tsns) {
+  for (UnwrappedTSN tsn : additional_tsns_) {
     if (last_tsn_in_block.has_value() &&
         last_tsn_in_block->next_value() == tsn) {
       // Continuing the same block.
diff --git a/net/dcsctp/rx/data_tracker.h b/net/dcsctp/rx/data_tracker.h
index a528967..6146d2a 100644
--- a/net/dcsctp/rx/data_tracker.h
+++ b/net/dcsctp/rx/data_tracker.h
@@ -38,6 +38,13 @@
 // 200ms, whatever is smallest).
 class DataTracker {
  public:
+  // The maximum number of accepted in-flight DATA chunks. This indicates the
+  // maximum difference from this buffer's last cumulative ack TSN, and any
+  // received data. Data received beyond this limit will be dropped, which will
+  // force the transmitter to send data that actually increases the last
+  // cumulative acked TSN.
+  static constexpr uint32_t kMaxAcceptedOutstandingFragments = 256;
+
   explicit DataTracker(absl::string_view log_prefix,
                        Timer* delayed_ack_timer,
                        TSN peer_initial_tsn)
@@ -46,6 +53,11 @@
         last_cumulative_acked_tsn_(
             tsn_unwrapper_.Unwrap(TSN(*peer_initial_tsn - 1))) {}
 
+  // Indicates if the provided TSN is valid. If this return false, the data
+  // should be dropped and not added to any other buffers, which essentially
+  // means that there is intentional packet loss.
+  bool IsTSNValid(TSN tsn) const;
+
   // Call for every incoming data chunk.
   void Observe(TSN tsn,
                AnyDataChunk::ImmediateAckFlag immediate_ack =
@@ -113,7 +125,7 @@
   // All TSNs up until (and including) this value have been seen.
   UnwrappedTSN last_cumulative_acked_tsn_;
   // Received TSNs that are not directly following `last_cumulative_acked_tsn_`.
-  std::set<UnwrappedTSN> additional_tsns;
+  std::set<UnwrappedTSN> additional_tsns_;
   std::set<UnwrappedTSN> duplicates_;
 };
 }  // namespace dcsctp
diff --git a/net/dcsctp/rx/data_tracker_test.cc b/net/dcsctp/rx/data_tracker_test.cc
index 1bad807..d714b0b 100644
--- a/net/dcsctp/rx/data_tracker_test.cc
+++ b/net/dcsctp/rx/data_tracker_test.cc
@@ -27,6 +27,7 @@
 using ::testing::IsEmpty;
 
 constexpr size_t kArwnd = 10000;
+constexpr TSN kInitialTSN(11);
 
 class DataTrackerTest : public testing::Test {
  protected:
@@ -37,7 +38,7 @@
             "test/delayed_ack",
             []() { return absl::nullopt; },
             TimerOptions(DurationMs(0)))),
-        buf_("log: ", timer_.get(), /*peer_initial_tsn=*/TSN(11)) {}
+        buf_("log: ", timer_.get(), kInitialTSN) {}
 
   void Observer(std::initializer_list<uint32_t> tsns) {
     for (const uint32_t tsn : tsns) {
@@ -205,5 +206,29 @@
 
   EXPECT_TRUE(buf_.ShouldSendAck());
 }
+
+TEST_F(DataTrackerTest, WillAcceptValidTSNs) {
+  // The initial TSN is always one more than the last, which is our base.
+  TSN last_tsn = TSN(*kInitialTSN - 1);
+  int limit = static_cast<int>(DataTracker::kMaxAcceptedOutstandingFragments);
+
+  for (int i = -limit; i <= limit; ++i) {
+    EXPECT_TRUE(buf_.IsTSNValid(TSN(*last_tsn + i)));
+  }
+}
+
+TEST_F(DataTrackerTest, WillNotAcceptInvalidTSNs) {
+  // The initial TSN is always one more than the last, which is our base.
+  TSN last_tsn = TSN(*kInitialTSN - 1);
+
+  size_t limit = DataTracker::kMaxAcceptedOutstandingFragments;
+  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn + limit + 1)));
+  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn - (limit + 1))));
+  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn + 65536)));
+  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn - 65536)));
+  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn + 0x8000000)));
+  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn - 0x8000000)));
+}
+
 }  // namespace
 }  // namespace dcsctp