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}
This commit is contained in:
parent
3c15f468c6
commit
62bb47f5f8
@ -28,48 +28,19 @@ EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
|
||||
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::HandlePacketReceived(EmulatedIpPacket packet) {
|
||||
});
|
||||
}
|
||||
|
||||
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 @@ void EmulatedNetworkNode::Process(Timestamp at_time) {
|
||||
}
|
||||
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::Process(Timestamp at_time) {
|
||||
}
|
||||
}
|
||||
|
||||
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::SetReceiver(
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
|
||||
@ -68,6 +68,52 @@ class EmulatedNetworkReceiverInterface {
|
||||
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 @@ class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
|
||||
// |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 @@ class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
|
||||
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 @@ class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
|
||||
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.
|
||||
|
||||
@ -112,10 +112,10 @@ EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
|
||||
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 @@ void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) {
|
||||
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 @@ TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute(
|
||||
// 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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user