dcsctp: implement handover in DataTracker

Bug: webrtc:13154
Change-Id: Ia8c41dcffd95dafd904ee630f2131b575fe833dd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/231955
Reviewed-by: Victor Boivie <boivie@webrtc.org>
Commit-Queue: Sergey Sukhanov <sergeysu@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34996}
diff --git a/net/dcsctp/public/dcsctp_handover_state.h b/net/dcsctp/public/dcsctp_handover_state.h
index d1267ca..0f870b8 100644
--- a/net/dcsctp/public/dcsctp_handover_state.h
+++ b/net/dcsctp/public/dcsctp_handover_state.h
@@ -32,6 +32,8 @@
     uint32_t id = 0;
   };
   struct Receive {
+    bool seen_packet = false;
+    uint32_t last_cumulative_acked_tsn = 0;
     std::vector<OrderedStream> ordered_streams;
     std::vector<UnorderedStream> unordered_streams;
   };
@@ -42,7 +44,7 @@
 enum class HandoverUnreadinessReason : uint32_t {
   kWrongConnectionState = 1,
   kSendQueueNotEmpty = 2,
-  kDataTrackerNotIdle = 4,
+  kPendingStreamResetRequest = 4,
   kDataTrackerTsnBlocksPending = 8,
   kReassemblyQueueNotEmpty = 16,
   kReassemblyQueueDeliveredTSNsGap = 32,
@@ -53,8 +55,7 @@
   kRetransmissionQueueFastRecovery = 1024,
   kRetransmissionQueueNotEmpty = 2048,
   kPendingStreamReset = 4096,
-  kPendingStreamResetRequest = 8192,
-  kMax = kPendingStreamResetRequest,
+  kMax = kPendingStreamReset,
 };
 
 // Return value of `DcSctpSocketInterface::GetHandoverReadiness`. Set of
diff --git a/net/dcsctp/rx/BUILD.gn b/net/dcsctp/rx/BUILD.gn
index 6c49648..2179e69 100644
--- a/net/dcsctp/rx/BUILD.gn
+++ b/net/dcsctp/rx/BUILD.gn
@@ -17,6 +17,7 @@
     "../common:sequence_numbers",
     "../packet:chunk",
     "../packet:data",
+    "../public:socket",
     "../timer",
   ]
   sources = [
diff --git a/net/dcsctp/rx/data_tracker.cc b/net/dcsctp/rx/data_tracker.cc
index 5b563a8..f31847b 100644
--- a/net/dcsctp/rx/data_tracker.cc
+++ b/net/dcsctp/rx/data_tracker.cc
@@ -356,4 +356,17 @@
   }
 }
 
+HandoverReadinessStatus DataTracker::GetHandoverReadiness() const {
+  HandoverReadinessStatus status;
+  if (!additional_tsn_blocks_.empty()) {
+    status.Add(HandoverUnreadinessReason::kDataTrackerTsnBlocksPending);
+  }
+  return status;
+}
+
+void DataTracker::AddHandoverState(DcSctpSocketHandoverState& state) {
+  state.rx.last_cumulative_acked_tsn = last_cumulative_acked_tsn().value();
+  state.rx.seen_packet = seen_packet_;
+}
+
 }  // namespace dcsctp
diff --git a/net/dcsctp/rx/data_tracker.h b/net/dcsctp/rx/data_tracker.h
index 167f5a0..fb8add8 100644
--- a/net/dcsctp/rx/data_tracker.h
+++ b/net/dcsctp/rx/data_tracker.h
@@ -24,6 +24,7 @@
 #include "net/dcsctp/packet/chunk/data_common.h"
 #include "net/dcsctp/packet/chunk/sack_chunk.h"
 #include "net/dcsctp/packet/data.h"
+#include "net/dcsctp/public/dcsctp_handover_state.h"
 #include "net/dcsctp/timer/timer.h"
 
 namespace dcsctp {
@@ -51,13 +52,17 @@
   // cumulative acked TSN.
   static constexpr uint32_t kMaxAcceptedOutstandingFragments = 100000;
 
-  explicit DataTracker(absl::string_view log_prefix,
-                       Timer* delayed_ack_timer,
-                       TSN peer_initial_tsn)
+  DataTracker(absl::string_view log_prefix,
+              Timer* delayed_ack_timer,
+              TSN peer_initial_tsn,
+              const DcSctpSocketHandoverState* handover_state = nullptr)
       : log_prefix_(std::string(log_prefix) + "dtrack: "),
+        seen_packet_(handover_state != nullptr ? handover_state->rx.seen_packet
+                                               : false),
         delayed_ack_timer_(*delayed_ack_timer),
-        last_cumulative_acked_tsn_(
-            tsn_unwrapper_.Unwrap(TSN(*peer_initial_tsn - 1))) {}
+        last_cumulative_acked_tsn_(tsn_unwrapper_.Unwrap(
+            handover_state ? TSN(handover_state->rx.last_cumulative_acked_tsn)
+                           : 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
@@ -101,6 +106,10 @@
 
   void HandleDelayedAckTimerExpiry();
 
+  HandoverReadinessStatus GetHandoverReadiness() const;
+
+  void AddHandoverState(DcSctpSocketHandoverState& state);
+
  private:
   enum class AckState {
     // No need to send an ACK.
@@ -166,7 +175,7 @@
 
   const std::string log_prefix_;
   // If a packet has ever been seen.
-  bool seen_packet_ = false;
+  bool seen_packet_;
   Timer& delayed_ack_timer_;
   AckState ack_state_ = AckState::kIdle;
   UnwrappedTSN::Unwrapper tsn_unwrapper_;
diff --git a/net/dcsctp/rx/data_tracker_test.cc b/net/dcsctp/rx/data_tracker_test.cc
index 5c2e56f..e59f8a9 100644
--- a/net/dcsctp/rx/data_tracker_test.cc
+++ b/net/dcsctp/rx/data_tracker_test.cc
@@ -40,23 +40,33 @@
             "test/delayed_ack",
             []() { return absl::nullopt; },
             TimerOptions(DurationMs(0)))),
-        buf_("log: ", timer_.get(), kInitialTSN) {}
+        tracker_(
+            std::make_unique<DataTracker>("log: ", timer_.get(), kInitialTSN)) {
+  }
 
   void Observer(std::initializer_list<uint32_t> tsns) {
     for (const uint32_t tsn : tsns) {
-      buf_.Observe(TSN(tsn), AnyDataChunk::ImmediateAckFlag(false));
+      tracker_->Observe(TSN(tsn), AnyDataChunk::ImmediateAckFlag(false));
     }
   }
 
+  void HandoverTracker() {
+    EXPECT_TRUE(tracker_->GetHandoverReadiness().IsReady());
+    DcSctpSocketHandoverState state;
+    tracker_->AddHandoverState(state);
+    tracker_ = std::make_unique<DataTracker>("log: ", timer_.get(), kInitialTSN,
+                                             &state);
+  }
+
   TimeMs now_ = TimeMs(0);
   FakeTimeoutManager timeout_manager_;
   TimerManager timer_manager_;
   std::unique_ptr<Timer> timer_;
-  DataTracker buf_;
+  std::unique_ptr<DataTracker> tracker_;
 };
 
 TEST_F(DataTrackerTest, Empty) {
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(), IsEmpty());
@@ -64,7 +74,7 @@
 
 TEST_F(DataTrackerTest, ObserverSingleInOrderPacket) {
   Observer({11});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(11));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(), IsEmpty());
@@ -72,7 +82,7 @@
 
 TEST_F(DataTrackerTest, ObserverManyInOrderMovesCumulativeTsnAck) {
   Observer({11, 12, 13});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(13));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(), IsEmpty());
@@ -80,7 +90,7 @@
 
 TEST_F(DataTrackerTest, ObserveOutOfOrderMovesCumulativeTsnAck) {
   Observer({12, 13, 14, 11});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(14));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(), IsEmpty());
@@ -88,7 +98,7 @@
 
 TEST_F(DataTrackerTest, SingleGap) {
   Observer({12});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 2)));
   EXPECT_THAT(sack.duplicate_tsns(), IsEmpty());
@@ -96,7 +106,7 @@
 
 TEST_F(DataTrackerTest, ExampleFromRFC4960Section334) {
   Observer({11, 12, 14, 15, 17});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(12));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 3),
                                                  SackChunk::GapAckBlock(5, 5)));
@@ -105,33 +115,33 @@
 
 TEST_F(DataTrackerTest, AckAlreadyReceivedChunk) {
   Observer({11});
-  SackChunk sack1 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack1 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack1.cumulative_tsn_ack(), TSN(11));
   EXPECT_THAT(sack1.gap_ack_blocks(), IsEmpty());
 
   // Receive old chunk
   Observer({8});
-  SackChunk sack2 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack2 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack2.cumulative_tsn_ack(), TSN(11));
   EXPECT_THAT(sack2.gap_ack_blocks(), IsEmpty());
 }
 
 TEST_F(DataTrackerTest, DoubleSendRetransmittedChunk) {
   Observer({11, 13, 14, 15});
-  SackChunk sack1 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack1 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack1.cumulative_tsn_ack(), TSN(11));
   EXPECT_THAT(sack1.gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(2, 4)));
 
   // Fill in the hole.
   Observer({12, 16, 17, 18});
-  SackChunk sack2 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack2 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack2.cumulative_tsn_ack(), TSN(18));
   EXPECT_THAT(sack2.gap_ack_blocks(), IsEmpty());
 
   // Receive chunk 12 again.
   Observer({12, 19, 20, 21});
-  SackChunk sack3 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack3 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack3.cumulative_tsn_ack(), TSN(21));
   EXPECT_THAT(sack3.gap_ack_blocks(), IsEmpty());
 }
@@ -140,9 +150,9 @@
   // Messages (11, 12, 13), (14, 15) - first message expires.
   Observer({11, 12, 15});
 
-  buf_.HandleForwardTsn(TSN(13));
+  tracker_->HandleForwardTsn(TSN(13));
 
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(13));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 2)));
 }
@@ -151,21 +161,21 @@
   // Messages (11, 12, 13), (14, 15) - first message expires.
   Observer({11, 12, 14});
 
-  buf_.HandleForwardTsn(TSN(13));
+  tracker_->HandleForwardTsn(TSN(13));
 
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(14));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
 }
 
 TEST_F(DataTrackerTest, ExampleFromRFC3758) {
-  buf_.HandleForwardTsn(TSN(102));
+  tracker_->HandleForwardTsn(TSN(102));
 
   Observer({102, 104, 105, 107});
 
-  buf_.HandleForwardTsn(TSN(103));
+  tracker_->HandleForwardTsn(TSN(103));
 
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(105));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 2)));
 }
@@ -173,40 +183,40 @@
 TEST_F(DataTrackerTest, EmptyAllAcks) {
   Observer({11, 13, 14, 15});
 
-  buf_.HandleForwardTsn(TSN(100));
+  tracker_->HandleForwardTsn(TSN(100));
 
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(100));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
 }
 
 TEST_F(DataTrackerTest, SetsArwndCorrectly) {
-  SackChunk sack1 = buf_.CreateSelectiveAck(/*a_rwnd=*/100);
+  SackChunk sack1 = tracker_->CreateSelectiveAck(/*a_rwnd=*/100);
   EXPECT_EQ(sack1.a_rwnd(), 100u);
 
-  SackChunk sack2 = buf_.CreateSelectiveAck(/*a_rwnd=*/101);
+  SackChunk sack2 = tracker_->CreateSelectiveAck(/*a_rwnd=*/101);
   EXPECT_EQ(sack2.a_rwnd(), 101u);
 }
 
 TEST_F(DataTrackerTest, WillIncreaseCumAckTsn) {
-  EXPECT_EQ(buf_.last_cumulative_acked_tsn(), TSN(10));
-  EXPECT_FALSE(buf_.will_increase_cum_ack_tsn(TSN(10)));
-  EXPECT_TRUE(buf_.will_increase_cum_ack_tsn(TSN(11)));
-  EXPECT_FALSE(buf_.will_increase_cum_ack_tsn(TSN(12)));
+  EXPECT_EQ(tracker_->last_cumulative_acked_tsn(), TSN(10));
+  EXPECT_FALSE(tracker_->will_increase_cum_ack_tsn(TSN(10)));
+  EXPECT_TRUE(tracker_->will_increase_cum_ack_tsn(TSN(11)));
+  EXPECT_FALSE(tracker_->will_increase_cum_ack_tsn(TSN(12)));
 
   Observer({11, 12, 13, 14, 15});
-  EXPECT_EQ(buf_.last_cumulative_acked_tsn(), TSN(15));
-  EXPECT_FALSE(buf_.will_increase_cum_ack_tsn(TSN(15)));
-  EXPECT_TRUE(buf_.will_increase_cum_ack_tsn(TSN(16)));
-  EXPECT_FALSE(buf_.will_increase_cum_ack_tsn(TSN(17)));
+  EXPECT_EQ(tracker_->last_cumulative_acked_tsn(), TSN(15));
+  EXPECT_FALSE(tracker_->will_increase_cum_ack_tsn(TSN(15)));
+  EXPECT_TRUE(tracker_->will_increase_cum_ack_tsn(TSN(16)));
+  EXPECT_FALSE(tracker_->will_increase_cum_ack_tsn(TSN(17)));
 }
 
 TEST_F(DataTrackerTest, ForceShouldSendSackImmediately) {
-  EXPECT_FALSE(buf_.ShouldSendAck());
+  EXPECT_FALSE(tracker_->ShouldSendAck());
 
-  buf_.ForceImmediateSack();
+  tracker_->ForceImmediateSack();
 
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  EXPECT_TRUE(tracker_->ShouldSendAck());
 }
 
 TEST_F(DataTrackerTest, WillAcceptValidTSNs) {
@@ -215,7 +225,7 @@
   int limit = static_cast<int>(DataTracker::kMaxAcceptedOutstandingFragments);
 
   for (int i = -limit; i <= limit; ++i) {
-    EXPECT_TRUE(buf_.IsTSNValid(TSN(*last_tsn + i)));
+    EXPECT_TRUE(tracker_->IsTSNValid(TSN(*last_tsn + i)));
   }
 }
 
@@ -224,15 +234,15 @@
   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 + 0x8000000)));
-  EXPECT_FALSE(buf_.IsTSNValid(TSN(*last_tsn - 0x8000000)));
+  EXPECT_FALSE(tracker_->IsTSNValid(TSN(*last_tsn + limit + 1)));
+  EXPECT_FALSE(tracker_->IsTSNValid(TSN(*last_tsn - (limit + 1))));
+  EXPECT_FALSE(tracker_->IsTSNValid(TSN(*last_tsn + 0x8000000)));
+  EXPECT_FALSE(tracker_->IsTSNValid(TSN(*last_tsn - 0x8000000)));
 }
 
 TEST_F(DataTrackerTest, ReportSingleDuplicateTsns) {
   Observer({11, 12, 11});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(12));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(), UnorderedElementsAre(TSN(11)));
@@ -240,7 +250,7 @@
 
 TEST_F(DataTrackerTest, ReportMultipleDuplicateTsns) {
   Observer({11, 12, 13, 14, 12, 13, 12, 13, 15, 16});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(16));
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(), UnorderedElementsAre(TSN(12), TSN(13)));
@@ -248,7 +258,7 @@
 
 TEST_F(DataTrackerTest, ReportDuplicateTsnsInGapAckBlocks) {
   Observer({11, /*12,*/ 13, 14, 13, 14, 15, 16});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(11));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 5)));
   EXPECT_THAT(sack.duplicate_tsns(), UnorderedElementsAre(TSN(13), TSN(14)));
@@ -256,13 +266,13 @@
 
 TEST_F(DataTrackerTest, ClearsDuplicateTsnsAfterCreatingSack) {
   Observer({11, 12, 13, 14, 12, 13, 12, 13, 15, 16});
-  SackChunk sack1 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack1 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack1.cumulative_tsn_ack(), TSN(16));
   EXPECT_THAT(sack1.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack1.duplicate_tsns(), UnorderedElementsAre(TSN(12), TSN(13)));
 
   Observer({17});
-  SackChunk sack2 = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack2 = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack2.cumulative_tsn_ack(), TSN(17));
   EXPECT_THAT(sack2.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack2.duplicate_tsns(), IsEmpty());
@@ -271,11 +281,11 @@
 TEST_F(DataTrackerTest, LimitsNumberOfDuplicatesReported) {
   for (size_t i = 0; i < DataTracker::kMaxDuplicateTsnReported + 10; ++i) {
     TSN tsn(11 + i);
-    buf_.Observe(tsn, AnyDataChunk::ImmediateAckFlag(false));
-    buf_.Observe(tsn, AnyDataChunk::ImmediateAckFlag(false));
+    tracker_->Observe(tsn, AnyDataChunk::ImmediateAckFlag(false));
+    tracker_->Observe(tsn, AnyDataChunk::ImmediateAckFlag(false));
   }
 
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
   EXPECT_THAT(sack.duplicate_tsns(),
               SizeIs(DataTracker::kMaxDuplicateTsnReported));
@@ -284,10 +294,10 @@
 TEST_F(DataTrackerTest, LimitsNumberOfGapAckBlocksReported) {
   for (size_t i = 0; i < DataTracker::kMaxGapAckBlocksReported + 10; ++i) {
     TSN tsn(11 + i * 2);
-    buf_.Observe(tsn, AnyDataChunk::ImmediateAckFlag(false));
+    tracker_->Observe(tsn, AnyDataChunk::ImmediateAckFlag(false));
   }
 
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(11));
   EXPECT_THAT(sack.gap_ack_blocks(),
               SizeIs(DataTracker::kMaxGapAckBlocksReported));
@@ -295,99 +305,99 @@
 
 TEST_F(DataTrackerTest, SendsSackForFirstPacketObserved) {
   Observer({11});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
 }
 
 TEST_F(DataTrackerTest, SendsSackEverySecondPacketWhenThereIsNoPacketLoss) {
   Observer({11});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({12});
-  buf_.ObservePacketEnd();
-  EXPECT_FALSE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
   EXPECT_TRUE(timer_->is_running());
   Observer({13});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({14});
-  buf_.ObservePacketEnd();
-  EXPECT_FALSE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
   EXPECT_TRUE(timer_->is_running());
   Observer({15});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
 }
 
 TEST_F(DataTrackerTest, SendsSackEveryPacketOnPacketLoss) {
   Observer({11});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({13});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({14});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({15});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({16});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   // Fill the hole.
   Observer({12});
-  buf_.ObservePacketEnd();
-  EXPECT_FALSE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
   EXPECT_TRUE(timer_->is_running());
   // Goes back to every second packet
   Observer({17});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({18});
-  buf_.ObservePacketEnd();
-  EXPECT_FALSE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
   EXPECT_TRUE(timer_->is_running());
 }
 
 TEST_F(DataTrackerTest, SendsSackOnDuplicateDataChunks) {
   Observer({11});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({11});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   Observer({12});
-  buf_.ObservePacketEnd();
-  EXPECT_FALSE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
   EXPECT_TRUE(timer_->is_running());
   // Goes back to every second packet
   Observer({13});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
   // Duplicate again
   Observer({12});
-  buf_.ObservePacketEnd();
-  EXPECT_TRUE(buf_.ShouldSendAck());
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
   EXPECT_FALSE(timer_->is_running());
 }
 
 TEST_F(DataTrackerTest, GapAckBlockAddSingleBlock) {
   Observer({12});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 2)));
 }
@@ -395,7 +405,7 @@
 TEST_F(DataTrackerTest, GapAckBlockAddsAnother) {
   Observer({12});
   Observer({14});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 2),
                                                  SackChunk::GapAckBlock(4, 4)));
@@ -404,7 +414,7 @@
 TEST_F(DataTrackerTest, GapAckBlockAddsDuplicate) {
   Observer({12});
   Observer({12});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 2)));
   EXPECT_THAT(sack.duplicate_tsns(), ElementsAre(TSN(12)));
@@ -413,7 +423,7 @@
 TEST_F(DataTrackerTest, GapAckBlockExpandsToRight) {
   Observer({12});
   Observer({13});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 3)));
 }
@@ -423,7 +433,7 @@
   Observer({20});
   Observer({30});
   Observer({21});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(2, 2),    //
@@ -434,7 +444,7 @@
 TEST_F(DataTrackerTest, GapAckBlockExpandsToLeft) {
   Observer({13});
   Observer({12});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(), ElementsAre(SackChunk::GapAckBlock(2, 3)));
 }
@@ -444,7 +454,7 @@
   Observer({21});
   Observer({30});
   Observer({20});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(2, 2),    //
@@ -458,7 +468,7 @@
   Observer({22});
   Observer({30});
   Observer({21});
-  SackChunk sack = buf_.CreateSelectiveAck(kArwnd);
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
   EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(10));
   EXPECT_THAT(sack.gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(2, 2),    //
@@ -468,73 +478,73 @@
 
 TEST_F(DataTrackerTest, GapAckBlockMergesManyBlocksIntoOne) {
   Observer({22});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 12)));
   Observer({30});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 12),  //
                           SackChunk::GapAckBlock(20, 20)));
   Observer({24});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 12),  //
                           SackChunk::GapAckBlock(14, 14),  //
                           SackChunk::GapAckBlock(20, 20)));
   Observer({28});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 12),  //
                           SackChunk::GapAckBlock(14, 14),  //
                           SackChunk::GapAckBlock(18, 18),  //
                           SackChunk::GapAckBlock(20, 20)));
   Observer({26});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 12),  //
                           SackChunk::GapAckBlock(14, 14),  //
                           SackChunk::GapAckBlock(16, 16),  //
                           SackChunk::GapAckBlock(18, 18),  //
                           SackChunk::GapAckBlock(20, 20)));
   Observer({29});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 12),  //
                           SackChunk::GapAckBlock(14, 14),  //
                           SackChunk::GapAckBlock(16, 16),  //
                           SackChunk::GapAckBlock(18, 20)));
   Observer({23});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 14),  //
                           SackChunk::GapAckBlock(16, 16),  //
                           SackChunk::GapAckBlock(18, 20)));
   Observer({27});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 14),  //
                           SackChunk::GapAckBlock(16, 20)));
 
   Observer({25});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(12, 20)));
   Observer({20});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(10, 10),  //
                           SackChunk::GapAckBlock(12, 20)));
   Observer({32});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(10, 10),  //
                           SackChunk::GapAckBlock(12, 20),  //
                           SackChunk::GapAckBlock(22, 22)));
   Observer({21});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(10, 20),  //
                           SackChunk::GapAckBlock(22, 22)));
   Observer({31});
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(10, 22)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveBeforeCumAckTsn) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(8));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(10));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(8));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(10));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(2, 4),  //
                           SackChunk::GapAckBlock(10, 12),
                           SackChunk::GapAckBlock(20, 21)));
@@ -543,9 +553,9 @@
 TEST_F(DataTrackerTest, GapAckBlockRemoveBeforeFirstBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(11));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(11));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(6, 8),  //
                           SackChunk::GapAckBlock(16, 17)));
 }
@@ -553,27 +563,27 @@
 TEST_F(DataTrackerTest, GapAckBlockRemoveAtBeginningOfFirstBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(12));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(12));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(6, 8),  //
                           SackChunk::GapAckBlock(16, 17)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveAtMiddleOfFirstBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
-  buf_.HandleForwardTsn(TSN(13));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(13));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(6, 8),  //
                           SackChunk::GapAckBlock(16, 17)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveAtEndOfFirstBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
-  buf_.HandleForwardTsn(TSN(14));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(14));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(14));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(6, 8),  //
                           SackChunk::GapAckBlock(16, 17)));
 }
@@ -581,9 +591,9 @@
 TEST_F(DataTrackerTest, GapAckBlockRemoveRightAfterFirstBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(18));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(18));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(18));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(18));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(2, 4),  //
                           SackChunk::GapAckBlock(12, 13)));
 }
@@ -591,46 +601,117 @@
 TEST_F(DataTrackerTest, GapAckBlockRemoveRightBeforeSecondBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(19));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(19));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(8, 9)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveRightAtStartOfSecondBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(20));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(20));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(8, 9)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveRightAtMiddleOfSecondBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(21));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(21));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(8, 9)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveRightAtEndOfSecondBlock) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(22));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(),
+  tracker_->HandleForwardTsn(TSN(22));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(22));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(),
               ElementsAre(SackChunk::GapAckBlock(8, 9)));
 }
 
 TEST_F(DataTrackerTest, GapAckBlockRemoveeFarAfterAllBlocks) {
   Observer({12, 13, 14, 20, 21, 22, 30, 31});
 
-  buf_.HandleForwardTsn(TSN(40));
-  EXPECT_EQ(buf_.CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(40));
-  EXPECT_THAT(buf_.CreateSelectiveAck(kArwnd).gap_ack_blocks(), IsEmpty());
+  tracker_->HandleForwardTsn(TSN(40));
+  EXPECT_EQ(tracker_->CreateSelectiveAck(kArwnd).cumulative_tsn_ack(), TSN(40));
+  EXPECT_THAT(tracker_->CreateSelectiveAck(kArwnd).gap_ack_blocks(), IsEmpty());
 }
 
+TEST_F(DataTrackerTest, HandoverEmpty) {
+  HandoverTracker();
+  Observer({11});
+  SackChunk sack = tracker_->CreateSelectiveAck(kArwnd);
+  EXPECT_EQ(sack.cumulative_tsn_ack(), TSN(11));
+  EXPECT_THAT(sack.gap_ack_blocks(), IsEmpty());
+}
+
+TEST_F(DataTrackerTest,
+       HandoverWhileSendingSackEverySecondPacketWhenThereIsNoPacketLoss) {
+  Observer({11});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+
+  HandoverTracker();
+
+  Observer({12});
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
+  Observer({13});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  EXPECT_FALSE(timer_->is_running());
+  Observer({14});
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
+  EXPECT_TRUE(timer_->is_running());
+  Observer({15});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  EXPECT_FALSE(timer_->is_running());
+}
+
+TEST_F(DataTrackerTest, HandoverWhileSendingSackEveryPacketOnPacketLoss) {
+  Observer({11});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  Observer({13});
+  EXPECT_EQ(tracker_->GetHandoverReadiness(),
+            HandoverReadinessStatus().Add(
+                HandoverUnreadinessReason::kDataTrackerTsnBlocksPending));
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  Observer({14});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  EXPECT_EQ(tracker_->GetHandoverReadiness(),
+            HandoverReadinessStatus(
+                HandoverUnreadinessReason::kDataTrackerTsnBlocksPending));
+  Observer({15});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  Observer({16});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+  // Fill the hole.
+  Observer({12});
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
+  // Goes back to every second packet
+  Observer({17});
+  tracker_->ObservePacketEnd();
+  EXPECT_TRUE(tracker_->ShouldSendAck());
+
+  HandoverTracker();
+
+  Observer({18});
+  tracker_->ObservePacketEnd();
+  EXPECT_FALSE(tracker_->ShouldSendAck());
+  EXPECT_TRUE(timer_->is_running());
+}
 }  // namespace
 }  // namespace dcsctp