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:
Sebastian Jansson 2019-04-01 18:23:58 +02:00 committed by Commit Bot
parent 3c15f468c6
commit 62bb47f5f8
3 changed files with 111 additions and 67 deletions

View File

@ -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,

View File

@ -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.

View File

@ -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);