Adds support for stopping fake TCP cross traffic.

Bug: webrtc:9510
Change-Id: I95bca7e620e0b3916f1ae633ff1b7067f19bd8ab
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156500
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29451}
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
index 5cbb73d..51f3cd7 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
@@ -803,9 +803,7 @@
   auto* route = s.CreateRoutes(
       client, send_net, s.CreateClient("return", CallClientConfig()), ret_net);
   s.CreateVideoStream(route->forward(), VideoStreamConfig());
-  s.net()->StartFakeTcpCrossTraffic(s.net()->CreateRoute(send_net),
-                                    s.net()->CreateRoute(ret_net),
-                                    FakeTcpConfig());
+  s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
   s.RunFor(TimeDelta::seconds(10));
 
   // Currently only testing for the upper limit as we in practice back out
diff --git a/modules/congestion_controller/receive_side_congestion_controller_unittest.cc b/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
index a9827b2..5473497 100644
--- a/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
+++ b/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
@@ -107,9 +107,7 @@
   VideoStreamConfig video;
   video.stream.packet_feedback = false;
   s.CreateVideoStream(route->forward(), video);
-  s.net()->StartFakeTcpCrossTraffic(s.net()->CreateRoute(send_net),
-                                    s.net()->CreateRoute(ret_net),
-                                    FakeTcpConfig());
+  s.net()->StartFakeTcpCrossTraffic(send_net, ret_net, FakeTcpConfig());
   s.RunFor(TimeDelta::seconds(30));
   // For some reason we get outcompeted by TCP here, this should probably be
   // fixed and a lower bound should be added to the test.
diff --git a/test/network/cross_traffic.cc b/test/network/cross_traffic.cc
index 63982a1..0d1937f 100644
--- a/test/network/cross_traffic.cc
+++ b/test/network/cross_traffic.cc
@@ -115,10 +115,22 @@
       32);
 }
 
-FakeTcpCrossTraffic::FakeTcpCrossTraffic(FakeTcpConfig config,
+FakeTcpCrossTraffic::FakeTcpCrossTraffic(Clock* clock,
+                                         FakeTcpConfig config,
                                          EmulatedRoute* send_route,
                                          EmulatedRoute* ret_route)
-    : conf_(config), route_(this, send_route, ret_route) {}
+    : clock_(clock), conf_(config), route_(this, send_route, ret_route) {}
+
+void FakeTcpCrossTraffic::Start(TaskQueueBase* task_queue) {
+  repeating_task_handle_ = RepeatingTaskHandle::Start(task_queue, [this] {
+    Process(clock_->CurrentTime());
+    return conf_.process_interval;
+  });
+}
+
+void FakeTcpCrossTraffic::Stop() {
+  repeating_task_handle_.Stop();
+}
 
 void FakeTcpCrossTraffic::Process(Timestamp at_time) {
   SendPackets(at_time);
diff --git a/test/network/cross_traffic.h b/test/network/cross_traffic.h
index 6a01a4e..98e56d6 100644
--- a/test/network/cross_traffic.h
+++ b/test/network/cross_traffic.h
@@ -95,7 +95,6 @@
 struct FakeTcpConfig {
   DataSize packet_size = DataSize::bytes(1200);
   DataSize send_limit = DataSize::PlusInfinity();
-  int packet_window;
   TimeDelta process_interval = TimeDelta::ms(200);
   TimeDelta packet_timeout = TimeDelta::seconds(1);
 };
@@ -103,9 +102,12 @@
 class FakeTcpCrossTraffic
     : public TwoWayFakeTrafficRoute<int, int>::TrafficHandlerInterface {
  public:
-  FakeTcpCrossTraffic(FakeTcpConfig config,
+  FakeTcpCrossTraffic(Clock* clock,
+                      FakeTcpConfig config,
                       EmulatedRoute* send_route,
                       EmulatedRoute* ret_route);
+  void Start(TaskQueueBase* task_queue);
+  void Stop();
   void Process(Timestamp at_time);
   void OnRequest(int sequence_number, Timestamp at_time) override;
   void OnResponse(int sequence_number, Timestamp at_time) override;
@@ -115,6 +117,7 @@
   void SendPackets(Timestamp at_time);
 
  private:
+  Clock* const clock_;
   const FakeTcpConfig conf_;
   TwoWayFakeTrafficRoute<int, int> route_;
 
@@ -127,6 +130,7 @@
   Timestamp last_reduction_time_ = Timestamp::MinusInfinity();
   TimeDelta last_rtt_ = TimeDelta::Zero();
   DataSize total_sent_ = DataSize::Zero();
+  RepeatingTaskHandle repeating_task_handle_;
 };
 
 }  // namespace test
diff --git a/test/network/network_emulation.h b/test/network/network_emulation.h
index f23f575..2051216 100644
--- a/test/network/network_emulation.h
+++ b/test/network/network_emulation.h
@@ -268,6 +268,8 @@
         recv_addr_(route_->to->GetPeerLocalAddress(),
                    *route_->to->BindReceiver(0, this)) {}
 
+  ~FakePacketRoute() { route_->to->UnbindReceiver(recv_addr_.port()); }
+
   void SendPacket(size_t size, FakePacketType packet) {
     RTC_CHECK_GE(size, sizeof(int));
     sent_.emplace(next_packet_id_, packet);
diff --git a/test/network/network_emulation_manager.cc b/test/network/network_emulation_manager.cc
index 73f1021..b0caac3 100644
--- a/test/network/network_emulation_manager.cc
+++ b/test/network/network_emulation_manager.cc
@@ -212,21 +212,28 @@
   return out;
 }
 
-void NetworkEmulationManagerImpl::StartFakeTcpCrossTraffic(
-    EmulatedRoute* send_route,
-    EmulatedRoute* ret_route,
+FakeTcpCrossTraffic* NetworkEmulationManagerImpl::StartFakeTcpCrossTraffic(
+    std::vector<EmulatedNetworkNode*> send_link,
+    std::vector<EmulatedNetworkNode*> ret_link,
     FakeTcpConfig config) {
-  task_queue_.PostTask([=]() {
-    auto traffic =
-        std::make_unique<FakeTcpCrossTraffic>(config, send_route, ret_route);
-    auto* traffic_ptr = traffic.get();
+  auto traffic = std::make_unique<FakeTcpCrossTraffic>(
+      clock_, config, CreateRoute(send_link), CreateRoute(ret_link));
+  auto* traffic_ptr = traffic.get();
+  task_queue_.PostTask([this, traffic = std::move(traffic)]() mutable {
+    traffic->Start(task_queue_.Get());
     tcp_cross_traffics_.push_back(std::move(traffic));
-    TimeDelta process_interval = config.process_interval;
-    RepeatingTaskHandle::Start(task_queue_.Get(),
-                               [this, process_interval, traffic_ptr] {
-                                 traffic_ptr->Process(Now());
-                                 return process_interval;
-                               });
+  });
+  return traffic_ptr;
+}
+
+void NetworkEmulationManagerImpl::StopCrossTraffic(
+    FakeTcpCrossTraffic* traffic) {
+  task_queue_.PostTask([=]() {
+    traffic->Stop();
+    tcp_cross_traffics_.remove_if(
+        [=](const std::unique_ptr<FakeTcpCrossTraffic>& ptr) {
+          return ptr.get() == traffic;
+        });
   });
 }
 
diff --git a/test/network/network_emulation_manager.h b/test/network/network_emulation_manager.h
index fbe8a23..b4e06ce 100644
--- a/test/network/network_emulation_manager.h
+++ b/test/network/network_emulation_manager.h
@@ -72,9 +72,11 @@
   PulsedPeaksCrossTraffic* CreatePulsedPeaksCrossTraffic(
       TrafficRoute* traffic_route,
       PulsedPeaksConfig config);
-  void StartFakeTcpCrossTraffic(EmulatedRoute* send_route,
-                                EmulatedRoute* ret_route,
-                                FakeTcpConfig config);
+  FakeTcpCrossTraffic* StartFakeTcpCrossTraffic(
+      std::vector<EmulatedNetworkNode*> send_link,
+      std::vector<EmulatedNetworkNode*> ret_link,
+      FakeTcpConfig config);
+  void StopCrossTraffic(FakeTcpCrossTraffic* traffic);
 
   EmulatedNetworkManagerInterface* CreateEmulatedNetworkManagerInterface(
       const std::vector<EmulatedEndpoint*>& endpoints) override;
@@ -98,7 +100,7 @@
   std::vector<std::unique_ptr<TrafficRoute>> traffic_routes_;
   std::vector<std::unique_ptr<RandomWalkCrossTraffic>> random_cross_traffics_;
   std::vector<std::unique_ptr<PulsedPeaksCrossTraffic>> pulsed_cross_traffics_;
-  std::vector<std::unique_ptr<FakeTcpCrossTraffic>> tcp_cross_traffics_;
+  std::list<std::unique_ptr<FakeTcpCrossTraffic>> tcp_cross_traffics_;
   std::vector<std::unique_ptr<EndpointsContainer>> endpoints_containers_;
   std::vector<std::unique_ptr<EmulatedNetworkManager>> network_managers_;