Splits network node into link and router.

Bug: webrtc:9883
Change-Id: I5ec5265be0940922cff311d385f2bf190f731422
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130496
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27418}
diff --git a/test/scenario/network/network_emulation.cc b/test/scenario/network/network_emulation.cc
index 4f706cf..fe977e5 100644
--- a/test/scenario/network/network_emulation.cc
+++ b/test/scenario/network/network_emulation.cc
@@ -28,48 +28,19 @@
       data(data),
       arrival_time(arrival_time) {}
 
-void EmulatedNetworkNode::CreateRoute(
-    rtc::IPAddress receiver_ip,
-    std::vector<EmulatedNetworkNode*> nodes,
-    EmulatedNetworkReceiverInterface* receiver) {
-  RTC_CHECK(!nodes.empty());
-  for (size_t i = 0; i + 1 < nodes.size(); ++i)
-    nodes[i]->SetReceiver(receiver_ip, nodes[i + 1]);
-  nodes.back()->SetReceiver(receiver_ip, receiver);
-}
-
-void EmulatedNetworkNode::ClearRoute(rtc::IPAddress receiver_ip,
-                                     std::vector<EmulatedNetworkNode*> nodes) {
-  for (EmulatedNetworkNode* node : nodes)
-    node->RemoveReceiver(receiver_ip);
-}
-
-EmulatedNetworkNode::EmulatedNetworkNode(
-    Clock* clock,
-    rtc::TaskQueue* task_queue,
-    std::unique_ptr<NetworkBehaviorInterface> network_behavior)
-    : clock_(clock),
-      task_queue_(task_queue),
-      network_behavior_(std::move(network_behavior)) {}
-
-EmulatedNetworkNode::~EmulatedNetworkNode() = default;
-
-void EmulatedNetworkNode::OnPacketReceived(EmulatedIpPacket packet) {
+void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
   struct Closure {
     void operator()() {
-      RTC_DCHECK_RUN_ON(node->task_queue_);
-      node->HandlePacketReceived(std::move(packet));
+      RTC_DCHECK_RUN_ON(link->task_queue_);
+      link->HandlePacketReceived(std::move(packet));
     }
-    EmulatedNetworkNode* node;
+    LinkEmulation* link;
     EmulatedIpPacket packet;
   };
   task_queue_->PostTask(Closure{this, std::move(packet)});
 }
 
-void EmulatedNetworkNode::HandlePacketReceived(EmulatedIpPacket packet) {
-  if (routing_.find(packet.to.ipaddr()) == routing_.end()) {
-    return;
-  }
+void LinkEmulation::HandlePacketReceived(EmulatedIpPacket packet) {
   uint64_t packet_id = next_packet_id_++;
   bool sent = network_behavior_->EnqueuePacket(
       PacketInFlightInfo(packet.size(), packet.arrival_time.us(), packet_id));
@@ -101,7 +72,7 @@
       });
 }
 
-void EmulatedNetworkNode::Process(Timestamp at_time) {
+void LinkEmulation::Process(Timestamp at_time) {
   std::vector<PacketDeliveryInfo> delivery_infos =
       network_behavior_->DequeueDeliverablePackets(at_time.us());
   for (PacketDeliveryInfo& delivery_info : delivery_infos) {
@@ -114,14 +85,12 @@
     }
     RTC_CHECK(packet);
     RTC_DCHECK(!packet->removed);
-    auto receiver_it = routing_.find(packet->packet.to.ipaddr());
-    RTC_CHECK(receiver_it != routing_.end());
     packet->removed = true;
 
     if (delivery_info.receive_time_us != PacketDeliveryInfo::kNotReceived) {
       packet->packet.arrival_time =
           Timestamp::us(delivery_info.receive_time_us);
-      receiver_it->second->OnPacketReceived(std::move(packet->packet));
+      receiver_->OnPacketReceived(std::move(packet->packet));
     }
     while (!packets_.empty() && packets_.front().removed) {
       packets_.pop_front();
@@ -129,7 +98,21 @@
   }
 }
 
-void EmulatedNetworkNode::SetReceiver(
+NetworkRouterNode::NetworkRouterNode(rtc::TaskQueue* task_queue)
+    : task_queue_(task_queue) {}
+
+void NetworkRouterNode::OnPacketReceived(EmulatedIpPacket packet) {
+  RTC_DCHECK_RUN_ON(task_queue_);
+  auto receiver_it = routing_.find(packet.to.ipaddr());
+  if (receiver_it == routing_.end()) {
+    return;
+  }
+  RTC_CHECK(receiver_it != routing_.end());
+
+  receiver_it->second->OnPacketReceived(std::move(packet));
+}
+
+void NetworkRouterNode::SetReceiver(
     rtc::IPAddress dest_ip,
     EmulatedNetworkReceiverInterface* receiver) {
   task_queue_->PostTask([=] {
@@ -141,11 +124,40 @@
   });
 }
 
-void EmulatedNetworkNode::RemoveReceiver(rtc::IPAddress dest_ip) {
+void NetworkRouterNode::RemoveReceiver(rtc::IPAddress dest_ip) {
   RTC_DCHECK_RUN_ON(task_queue_);
   routing_.erase(dest_ip);
 }
 
+EmulatedNetworkNode::EmulatedNetworkNode(
+    Clock* clock,
+    rtc::TaskQueue* task_queue,
+    std::unique_ptr<NetworkBehaviorInterface> network_behavior)
+    : router_(task_queue),
+      link_(clock, task_queue, std::move(network_behavior), &router_) {}
+
+void EmulatedNetworkNode::OnPacketReceived(EmulatedIpPacket packet) {
+  link_.OnPacketReceived(std::move(packet));
+}
+
+void EmulatedNetworkNode::CreateRoute(
+    rtc::IPAddress receiver_ip,
+    std::vector<EmulatedNetworkNode*> nodes,
+    EmulatedNetworkReceiverInterface* receiver) {
+  RTC_CHECK(!nodes.empty());
+  for (size_t i = 0; i + 1 < nodes.size(); ++i)
+    nodes[i]->router()->SetReceiver(receiver_ip, nodes[i + 1]);
+  nodes.back()->router()->SetReceiver(receiver_ip, receiver);
+}
+
+void EmulatedNetworkNode::ClearRoute(rtc::IPAddress receiver_ip,
+                                     std::vector<EmulatedNetworkNode*> nodes) {
+  for (EmulatedNetworkNode* node : nodes)
+    node->router()->RemoveReceiver(receiver_ip);
+}
+
+EmulatedNetworkNode::~EmulatedNetworkNode() = default;
+
 EmulatedEndpoint::EmulatedEndpoint(uint64_t id,
                                    const rtc::IPAddress& ip,
                                    bool is_enabled,
diff --git a/test/scenario/network/network_emulation.h b/test/scenario/network/network_emulation.h
index 674e39e..7505cbd 100644
--- a/test/scenario/network/network_emulation.h
+++ b/test/scenario/network/network_emulation.h
@@ -68,6 +68,52 @@
   virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
 };
 
+class LinkEmulation : public EmulatedNetworkReceiverInterface {
+ public:
+  LinkEmulation(Clock* clock,
+                rtc::TaskQueue* task_queue,
+                std::unique_ptr<NetworkBehaviorInterface> network_behavior,
+                EmulatedNetworkReceiverInterface* receiver)
+      : clock_(clock),
+        task_queue_(task_queue),
+        network_behavior_(std::move(network_behavior)),
+        receiver_(receiver) {}
+  void OnPacketReceived(EmulatedIpPacket packet) override;
+
+ private:
+  struct StoredPacket {
+    uint64_t id;
+    EmulatedIpPacket packet;
+    bool removed;
+  };
+  void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
+  void HandlePacketReceived(EmulatedIpPacket packet) RTC_RUN_ON(task_queue_);
+
+  Clock* const clock_;
+  rtc::TaskQueue* const task_queue_;
+  const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
+      RTC_GUARDED_BY(task_queue_);
+  EmulatedNetworkReceiverInterface* const receiver_;
+  RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
+  std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
+  uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
+};
+
+class NetworkRouterNode : public EmulatedNetworkReceiverInterface {
+ public:
+  explicit NetworkRouterNode(rtc::TaskQueue* task_queue);
+
+  void OnPacketReceived(EmulatedIpPacket packet) override;
+  void SetReceiver(rtc::IPAddress dest_ip,
+                   EmulatedNetworkReceiverInterface* receiver);
+  void RemoveReceiver(rtc::IPAddress dest_ip);
+
+ private:
+  rtc::TaskQueue* const task_queue_;
+  std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
+      RTC_GUARDED_BY(task_queue_);
+};
+
 // Represents node in the emulated network. Nodes can be connected with each
 // other to form different networks with different behavior. The behavior of
 // the node itself is determined by a concrete implementation of
@@ -79,7 +125,7 @@
   // |network_behavior|.
   // |task_queue| is used to process packets and to forward the packets when
   // they are ready.
-  explicit EmulatedNetworkNode(
+  EmulatedNetworkNode(
       Clock* clock,
       rtc::TaskQueue* task_queue,
       std::unique_ptr<NetworkBehaviorInterface> network_behavior);
@@ -87,9 +133,9 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(EmulatedNetworkNode);
 
   void OnPacketReceived(EmulatedIpPacket packet) override;
-  void SetReceiver(rtc::IPAddress dest_ip,
-                   EmulatedNetworkReceiverInterface* receiver);
-  void RemoveReceiver(rtc::IPAddress dest_ip);
+
+  LinkEmulation* link() { return &link_; }
+  NetworkRouterNode* router() { return &router_; }
 
   // Creates a route for the given receiver_ip over all the given nodes to the
   // given receiver.
@@ -100,23 +146,8 @@
                          std::vector<EmulatedNetworkNode*> nodes);
 
  private:
-  void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
-  void HandlePacketReceived(EmulatedIpPacket packet) RTC_RUN_ON(task_queue_);
-  struct StoredPacket {
-    uint64_t id;
-    EmulatedIpPacket packet;
-    bool removed;
-  };
-  Clock* const clock_;
-  rtc::TaskQueue* const task_queue_;
-  RepeatingTaskHandle process_task_;
-  std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
-      RTC_GUARDED_BY(task_queue_);
-  const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
-      RTC_GUARDED_BY(task_queue_);
-  std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
-
-  uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
+  NetworkRouterNode router_;
+  LinkEmulation link_;
 };
 
 // Represents single network interface on the device.
diff --git a/test/scenario/network/network_emulation_manager.cc b/test/scenario/network/network_emulation_manager.cc
index fdcb3e8..190a0a8 100644
--- a/test/scenario/network/network_emulation_manager.cc
+++ b/test/scenario/network/network_emulation_manager.cc
@@ -112,10 +112,10 @@
   from->SetSendNode(via_nodes[0]);
   EmulatedNetworkNode* cur_node = via_nodes[0];
   for (size_t i = 1; i < via_nodes.size(); ++i) {
-    cur_node->SetReceiver(to->GetPeerLocalAddress(), via_nodes[i]);
+    cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), via_nodes[i]);
     cur_node = via_nodes[i];
   }
-  cur_node->SetReceiver(to->GetPeerLocalAddress(), to);
+  cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), to);
 
   std::unique_ptr<EmulatedRoute> route =
       absl::make_unique<EmulatedRoute>(from, std::move(via_nodes), to);
@@ -129,11 +129,11 @@
   task_queue_.SendTask([route]() {
     // Remove receiver from intermediate nodes.
     for (auto* node : route->via_nodes) {
-      node->RemoveReceiver(route->to->GetPeerLocalAddress());
+      node->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
     }
     // Detach endpoint from current send node.
     if (route->from->GetSendNode()) {
-      route->from->GetSendNode()->RemoveReceiver(
+      route->from->GetSendNode()->router()->RemoveReceiver(
           route->to->GetPeerLocalAddress());
       route->from->SetSendNode(nullptr);
     }
@@ -150,10 +150,11 @@
   // Setup a route via specified nodes.
   EmulatedNetworkNode* cur_node = via_nodes[0];
   for (size_t i = 1; i < via_nodes.size(); ++i) {
-    cur_node->SetReceiver(endpoint->GetPeerLocalAddress(), via_nodes[i]);
+    cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(),
+                                    via_nodes[i]);
     cur_node = via_nodes[i];
   }
-  cur_node->SetReceiver(endpoint->GetPeerLocalAddress(), endpoint);
+  cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(), endpoint);
 
   std::unique_ptr<TrafficRoute> traffic_route =
       absl::make_unique<TrafficRoute>(clock_, via_nodes[0], endpoint);