Exposing more features in the network emulation manager API.
Bug: webrtc:9883 Change-Id: I2a687b46e3374db0dd08b0c02dfea1482e6fb89f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/161229 Reviewed-by: Per Kjellander <perkj@webrtc.org> Reviewed-by: Steve Anton <steveanton@webrtc.org> Reviewed-by: Artem Titov <titovartem@webrtc.org> Commit-Queue: Sebastian Jansson <srte@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30024}
This commit is contained in:

committed by
Commit Bot

parent
1fce3f8e55
commit
cec2433c47
@ -420,6 +420,7 @@ if (rtc_include_tests) {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO(srte): Move to network_emulation sub directory.
|
||||||
rtc_library("create_network_emulation_manager") {
|
rtc_library("create_network_emulation_manager") {
|
||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
testonly = true
|
testonly = true
|
||||||
@ -541,6 +542,7 @@ rtc_source_set("bitrate_allocation") {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO(srte): Move to network_emulation sub directory.
|
||||||
rtc_source_set("simulated_network_api") {
|
rtc_source_set("simulated_network_api") {
|
||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
sources = [
|
sources = [
|
||||||
@ -553,14 +555,18 @@ rtc_source_set("simulated_network_api") {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO(srte): Move to network_emulation sub directory.
|
||||||
rtc_source_set("network_emulation_manager_api") {
|
rtc_source_set("network_emulation_manager_api") {
|
||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
sources = [
|
sources = [
|
||||||
|
"test/network_emulation_manager.cc",
|
||||||
"test/network_emulation_manager.h",
|
"test/network_emulation_manager.h",
|
||||||
]
|
]
|
||||||
deps = [
|
deps = [
|
||||||
":simulated_network_api",
|
":simulated_network_api",
|
||||||
|
"../call:simulated_network",
|
||||||
"../rtc_base",
|
"../rtc_base",
|
||||||
|
"test/network_emulation",
|
||||||
"units:data_rate",
|
"units:data_rate",
|
||||||
"units:data_size",
|
"units:data_size",
|
||||||
"units:timestamp",
|
"units:timestamp",
|
||||||
|
28
api/test/network_emulation/BUILD.gn
Normal file
28
api/test/network_emulation/BUILD.gn
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Use of this source code is governed by a BSD-style license
|
||||||
|
# that can be found in the LICENSE file in the root of the source
|
||||||
|
# tree. An additional intellectual property rights grant can be found
|
||||||
|
# in the file PATENTS. All contributing project authors may
|
||||||
|
# be found in the AUTHORS file in the root of the source tree.
|
||||||
|
|
||||||
|
import("../../../webrtc.gni")
|
||||||
|
|
||||||
|
rtc_library("network_emulation") {
|
||||||
|
visibility = [ "*" ]
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
"network_emulation_interfaces.cc",
|
||||||
|
"network_emulation_interfaces.h",
|
||||||
|
]
|
||||||
|
|
||||||
|
deps = [
|
||||||
|
"../../../rtc_base",
|
||||||
|
"../../../rtc_base:checks",
|
||||||
|
"../../../rtc_base:rtc_base_approved",
|
||||||
|
"../../units:data_rate",
|
||||||
|
"../../units:data_size",
|
||||||
|
"../../units:timestamp",
|
||||||
|
"//third_party/abseil-cpp/absl/types:optional",
|
||||||
|
]
|
||||||
|
}
|
7
api/test/network_emulation/DEPS
Normal file
7
api/test/network_emulation/DEPS
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
specific_include_rules = {
|
||||||
|
".*": [
|
||||||
|
"+rtc_base/socket_address.h",
|
||||||
|
"+rtc_base/ip_address.h",
|
||||||
|
"+rtc_base/copy_on_write_buffer.h",
|
||||||
|
],
|
||||||
|
}
|
32
api/test/network_emulation/network_emulation_interfaces.cc
Normal file
32
api/test/network_emulation/network_emulation_interfaces.cc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
#include "api/test/network_emulation/network_emulation_interfaces.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr size_t kIPv4HeaderSize = 20;
|
||||||
|
constexpr size_t kIPv6HeaderSize = 40;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
|
||||||
|
const rtc::SocketAddress& to,
|
||||||
|
rtc::CopyOnWriteBuffer data,
|
||||||
|
Timestamp arrival_time)
|
||||||
|
: from(from),
|
||||||
|
to(to),
|
||||||
|
data(data),
|
||||||
|
ip_header_size((to.family() == AF_INET) ? kIPv4HeaderSize
|
||||||
|
: kIPv6HeaderSize),
|
||||||
|
arrival_time(arrival_time) {
|
||||||
|
RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
149
api/test/network_emulation/network_emulation_interfaces.h
Normal file
149
api/test/network_emulation/network_emulation_interfaces.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
#ifndef API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
|
||||||
|
#define API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
|
||||||
|
|
||||||
|
#include "absl/types/optional.h"
|
||||||
|
#include "api/units/data_rate.h"
|
||||||
|
#include "api/units/data_size.h"
|
||||||
|
#include "api/units/timestamp.h"
|
||||||
|
#include "rtc_base/copy_on_write_buffer.h"
|
||||||
|
#include "rtc_base/ip_address.h"
|
||||||
|
#include "rtc_base/socket_address.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
struct EmulatedIpPacket {
|
||||||
|
public:
|
||||||
|
static constexpr int kUdpHeaderSize = 8;
|
||||||
|
|
||||||
|
EmulatedIpPacket(const rtc::SocketAddress& from,
|
||||||
|
const rtc::SocketAddress& to,
|
||||||
|
rtc::CopyOnWriteBuffer data,
|
||||||
|
Timestamp arrival_time);
|
||||||
|
~EmulatedIpPacket() = default;
|
||||||
|
// This object is not copyable or assignable.
|
||||||
|
EmulatedIpPacket(const EmulatedIpPacket&) = delete;
|
||||||
|
EmulatedIpPacket& operator=(const EmulatedIpPacket&) = delete;
|
||||||
|
// This object is only moveable.
|
||||||
|
EmulatedIpPacket(EmulatedIpPacket&&) = default;
|
||||||
|
EmulatedIpPacket& operator=(EmulatedIpPacket&&) = default;
|
||||||
|
|
||||||
|
size_t size() const { return data.size(); }
|
||||||
|
const uint8_t* cdata() const { return data.cdata(); }
|
||||||
|
|
||||||
|
size_t ip_packet_size() const {
|
||||||
|
return size() + kUdpHeaderSize + ip_header_size;
|
||||||
|
}
|
||||||
|
rtc::SocketAddress from;
|
||||||
|
rtc::SocketAddress to;
|
||||||
|
// Holds the UDP payload.
|
||||||
|
rtc::CopyOnWriteBuffer data;
|
||||||
|
int ip_header_size;
|
||||||
|
Timestamp arrival_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Interface for handling IP packets from an emulated network. This is used with
|
||||||
|
// EmulatedEndpoint to receive packets on a specific port.
|
||||||
|
class EmulatedNetworkReceiverInterface {
|
||||||
|
public:
|
||||||
|
virtual ~EmulatedNetworkReceiverInterface() = default;
|
||||||
|
|
||||||
|
virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EmulatedNetworkStats {
|
||||||
|
int64_t packets_sent = 0;
|
||||||
|
DataSize bytes_sent = DataSize::Zero();
|
||||||
|
// Total amount of packets received with or without destination.
|
||||||
|
int64_t packets_received = 0;
|
||||||
|
// Total amount of bytes in received packets.
|
||||||
|
DataSize bytes_received = DataSize::Zero();
|
||||||
|
// Total amount of packets that were received, but no destination was found.
|
||||||
|
int64_t packets_dropped = 0;
|
||||||
|
// Total amount of bytes in dropped packets.
|
||||||
|
DataSize bytes_dropped = DataSize::Zero();
|
||||||
|
|
||||||
|
DataSize first_received_packet_size = DataSize::Zero();
|
||||||
|
DataSize first_sent_packet_size = DataSize::Zero();
|
||||||
|
|
||||||
|
Timestamp first_packet_sent_time = Timestamp::PlusInfinity();
|
||||||
|
Timestamp last_packet_sent_time = Timestamp::PlusInfinity();
|
||||||
|
Timestamp first_packet_received_time = Timestamp::PlusInfinity();
|
||||||
|
Timestamp last_packet_received_time = Timestamp::PlusInfinity();
|
||||||
|
|
||||||
|
DataRate AverageSendRate() const {
|
||||||
|
RTC_DCHECK_GE(packets_sent, 2);
|
||||||
|
return (bytes_sent - first_sent_packet_size) /
|
||||||
|
(last_packet_sent_time - first_packet_sent_time);
|
||||||
|
}
|
||||||
|
DataRate AverageReceiveRate() const {
|
||||||
|
RTC_DCHECK_GE(packets_received, 2);
|
||||||
|
return (bytes_received - first_received_packet_size) /
|
||||||
|
(last_packet_received_time - first_packet_received_time);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// EmulatedEndpoint is an abstraction for network interface on device. Instances
|
||||||
|
// of this are created by NetworkEmulationManager::CreateEndpoint.
|
||||||
|
class EmulatedEndpoint : public EmulatedNetworkReceiverInterface {
|
||||||
|
public:
|
||||||
|
// Send packet into network.
|
||||||
|
// |from| will be used to set source address for the packet in destination
|
||||||
|
// socket.
|
||||||
|
// |to| will be used for routing verification and picking right socket by port
|
||||||
|
// on destination endpoint.
|
||||||
|
virtual void SendPacket(const rtc::SocketAddress& from,
|
||||||
|
const rtc::SocketAddress& to,
|
||||||
|
rtc::CopyOnWriteBuffer packet_data) = 0;
|
||||||
|
|
||||||
|
// Binds receiver to this endpoint to send and receive data.
|
||||||
|
// |desired_port| is a port that should be used. If it is equal to 0,
|
||||||
|
// endpoint will pick the first available port starting from
|
||||||
|
// |kFirstEphemeralPort|.
|
||||||
|
//
|
||||||
|
// Returns the port, that should be used (it will be equals to desired, if
|
||||||
|
// |desired_port| != 0 and is free or will be the one, selected by endpoint)
|
||||||
|
// or absl::nullopt if desired_port in used. Also fails if there are no more
|
||||||
|
// free ports to bind to.
|
||||||
|
virtual absl::optional<uint16_t> BindReceiver(
|
||||||
|
uint16_t desired_port,
|
||||||
|
EmulatedNetworkReceiverInterface* receiver) = 0;
|
||||||
|
virtual void UnbindReceiver(uint16_t port) = 0;
|
||||||
|
virtual rtc::IPAddress GetPeerLocalAddress() const = 0;
|
||||||
|
|
||||||
|
virtual EmulatedNetworkStats stats() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Ensure that there can be no other subclass than EmulatedEndpointImpl. This
|
||||||
|
// means that it's always safe to downcast EmulatedEndpoint instances to
|
||||||
|
// EmulatedEndpointImpl.
|
||||||
|
friend class EmulatedEndpointImpl;
|
||||||
|
EmulatedEndpoint() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Simulates a TCP connection, this roughly implements the Reno algorithm. In
|
||||||
|
// difference from TCP this only support sending messages with a fixed length,
|
||||||
|
// no streaming. This is useful to simulate signaling and cross traffic using
|
||||||
|
// message based protocols such as HTTP. It differs from UDP messages in that
|
||||||
|
// they are guranteed to be delivered eventually, even on lossy networks.
|
||||||
|
class TcpMessageRoute {
|
||||||
|
public:
|
||||||
|
// Sends a TCP message of the given |size| over the route, |on_received| is
|
||||||
|
// called when the message has been delivered. Note that the connection
|
||||||
|
// parameters are reset iff there's no currently pending message on the route.
|
||||||
|
virtual void SendMessage(size_t size, std::function<void()> on_received) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~TcpMessageRoute() = default;
|
||||||
|
};
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_
|
@ -7,62 +7,53 @@
|
|||||||
* in the file PATENTS. All contributing project authors may
|
* in the file PATENTS. All contributing project authors may
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
#include "test/network/simulated_network_node.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "api/test/network_emulation_manager.h"
|
||||||
|
#include "call/simulated_network.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace test {
|
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder::Builder() {}
|
NetworkEmulationManager::SimulatedNetworkNode::Builder&
|
||||||
|
NetworkEmulationManager::SimulatedNetworkNode::Builder::config(
|
||||||
SimulatedNetworkNode::Builder::Builder(NetworkEmulationManager* net)
|
BuiltInNetworkBehaviorConfig config) {
|
||||||
: net_(net) {}
|
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder& SimulatedNetworkNode::Builder::config(
|
|
||||||
SimulatedNetwork::Config config) {
|
|
||||||
config_ = config;
|
config_ = config;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder& SimulatedNetworkNode::Builder::delay_ms(
|
NetworkEmulationManager::SimulatedNetworkNode::Builder&
|
||||||
|
NetworkEmulationManager::SimulatedNetworkNode::Builder::delay_ms(
|
||||||
int queue_delay_ms) {
|
int queue_delay_ms) {
|
||||||
config_.queue_delay_ms = queue_delay_ms;
|
config_.queue_delay_ms = queue_delay_ms;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder& SimulatedNetworkNode::Builder::capacity_kbps(
|
NetworkEmulationManager::SimulatedNetworkNode::Builder&
|
||||||
|
NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_kbps(
|
||||||
int link_capacity_kbps) {
|
int link_capacity_kbps) {
|
||||||
config_.link_capacity_kbps = link_capacity_kbps;
|
config_.link_capacity_kbps = link_capacity_kbps;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder& SimulatedNetworkNode::Builder::capacity_Mbps(
|
NetworkEmulationManager::SimulatedNetworkNode::Builder&
|
||||||
|
NetworkEmulationManager::SimulatedNetworkNode::Builder::capacity_Mbps(
|
||||||
int link_capacity_Mbps) {
|
int link_capacity_Mbps) {
|
||||||
config_.link_capacity_kbps = link_capacity_Mbps * 1000;
|
config_.link_capacity_kbps = link_capacity_Mbps * 1000;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder& SimulatedNetworkNode::Builder::loss(
|
NetworkEmulationManager::SimulatedNetworkNode::Builder&
|
||||||
double loss_rate) {
|
NetworkEmulationManager::SimulatedNetworkNode::Builder::loss(double loss_rate) {
|
||||||
config_.loss_percent = std::round(loss_rate * 100);
|
config_.loss_percent = std::round(loss_rate * 100);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetworkNode SimulatedNetworkNode::Builder::Build() const {
|
NetworkEmulationManager::SimulatedNetworkNode
|
||||||
RTC_DCHECK(net_);
|
NetworkEmulationManager::SimulatedNetworkNode::Builder::Build() const {
|
||||||
return Build(net_);
|
|
||||||
}
|
|
||||||
|
|
||||||
SimulatedNetworkNode SimulatedNetworkNode::Builder::Build(
|
|
||||||
NetworkEmulationManager* net) const {
|
|
||||||
SimulatedNetworkNode res;
|
SimulatedNetworkNode res;
|
||||||
auto behavior = std::make_unique<SimulatedNetwork>(config_);
|
auto behavior = std::make_unique<SimulatedNetwork>(config_);
|
||||||
res.simulation = behavior.get();
|
res.simulation = behavior.get();
|
||||||
res.node = net->CreateEmulatedNode(std::move(behavior));
|
res.node = net_->CreateEmulatedNode(std::move(behavior));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace test
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
@ -14,9 +14,9 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "api/test/network_emulation/network_emulation_interfaces.h"
|
||||||
#include "api/test/simulated_network.h"
|
#include "api/test/simulated_network.h"
|
||||||
#include "api/units/data_rate.h"
|
|
||||||
#include "api/units/data_size.h"
|
|
||||||
#include "api/units/timestamp.h"
|
#include "api/units/timestamp.h"
|
||||||
#include "rtc_base/network.h"
|
#include "rtc_base/network.h"
|
||||||
#include "rtc_base/thread.h"
|
#include "rtc_base/thread.h"
|
||||||
@ -36,8 +36,7 @@ namespace webrtc {
|
|||||||
// Multiple networks can be joined into chain emulating a network path from
|
// Multiple networks can be joined into chain emulating a network path from
|
||||||
// one peer to another.
|
// one peer to another.
|
||||||
class EmulatedNetworkNode;
|
class EmulatedNetworkNode;
|
||||||
// EmulatedEndpoint is and abstraction for network interface on device.
|
|
||||||
class EmulatedEndpoint;
|
|
||||||
// EmulatedRoute is handle for single route from one network interface on one
|
// EmulatedRoute is handle for single route from one network interface on one
|
||||||
// peer device to another network interface on another peer device.
|
// peer device to another network interface on another peer device.
|
||||||
class EmulatedRoute;
|
class EmulatedRoute;
|
||||||
@ -54,37 +53,6 @@ struct EmulatedEndpointConfig {
|
|||||||
bool start_as_enabled = true;
|
bool start_as_enabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EmulatedNetworkStats {
|
|
||||||
int64_t packets_sent = 0;
|
|
||||||
DataSize bytes_sent = DataSize::Zero();
|
|
||||||
// Total amount of packets received with or without destination.
|
|
||||||
int64_t packets_received = 0;
|
|
||||||
// Total amount of bytes in received packets.
|
|
||||||
DataSize bytes_received = DataSize::Zero();
|
|
||||||
// Total amount of packets that were received, but no destination was found.
|
|
||||||
int64_t packets_dropped = 0;
|
|
||||||
// Total amount of bytes in dropped packets.
|
|
||||||
DataSize bytes_dropped = DataSize::Zero();
|
|
||||||
|
|
||||||
DataSize first_received_packet_size = DataSize::Zero();
|
|
||||||
DataSize first_sent_packet_size = DataSize::Zero();
|
|
||||||
|
|
||||||
Timestamp first_packet_sent_time = Timestamp::PlusInfinity();
|
|
||||||
Timestamp last_packet_sent_time = Timestamp::PlusInfinity();
|
|
||||||
Timestamp first_packet_received_time = Timestamp::PlusInfinity();
|
|
||||||
Timestamp last_packet_received_time = Timestamp::PlusInfinity();
|
|
||||||
|
|
||||||
DataRate AverageSendRate() const {
|
|
||||||
RTC_DCHECK_GE(packets_sent, 2);
|
|
||||||
return (bytes_sent - first_sent_packet_size) /
|
|
||||||
(last_packet_sent_time - first_packet_sent_time);
|
|
||||||
}
|
|
||||||
DataRate AverageReceiveRate() const {
|
|
||||||
RTC_DCHECK_GE(packets_received, 2);
|
|
||||||
return (bytes_received - first_received_packet_size) /
|
|
||||||
(last_packet_received_time - first_packet_received_time);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Provide interface to obtain all required objects to inject network emulation
|
// Provide interface to obtain all required objects to inject network emulation
|
||||||
// layer into PeerConnection. Also contains information about network interfaces
|
// layer into PeerConnection. Also contains information about network interfaces
|
||||||
@ -106,6 +74,30 @@ class EmulatedNetworkManagerInterface {
|
|||||||
// and will be deleted when manager will be deleted.
|
// and will be deleted when manager will be deleted.
|
||||||
class NetworkEmulationManager {
|
class NetworkEmulationManager {
|
||||||
public:
|
public:
|
||||||
|
// Helper struct to simplify creation of simulated network behaviors. Contains
|
||||||
|
// non-owning pointers as the underlying instances are owned by the manager.
|
||||||
|
struct SimulatedNetworkNode {
|
||||||
|
SimulatedNetworkInterface* simulation;
|
||||||
|
EmulatedNetworkNode* node;
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
explicit Builder(NetworkEmulationManager* net) : net_(net) {}
|
||||||
|
Builder(const Builder&) = default;
|
||||||
|
// Sets the config state, note that this will replace any previously set
|
||||||
|
// values.
|
||||||
|
Builder& config(BuiltInNetworkBehaviorConfig config);
|
||||||
|
Builder& delay_ms(int queue_delay_ms);
|
||||||
|
Builder& capacity_kbps(int link_capacity_kbps);
|
||||||
|
Builder& capacity_Mbps(int link_capacity_Mbps);
|
||||||
|
Builder& loss(double loss_rate);
|
||||||
|
SimulatedNetworkNode Build() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
NetworkEmulationManager* const net_;
|
||||||
|
BuiltInNetworkBehaviorConfig config_;
|
||||||
|
};
|
||||||
|
};
|
||||||
virtual ~NetworkEmulationManager() = default;
|
virtual ~NetworkEmulationManager() = default;
|
||||||
|
|
||||||
// Creates an emulated network node, which represents single network in
|
// Creates an emulated network node, which represents single network in
|
||||||
@ -115,6 +107,8 @@ class NetworkEmulationManager {
|
|||||||
virtual EmulatedNetworkNode* CreateEmulatedNode(
|
virtual EmulatedNetworkNode* CreateEmulatedNode(
|
||||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior) = 0;
|
std::unique_ptr<NetworkBehaviorInterface> network_behavior) = 0;
|
||||||
|
|
||||||
|
virtual SimulatedNetworkNode::Builder NodeBuilder() = 0;
|
||||||
|
|
||||||
// Creates an emulated endpoint, which represents single network interface on
|
// Creates an emulated endpoint, which represents single network interface on
|
||||||
// the peer's device.
|
// the peer's device.
|
||||||
virtual EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) = 0;
|
virtual EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) = 0;
|
||||||
@ -149,11 +143,25 @@ class NetworkEmulationManager {
|
|||||||
EmulatedEndpoint* from,
|
EmulatedEndpoint* from,
|
||||||
const std::vector<EmulatedNetworkNode*>& via_nodes,
|
const std::vector<EmulatedNetworkNode*>& via_nodes,
|
||||||
EmulatedEndpoint* to) = 0;
|
EmulatedEndpoint* to) = 0;
|
||||||
|
|
||||||
|
// Creates a route over the given |via_nodes| creating the required endpoints
|
||||||
|
// in the process. The returned EmulatedRoute pointer can be used in other
|
||||||
|
// calls as a transport route for message or cross traffic.
|
||||||
|
virtual EmulatedRoute* CreateRoute(
|
||||||
|
const std::vector<EmulatedNetworkNode*>& via_nodes) = 0;
|
||||||
|
|
||||||
// Removes route previously created by CreateRoute(...).
|
// Removes route previously created by CreateRoute(...).
|
||||||
// Caller mustn't call this function with route, that have been already
|
// Caller mustn't call this function with route, that have been already
|
||||||
// removed earlier.
|
// removed earlier.
|
||||||
virtual void ClearRoute(EmulatedRoute* route) = 0;
|
virtual void ClearRoute(EmulatedRoute* route) = 0;
|
||||||
|
|
||||||
|
// Creates a simulated TCP connection using |send_route| for traffic and
|
||||||
|
// |ret_route| for feedback. This can be used to emulate HTTP cross traffic
|
||||||
|
// and to implement realistic reliable signaling over lossy networks.
|
||||||
|
// TODO(srte): Handle clearing of the routes involved.
|
||||||
|
virtual TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
|
||||||
|
EmulatedRoute* ret_route) = 0;
|
||||||
|
|
||||||
// Creates EmulatedNetworkManagerInterface which can be used then to inject
|
// Creates EmulatedNetworkManagerInterface which can be used then to inject
|
||||||
// network emulation layer into PeerConnection. |endpoints| - are available
|
// network emulation layer into PeerConnection. |endpoints| - are available
|
||||||
// network interfaces for PeerConnection. If endpoint is enabled, it will be
|
// network interfaces for PeerConnection. If endpoint is enabled, it will be
|
||||||
|
@ -80,6 +80,16 @@ class NetworkBehaviorInterface {
|
|||||||
virtual ~NetworkBehaviorInterface() = default;
|
virtual ~NetworkBehaviorInterface() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Class simulating a network link. This is a simple and naive solution just
|
||||||
|
// faking capacity and adding an extra transport delay in addition to the
|
||||||
|
// capacity introduced delay.
|
||||||
|
class SimulatedNetworkInterface : public NetworkBehaviorInterface {
|
||||||
|
public:
|
||||||
|
// Sets a new configuration. This won't affect packets already in the pipe.
|
||||||
|
virtual void SetConfig(const BuiltInNetworkBehaviorConfig& config) = 0;
|
||||||
|
virtual void PauseTransmissionUntil(int64_t until_us) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
#endif // API_TEST_SIMULATED_NETWORK_H_
|
#endif // API_TEST_SIMULATED_NETWORK_H_
|
||||||
|
@ -79,15 +79,14 @@ bool CoDelSimulation::DropDequeuedPacket(Timestamp now,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetwork::SimulatedNetwork(SimulatedNetwork::Config config,
|
SimulatedNetwork::SimulatedNetwork(Config config, uint64_t random_seed)
|
||||||
uint64_t random_seed)
|
|
||||||
: random_(random_seed), bursting_(false) {
|
: random_(random_seed), bursting_(false) {
|
||||||
SetConfig(config);
|
SetConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetwork::~SimulatedNetwork() = default;
|
SimulatedNetwork::~SimulatedNetwork() = default;
|
||||||
|
|
||||||
void SimulatedNetwork::SetConfig(const SimulatedNetwork::Config& config) {
|
void SimulatedNetwork::SetConfig(const Config& config) {
|
||||||
rtc::CritScope crit(&config_lock_);
|
rtc::CritScope crit(&config_lock_);
|
||||||
config_state_.config = config; // Shallow copy of the struct.
|
config_state_.config = config; // Shallow copy of the struct.
|
||||||
double prob_loss = config.loss_percent / 100.0;
|
double prob_loss = config.loss_percent / 100.0;
|
||||||
|
@ -54,15 +54,15 @@ class CoDelSimulation {
|
|||||||
// Class simulating a network link. This is a simple and naive solution just
|
// Class simulating a network link. This is a simple and naive solution just
|
||||||
// faking capacity and adding an extra transport delay in addition to the
|
// faking capacity and adding an extra transport delay in addition to the
|
||||||
// capacity introduced delay.
|
// capacity introduced delay.
|
||||||
class SimulatedNetwork : public NetworkBehaviorInterface {
|
class SimulatedNetwork : public SimulatedNetworkInterface {
|
||||||
public:
|
public:
|
||||||
using Config = BuiltInNetworkBehaviorConfig;
|
using Config = BuiltInNetworkBehaviorConfig;
|
||||||
explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
|
explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
|
||||||
~SimulatedNetwork() override;
|
~SimulatedNetwork() override;
|
||||||
|
|
||||||
// Sets a new configuration. This won't affect packets already in the pipe.
|
// Sets a new configuration. This won't affect packets already in the pipe.
|
||||||
void SetConfig(const Config& config);
|
void SetConfig(const Config& config) override;
|
||||||
void PauseTransmissionUntil(int64_t until_us);
|
void PauseTransmissionUntil(int64_t until_us) override;
|
||||||
|
|
||||||
// NetworkBehaviorInterface
|
// NetworkBehaviorInterface
|
||||||
bool EnqueuePacket(PacketInFlightInfo packet) override;
|
bool EnqueuePacket(PacketInFlightInfo packet) override;
|
||||||
|
@ -33,8 +33,6 @@ rtc_library("emulated_network") {
|
|||||||
"network_emulation.h",
|
"network_emulation.h",
|
||||||
"network_emulation_manager.cc",
|
"network_emulation_manager.cc",
|
||||||
"network_emulation_manager.h",
|
"network_emulation_manager.h",
|
||||||
"simulated_network_node.cc",
|
|
||||||
"simulated_network_node.h",
|
|
||||||
"traffic_route.cc",
|
"traffic_route.cc",
|
||||||
"traffic_route.h",
|
"traffic_route.h",
|
||||||
]
|
]
|
||||||
|
@ -116,10 +116,10 @@ ColumnPrinter PulsedPeaksCrossTraffic::StatsPrinter() {
|
|||||||
32);
|
32);
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpMessageRoute::TcpMessageRoute(Clock* clock,
|
TcpMessageRouteImpl::TcpMessageRouteImpl(Clock* clock,
|
||||||
TaskQueueBase* task_queue,
|
TaskQueueBase* task_queue,
|
||||||
EmulatedRoute* send_route,
|
EmulatedRoute* send_route,
|
||||||
EmulatedRoute* ret_route)
|
EmulatedRoute* ret_route)
|
||||||
: clock_(clock),
|
: clock_(clock),
|
||||||
task_queue_(task_queue),
|
task_queue_(task_queue),
|
||||||
request_route_(send_route,
|
request_route_(send_route,
|
||||||
@ -131,8 +131,8 @@ TcpMessageRoute::TcpMessageRoute(Clock* clock,
|
|||||||
OnResponse(std::move(packet), arrival_time);
|
OnResponse(std::move(packet), arrival_time);
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
void TcpMessageRoute::SendMessage(size_t size,
|
void TcpMessageRouteImpl::SendMessage(size_t size,
|
||||||
std::function<void()> on_received) {
|
std::function<void()> on_received) {
|
||||||
task_queue_->PostTask(
|
task_queue_->PostTask(
|
||||||
ToQueuedTask([this, size, handler = std::move(on_received)] {
|
ToQueuedTask([this, size, handler = std::move(on_received)] {
|
||||||
// If we are currently sending a message we won't reset the connection,
|
// If we are currently sending a message we won't reset the connection,
|
||||||
@ -159,7 +159,7 @@ void TcpMessageRoute::SendMessage(size_t size,
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpMessageRoute::OnRequest(TcpPacket packet_info) {
|
void TcpMessageRouteImpl::OnRequest(TcpPacket packet_info) {
|
||||||
for (auto it = messages_.begin(); it != messages_.end(); ++it) {
|
for (auto it = messages_.begin(); it != messages_.end(); ++it) {
|
||||||
if (it->pending_fragment_ids.count(packet_info.fragment.fragment_id) != 0) {
|
if (it->pending_fragment_ids.count(packet_info.fragment.fragment_id) != 0) {
|
||||||
it->pending_fragment_ids.erase(packet_info.fragment.fragment_id);
|
it->pending_fragment_ids.erase(packet_info.fragment.fragment_id);
|
||||||
@ -174,7 +174,7 @@ void TcpMessageRoute::OnRequest(TcpPacket packet_info) {
|
|||||||
response_route_.SendPacket(kAckPacketSize, packet_info);
|
response_route_.SendPacket(kAckPacketSize, packet_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpMessageRoute::OnResponse(TcpPacket packet_info, Timestamp at_time) {
|
void TcpMessageRouteImpl::OnResponse(TcpPacket packet_info, Timestamp at_time) {
|
||||||
auto it = in_flight_.find(packet_info.sequence_number);
|
auto it = in_flight_.find(packet_info.sequence_number);
|
||||||
if (it != in_flight_.end()) {
|
if (it != in_flight_.end()) {
|
||||||
last_rtt_ = at_time - packet_info.send_time;
|
last_rtt_ = at_time - packet_info.send_time;
|
||||||
@ -198,7 +198,7 @@ void TcpMessageRoute::OnResponse(TcpPacket packet_info, Timestamp at_time) {
|
|||||||
SendPackets(at_time);
|
SendPackets(at_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpMessageRoute::HandleLoss(Timestamp at_time) {
|
void TcpMessageRouteImpl::HandleLoss(Timestamp at_time) {
|
||||||
if (at_time - last_reduction_time_ < last_rtt_)
|
if (at_time - last_reduction_time_ < last_rtt_)
|
||||||
return;
|
return;
|
||||||
last_reduction_time_ = at_time;
|
last_reduction_time_ = at_time;
|
||||||
@ -206,7 +206,7 @@ void TcpMessageRoute::HandleLoss(Timestamp at_time) {
|
|||||||
cwnd_ = ssthresh_;
|
cwnd_ = ssthresh_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpMessageRoute::SendPackets(Timestamp at_time) {
|
void TcpMessageRouteImpl::SendPackets(Timestamp at_time) {
|
||||||
const TimeDelta kPacketTimeout = TimeDelta::seconds(1);
|
const TimeDelta kPacketTimeout = TimeDelta::seconds(1);
|
||||||
int cwnd = std::ceil(cwnd_);
|
int cwnd = std::ceil(cwnd_);
|
||||||
int packets_to_send = std::max(cwnd - static_cast<int>(in_flight_.size()), 0);
|
int packets_to_send = std::max(cwnd - static_cast<int>(in_flight_.size()), 0);
|
||||||
@ -227,7 +227,7 @@ void TcpMessageRoute::SendPackets(Timestamp at_time) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpMessageRoute::HandlePacketTimeout(int seq_num, Timestamp at_time) {
|
void TcpMessageRouteImpl::HandlePacketTimeout(int seq_num, Timestamp at_time) {
|
||||||
auto lost = in_flight_.find(seq_num);
|
auto lost = in_flight_.find(seq_num);
|
||||||
if (lost != in_flight_.end()) {
|
if (lost != in_flight_.end()) {
|
||||||
pending_.push_front(lost->second.fragment);
|
pending_.push_front(lost->second.fragment);
|
||||||
|
@ -92,22 +92,17 @@ class PulsedPeaksCrossTraffic {
|
|||||||
bool sending_ RTC_GUARDED_BY(sequence_checker_) = false;
|
bool sending_ RTC_GUARDED_BY(sequence_checker_) = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simulates a TCP connection, this roughly implements the Reno algorithm. In
|
class TcpMessageRouteImpl final : public TcpMessageRoute {
|
||||||
// difference from TCP this only support sending messages with a fixed length,
|
|
||||||
// no streaming. This is useful to simulate signaling and cross traffic using
|
|
||||||
// message based protocols such as HTTP. It differs from UDP messages in that
|
|
||||||
// they are guranteed to be delivered eventually, even on lossy networks.
|
|
||||||
class TcpMessageRoute {
|
|
||||||
public:
|
public:
|
||||||
TcpMessageRoute(Clock* clock,
|
TcpMessageRouteImpl(Clock* clock,
|
||||||
TaskQueueBase* task_queue,
|
TaskQueueBase* task_queue,
|
||||||
EmulatedRoute* send_route,
|
EmulatedRoute* send_route,
|
||||||
EmulatedRoute* ret_route);
|
EmulatedRoute* ret_route);
|
||||||
|
|
||||||
// Sends a TCP message of the given |size| over the route, |on_received| is
|
// Sends a TCP message of the given |size| over the route, |on_received| is
|
||||||
// called when the message has been delivered. Note that the connection
|
// called when the message has been delivered. Note that the connection
|
||||||
// parameters are reset iff there's no currently pending message on the route.
|
// parameters are reset iff there's no currently pending message on the route.
|
||||||
void SendMessage(size_t size, std::function<void()> on_received);
|
void SendMessage(size_t size, std::function<void()> on_received) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Represents a message sent over the route. When all fragments has been
|
// Represents a message sent over the route. When all fragments has been
|
||||||
|
@ -45,8 +45,8 @@ struct TrafficCounterFixture {
|
|||||||
SimulatedClock clock{0};
|
SimulatedClock clock{0};
|
||||||
CountingReceiver counter;
|
CountingReceiver counter;
|
||||||
TaskQueueForTest task_queue_;
|
TaskQueueForTest task_queue_;
|
||||||
EmulatedEndpoint endpoint{/*id=*/1, rtc::IPAddress(kTestIpAddress),
|
EmulatedEndpointImpl endpoint{/*id=*/1, rtc::IPAddress(kTestIpAddress),
|
||||||
/*is_enabled=*/true, &task_queue_, &clock};
|
/*is_enabled=*/true, &task_queue_, &clock};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -32,7 +32,7 @@ EmulatedNetworkManager::EmulatedNetworkManager(
|
|||||||
network_thread_.Start();
|
network_thread_.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedNetworkManager::EnableEndpoint(EmulatedEndpoint* endpoint) {
|
void EmulatedNetworkManager::EnableEndpoint(EmulatedEndpointImpl* endpoint) {
|
||||||
RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
|
RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
|
||||||
<< "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
|
<< "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
|
||||||
network_thread_.PostTask(RTC_FROM_HERE, [this, endpoint]() {
|
network_thread_.PostTask(RTC_FROM_HERE, [this, endpoint]() {
|
||||||
@ -41,7 +41,7 @@ void EmulatedNetworkManager::EnableEndpoint(EmulatedEndpoint* endpoint) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedNetworkManager::DisableEndpoint(EmulatedEndpoint* endpoint) {
|
void EmulatedNetworkManager::DisableEndpoint(EmulatedEndpointImpl* endpoint) {
|
||||||
RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
|
RTC_CHECK(endpoints_container_->HasEndpoint(endpoint))
|
||||||
<< "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
|
<< "No such interface: " << endpoint->GetPeerLocalAddress().ToString();
|
||||||
network_thread_.PostTask(RTC_FROM_HERE, [this, endpoint]() {
|
network_thread_.PostTask(RTC_FROM_HERE, [this, endpoint]() {
|
||||||
|
@ -36,8 +36,8 @@ class EmulatedNetworkManager : public rtc::NetworkManagerBase,
|
|||||||
TaskQueueForTest* task_queue,
|
TaskQueueForTest* task_queue,
|
||||||
EndpointsContainer* endpoints_container);
|
EndpointsContainer* endpoints_container);
|
||||||
|
|
||||||
void EnableEndpoint(EmulatedEndpoint* endpoint);
|
void EnableEndpoint(EmulatedEndpointImpl* endpoint);
|
||||||
void DisableEndpoint(EmulatedEndpoint* endpoint);
|
void DisableEndpoint(EmulatedEndpointImpl* endpoint);
|
||||||
|
|
||||||
// NetworkManager interface. All these methods are supposed to be called from
|
// NetworkManager interface. All these methods are supposed to be called from
|
||||||
// the same thread.
|
// the same thread.
|
||||||
|
@ -39,7 +39,7 @@ class SocketManager {
|
|||||||
virtual void WakeUp() = 0;
|
virtual void WakeUp() = 0;
|
||||||
virtual void Unregister(SocketIoProcessor* io_processor) = 0;
|
virtual void Unregister(SocketIoProcessor* io_processor) = 0;
|
||||||
// Provides endpoints by IP address.
|
// Provides endpoints by IP address.
|
||||||
virtual EmulatedEndpoint* GetEndpointNode(const rtc::IPAddress& ip) = 0;
|
virtual EmulatedEndpointImpl* GetEndpointNode(const rtc::IPAddress& ip) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents a socket, which will operate with emulated network.
|
// Represents a socket, which will operate with emulated network.
|
||||||
@ -82,7 +82,7 @@ class FakeNetworkSocket : public rtc::AsyncSocket,
|
|||||||
absl::optional<EmulatedIpPacket> PopFrontPacket();
|
absl::optional<EmulatedIpPacket> PopFrontPacket();
|
||||||
|
|
||||||
SocketManager* const socket_manager_;
|
SocketManager* const socket_manager_;
|
||||||
EmulatedEndpoint* endpoint_;
|
EmulatedEndpointImpl* endpoint_;
|
||||||
|
|
||||||
rtc::SocketAddress local_addr_;
|
rtc::SocketAddress local_addr_;
|
||||||
rtc::SocketAddress remote_addr_;
|
rtc::SocketAddress remote_addr_;
|
||||||
|
@ -29,7 +29,7 @@ void FakeNetworkSocketServer::OnMessageQueueDestroyed() {
|
|||||||
msg_queue_ = nullptr;
|
msg_queue_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulatedEndpoint* FakeNetworkSocketServer::GetEndpointNode(
|
EmulatedEndpointImpl* FakeNetworkSocketServer::GetEndpointNode(
|
||||||
const rtc::IPAddress& ip) {
|
const rtc::IPAddress& ip) {
|
||||||
return endpoints_container_->LookupByLocalAddress(ip);
|
return endpoints_container_->LookupByLocalAddress(ip);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ class FakeNetworkSocketServer : public rtc::SocketServer,
|
|||||||
EndpointsContainer* endpoints_controller);
|
EndpointsContainer* endpoints_controller);
|
||||||
~FakeNetworkSocketServer() override;
|
~FakeNetworkSocketServer() override;
|
||||||
|
|
||||||
EmulatedEndpoint* GetEndpointNode(const rtc::IPAddress& ip) override;
|
EmulatedEndpointImpl* GetEndpointNode(const rtc::IPAddress& ip) override;
|
||||||
void Unregister(SocketIoProcessor* io_processor) override;
|
void Unregister(SocketIoProcessor* io_processor) override;
|
||||||
void OnMessageQueueDestroyed();
|
void OnMessageQueueDestroyed();
|
||||||
|
|
||||||
|
@ -20,24 +20,6 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
namespace {
|
|
||||||
constexpr size_t kIPv4HeaderSize = 20;
|
|
||||||
constexpr size_t kIPv6HeaderSize = 40;
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
|
|
||||||
const rtc::SocketAddress& to,
|
|
||||||
rtc::CopyOnWriteBuffer data,
|
|
||||||
Timestamp arrival_time)
|
|
||||||
: from(from),
|
|
||||||
to(to),
|
|
||||||
data(data),
|
|
||||||
ip_header_size((to.family() == AF_INET) ? kIPv4HeaderSize
|
|
||||||
: kIPv6HeaderSize),
|
|
||||||
arrival_time(arrival_time) {
|
|
||||||
RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
void LinkEmulation::OnPacketReceived(EmulatedIpPacket packet) {
|
||||||
task_queue_->PostTask([this, packet = std::move(packet)]() mutable {
|
task_queue_->PostTask([this, packet = std::move(packet)]() mutable {
|
||||||
RTC_DCHECK_RUN_ON(task_queue_);
|
RTC_DCHECK_RUN_ON(task_queue_);
|
||||||
@ -172,11 +154,11 @@ void EmulatedNetworkNode::ClearRoute(rtc::IPAddress receiver_ip,
|
|||||||
|
|
||||||
EmulatedNetworkNode::~EmulatedNetworkNode() = default;
|
EmulatedNetworkNode::~EmulatedNetworkNode() = default;
|
||||||
|
|
||||||
EmulatedEndpoint::EmulatedEndpoint(uint64_t id,
|
EmulatedEndpointImpl::EmulatedEndpointImpl(uint64_t id,
|
||||||
const rtc::IPAddress& ip,
|
const rtc::IPAddress& ip,
|
||||||
bool is_enabled,
|
bool is_enabled,
|
||||||
rtc::TaskQueue* task_queue,
|
rtc::TaskQueue* task_queue,
|
||||||
Clock* clock)
|
Clock* clock)
|
||||||
: id_(id),
|
: id_(id),
|
||||||
peer_local_addr_(ip),
|
peer_local_addr_(ip),
|
||||||
is_enabled_(is_enabled),
|
is_enabled_(is_enabled),
|
||||||
@ -201,15 +183,15 @@ EmulatedEndpoint::EmulatedEndpoint(uint64_t id,
|
|||||||
|
|
||||||
enabled_state_checker_.Detach();
|
enabled_state_checker_.Detach();
|
||||||
}
|
}
|
||||||
EmulatedEndpoint::~EmulatedEndpoint() = default;
|
EmulatedEndpointImpl::~EmulatedEndpointImpl() = default;
|
||||||
|
|
||||||
uint64_t EmulatedEndpoint::GetId() const {
|
uint64_t EmulatedEndpointImpl::GetId() const {
|
||||||
return id_;
|
return id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedEndpoint::SendPacket(const rtc::SocketAddress& from,
|
void EmulatedEndpointImpl::SendPacket(const rtc::SocketAddress& from,
|
||||||
const rtc::SocketAddress& to,
|
const rtc::SocketAddress& to,
|
||||||
rtc::CopyOnWriteBuffer packet_data) {
|
rtc::CopyOnWriteBuffer packet_data) {
|
||||||
RTC_CHECK(from.ipaddr() == peer_local_addr_);
|
RTC_CHECK(from.ipaddr() == peer_local_addr_);
|
||||||
EmulatedIpPacket packet(from, to, std::move(packet_data),
|
EmulatedIpPacket packet(from, to, std::move(packet_data),
|
||||||
clock_->CurrentTime());
|
clock_->CurrentTime());
|
||||||
@ -228,7 +210,7 @@ void EmulatedEndpoint::SendPacket(const rtc::SocketAddress& from,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::optional<uint16_t> EmulatedEndpoint::BindReceiver(
|
absl::optional<uint16_t> EmulatedEndpointImpl::BindReceiver(
|
||||||
uint16_t desired_port,
|
uint16_t desired_port,
|
||||||
EmulatedNetworkReceiverInterface* receiver) {
|
EmulatedNetworkReceiverInterface* receiver) {
|
||||||
rtc::CritScope crit(&receiver_lock_);
|
rtc::CritScope crit(&receiver_lock_);
|
||||||
@ -259,7 +241,7 @@ absl::optional<uint16_t> EmulatedEndpoint::BindReceiver(
|
|||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t EmulatedEndpoint::NextPort() {
|
uint16_t EmulatedEndpointImpl::NextPort() {
|
||||||
uint16_t out = next_port_;
|
uint16_t out = next_port_;
|
||||||
if (next_port_ == std::numeric_limits<uint16_t>::max()) {
|
if (next_port_ == std::numeric_limits<uint16_t>::max()) {
|
||||||
next_port_ = kFirstEphemeralPort;
|
next_port_ = kFirstEphemeralPort;
|
||||||
@ -269,16 +251,16 @@ uint16_t EmulatedEndpoint::NextPort() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedEndpoint::UnbindReceiver(uint16_t port) {
|
void EmulatedEndpointImpl::UnbindReceiver(uint16_t port) {
|
||||||
rtc::CritScope crit(&receiver_lock_);
|
rtc::CritScope crit(&receiver_lock_);
|
||||||
port_to_receiver_.erase(port);
|
port_to_receiver_.erase(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::IPAddress EmulatedEndpoint::GetPeerLocalAddress() const {
|
rtc::IPAddress EmulatedEndpointImpl::GetPeerLocalAddress() const {
|
||||||
return peer_local_addr_;
|
return peer_local_addr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedEndpoint::OnPacketReceived(EmulatedIpPacket packet) {
|
void EmulatedEndpointImpl::OnPacketReceived(EmulatedIpPacket packet) {
|
||||||
RTC_DCHECK_RUN_ON(task_queue_);
|
RTC_DCHECK_RUN_ON(task_queue_);
|
||||||
RTC_CHECK(packet.to.ipaddr() == peer_local_addr_)
|
RTC_CHECK(packet.to.ipaddr() == peer_local_addr_)
|
||||||
<< "Routing error: wrong destination endpoint. Packet.to.ipaddr()=: "
|
<< "Routing error: wrong destination endpoint. Packet.to.ipaddr()=: "
|
||||||
@ -303,29 +285,29 @@ void EmulatedEndpoint::OnPacketReceived(EmulatedIpPacket packet) {
|
|||||||
it->second->OnPacketReceived(std::move(packet));
|
it->second->OnPacketReceived(std::move(packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedEndpoint::Enable() {
|
void EmulatedEndpointImpl::Enable() {
|
||||||
RTC_DCHECK_RUN_ON(&enabled_state_checker_);
|
RTC_DCHECK_RUN_ON(&enabled_state_checker_);
|
||||||
RTC_CHECK(!is_enabled_);
|
RTC_CHECK(!is_enabled_);
|
||||||
is_enabled_ = true;
|
is_enabled_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedEndpoint::Disable() {
|
void EmulatedEndpointImpl::Disable() {
|
||||||
RTC_DCHECK_RUN_ON(&enabled_state_checker_);
|
RTC_DCHECK_RUN_ON(&enabled_state_checker_);
|
||||||
RTC_CHECK(is_enabled_);
|
RTC_CHECK(is_enabled_);
|
||||||
is_enabled_ = false;
|
is_enabled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedEndpoint::Enabled() const {
|
bool EmulatedEndpointImpl::Enabled() const {
|
||||||
RTC_DCHECK_RUN_ON(&enabled_state_checker_);
|
RTC_DCHECK_RUN_ON(&enabled_state_checker_);
|
||||||
return is_enabled_;
|
return is_enabled_;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulatedNetworkStats EmulatedEndpoint::stats() {
|
EmulatedNetworkStats EmulatedEndpointImpl::stats() {
|
||||||
RTC_DCHECK_RUN_ON(task_queue_);
|
RTC_DCHECK_RUN_ON(task_queue_);
|
||||||
return stats_;
|
return stats_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedEndpoint::UpdateReceiveStats(const EmulatedIpPacket& packet) {
|
void EmulatedEndpointImpl::UpdateReceiveStats(const EmulatedIpPacket& packet) {
|
||||||
RTC_DCHECK_RUN_ON(task_queue_);
|
RTC_DCHECK_RUN_ON(task_queue_);
|
||||||
Timestamp current_time = clock_->CurrentTime();
|
Timestamp current_time = clock_->CurrentTime();
|
||||||
if (stats_.first_packet_received_time.IsInfinite()) {
|
if (stats_.first_packet_received_time.IsInfinite()) {
|
||||||
@ -339,10 +321,10 @@ void EmulatedEndpoint::UpdateReceiveStats(const EmulatedIpPacket& packet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EndpointsContainer::EndpointsContainer(
|
EndpointsContainer::EndpointsContainer(
|
||||||
const std::vector<EmulatedEndpoint*>& endpoints)
|
const std::vector<EmulatedEndpointImpl*>& endpoints)
|
||||||
: endpoints_(endpoints) {}
|
: endpoints_(endpoints) {}
|
||||||
|
|
||||||
EmulatedEndpoint* EndpointsContainer::LookupByLocalAddress(
|
EmulatedEndpointImpl* EndpointsContainer::LookupByLocalAddress(
|
||||||
const rtc::IPAddress& local_ip) const {
|
const rtc::IPAddress& local_ip) const {
|
||||||
for (auto* endpoint : endpoints_) {
|
for (auto* endpoint : endpoints_) {
|
||||||
rtc::IPAddress peer_local_address = endpoint->GetPeerLocalAddress();
|
rtc::IPAddress peer_local_address = endpoint->GetPeerLocalAddress();
|
||||||
@ -353,7 +335,7 @@ EmulatedEndpoint* EndpointsContainer::LookupByLocalAddress(
|
|||||||
RTC_CHECK(false) << "No network found for address" << local_ip.ToString();
|
RTC_CHECK(false) << "No network found for address" << local_ip.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EndpointsContainer::HasEndpoint(EmulatedEndpoint* endpoint) const {
|
bool EndpointsContainer::HasEndpoint(EmulatedEndpointImpl* endpoint) const {
|
||||||
for (auto* e : endpoints_) {
|
for (auto* e : endpoints_) {
|
||||||
if (e->GetId() == endpoint->GetId()) {
|
if (e->GetId() == endpoint->GetId()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -33,42 +33,6 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
struct EmulatedIpPacket {
|
|
||||||
public:
|
|
||||||
static constexpr int kUdpHeaderSize = 8;
|
|
||||||
|
|
||||||
EmulatedIpPacket(const rtc::SocketAddress& from,
|
|
||||||
const rtc::SocketAddress& to,
|
|
||||||
rtc::CopyOnWriteBuffer data,
|
|
||||||
Timestamp arrival_time);
|
|
||||||
~EmulatedIpPacket() = default;
|
|
||||||
// This object is not copyable or assignable.
|
|
||||||
EmulatedIpPacket(const EmulatedIpPacket&) = delete;
|
|
||||||
EmulatedIpPacket& operator=(const EmulatedIpPacket&) = delete;
|
|
||||||
// This object is only moveable.
|
|
||||||
EmulatedIpPacket(EmulatedIpPacket&&) = default;
|
|
||||||
EmulatedIpPacket& operator=(EmulatedIpPacket&&) = default;
|
|
||||||
|
|
||||||
size_t size() const { return data.size(); }
|
|
||||||
const uint8_t* cdata() const { return data.cdata(); }
|
|
||||||
|
|
||||||
size_t ip_packet_size() const {
|
|
||||||
return size() + kUdpHeaderSize + ip_header_size;
|
|
||||||
}
|
|
||||||
rtc::SocketAddress from;
|
|
||||||
rtc::SocketAddress to;
|
|
||||||
// Holds the UDP payload.
|
|
||||||
rtc::CopyOnWriteBuffer data;
|
|
||||||
int ip_header_size;
|
|
||||||
Timestamp arrival_time;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EmulatedNetworkReceiverInterface {
|
|
||||||
public:
|
|
||||||
virtual ~EmulatedNetworkReceiverInterface() = default;
|
|
||||||
|
|
||||||
virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinkEmulation : public EmulatedNetworkReceiverInterface {
|
class LinkEmulation : public EmulatedNetworkReceiverInterface {
|
||||||
public:
|
public:
|
||||||
@ -158,42 +122,29 @@ class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
|
|||||||
// It will be used as sender from socket side to send data to the network and
|
// It will be used as sender from socket side to send data to the network and
|
||||||
// will act as packet receiver from emulated network side to receive packets
|
// will act as packet receiver from emulated network side to receive packets
|
||||||
// from other EmulatedNetworkNodes.
|
// from other EmulatedNetworkNodes.
|
||||||
class EmulatedEndpoint : public EmulatedNetworkReceiverInterface {
|
class EmulatedEndpointImpl : public EmulatedEndpoint {
|
||||||
public:
|
public:
|
||||||
EmulatedEndpoint(uint64_t id,
|
EmulatedEndpointImpl(uint64_t id,
|
||||||
const rtc::IPAddress& ip,
|
const rtc::IPAddress& ip,
|
||||||
bool is_enabled,
|
bool is_enabled,
|
||||||
rtc::TaskQueue* task_queue,
|
rtc::TaskQueue* task_queue,
|
||||||
Clock* clock);
|
Clock* clock);
|
||||||
~EmulatedEndpoint() override;
|
~EmulatedEndpointImpl() override;
|
||||||
|
|
||||||
uint64_t GetId() const;
|
uint64_t GetId() const;
|
||||||
|
|
||||||
NetworkRouterNode* router() { return &router_; }
|
NetworkRouterNode* router() { return &router_; }
|
||||||
// Send packet into network.
|
|
||||||
// |from| will be used to set source address for the packet in destination
|
|
||||||
// socket.
|
|
||||||
// |to| will be used for routing verification and picking right socket by port
|
|
||||||
// on destination endpoint.
|
|
||||||
void SendPacket(const rtc::SocketAddress& from,
|
void SendPacket(const rtc::SocketAddress& from,
|
||||||
const rtc::SocketAddress& to,
|
const rtc::SocketAddress& to,
|
||||||
rtc::CopyOnWriteBuffer packet_data);
|
rtc::CopyOnWriteBuffer packet_data) override;
|
||||||
|
|
||||||
// Binds receiver to this endpoint to send and receive data.
|
|
||||||
// |desired_port| is a port that should be used. If it is equal to 0,
|
|
||||||
// endpoint will pick the first available port starting from
|
|
||||||
// |kFirstEphemeralPort|.
|
|
||||||
//
|
|
||||||
// Returns the port, that should be used (it will be equals to desired, if
|
|
||||||
// |desired_port| != 0 and is free or will be the one, selected by endpoint)
|
|
||||||
// or absl::nullopt if desired_port in used. Also fails if there are no more
|
|
||||||
// free ports to bind to.
|
|
||||||
absl::optional<uint16_t> BindReceiver(
|
absl::optional<uint16_t> BindReceiver(
|
||||||
uint16_t desired_port,
|
uint16_t desired_port,
|
||||||
EmulatedNetworkReceiverInterface* receiver);
|
EmulatedNetworkReceiverInterface* receiver) override;
|
||||||
void UnbindReceiver(uint16_t port);
|
void UnbindReceiver(uint16_t port) override;
|
||||||
|
|
||||||
rtc::IPAddress GetPeerLocalAddress() const;
|
rtc::IPAddress GetPeerLocalAddress() const override;
|
||||||
|
|
||||||
// Will be called to deliver packet into endpoint from network node.
|
// Will be called to deliver packet into endpoint from network node.
|
||||||
void OnPacketReceived(EmulatedIpPacket packet) override;
|
void OnPacketReceived(EmulatedIpPacket packet) override;
|
||||||
@ -204,7 +155,7 @@ class EmulatedEndpoint : public EmulatedNetworkReceiverInterface {
|
|||||||
|
|
||||||
const rtc::Network& network() const { return *network_.get(); }
|
const rtc::Network& network() const { return *network_.get(); }
|
||||||
|
|
||||||
EmulatedNetworkStats stats();
|
EmulatedNetworkStats stats() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint16_t kFirstEphemeralPort = 49152;
|
static constexpr uint16_t kFirstEphemeralPort = 49152;
|
||||||
@ -232,29 +183,31 @@ class EmulatedEndpoint : public EmulatedNetworkReceiverInterface {
|
|||||||
|
|
||||||
class EmulatedRoute {
|
class EmulatedRoute {
|
||||||
public:
|
public:
|
||||||
EmulatedRoute(EmulatedEndpoint* from,
|
EmulatedRoute(EmulatedEndpointImpl* from,
|
||||||
std::vector<EmulatedNetworkNode*> via_nodes,
|
std::vector<EmulatedNetworkNode*> via_nodes,
|
||||||
EmulatedEndpoint* to)
|
EmulatedEndpointImpl* to)
|
||||||
: from(from), via_nodes(std::move(via_nodes)), to(to), active(true) {}
|
: from(from), via_nodes(std::move(via_nodes)), to(to), active(true) {}
|
||||||
|
|
||||||
EmulatedEndpoint* from;
|
EmulatedEndpointImpl* from;
|
||||||
std::vector<EmulatedNetworkNode*> via_nodes;
|
std::vector<EmulatedNetworkNode*> via_nodes;
|
||||||
EmulatedEndpoint* to;
|
EmulatedEndpointImpl* to;
|
||||||
bool active;
|
bool active;
|
||||||
};
|
};
|
||||||
class EndpointsContainer {
|
class EndpointsContainer {
|
||||||
public:
|
public:
|
||||||
explicit EndpointsContainer(const std::vector<EmulatedEndpoint*>& endpoints);
|
explicit EndpointsContainer(
|
||||||
|
const std::vector<EmulatedEndpointImpl*>& endpoints);
|
||||||
|
|
||||||
EmulatedEndpoint* LookupByLocalAddress(const rtc::IPAddress& local_ip) const;
|
EmulatedEndpointImpl* LookupByLocalAddress(
|
||||||
bool HasEndpoint(EmulatedEndpoint* endpoint) const;
|
const rtc::IPAddress& local_ip) const;
|
||||||
|
bool HasEndpoint(EmulatedEndpointImpl* endpoint) const;
|
||||||
// Returns list of networks for enabled endpoints. Caller takes ownership of
|
// Returns list of networks for enabled endpoints. Caller takes ownership of
|
||||||
// returned rtc::Network objects.
|
// returned rtc::Network objects.
|
||||||
std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
|
std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
|
||||||
EmulatedNetworkStats GetStats() const;
|
EmulatedNetworkStats GetStats() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<EmulatedEndpoint*> endpoints_;
|
const std::vector<EmulatedEndpointImpl*> endpoints_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FakePacketType>
|
template <typename FakePacketType>
|
||||||
|
@ -62,7 +62,8 @@ EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder NetworkEmulationManagerImpl::NodeBuilder() {
|
NetworkEmulationManager::SimulatedNetworkNode::Builder
|
||||||
|
NetworkEmulationManagerImpl::NodeBuilder() {
|
||||||
return SimulatedNetworkNode::Builder(this);
|
return SimulatedNetworkNode::Builder(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ EmulatedEndpoint* NetworkEmulationManagerImpl::CreateEndpoint(
|
|||||||
|
|
||||||
bool res = used_ip_addresses_.insert(*ip).second;
|
bool res = used_ip_addresses_.insert(*ip).second;
|
||||||
RTC_CHECK(res) << "IP=" << ip->ToString() << " already in use";
|
RTC_CHECK(res) << "IP=" << ip->ToString() << " already in use";
|
||||||
auto node = std::make_unique<EmulatedEndpoint>(
|
auto node = std::make_unique<EmulatedEndpointImpl>(
|
||||||
next_node_id_++, *ip, config.start_as_enabled, &task_queue_, clock_);
|
next_node_id_++, *ip, config.start_as_enabled, &task_queue_, clock_);
|
||||||
EmulatedEndpoint* out = node.get();
|
EmulatedEndpoint* out = node.get();
|
||||||
endpoints_.push_back(std::move(node));
|
endpoints_.push_back(std::move(node));
|
||||||
@ -96,14 +97,15 @@ void NetworkEmulationManagerImpl::EnableEndpoint(EmulatedEndpoint* endpoint) {
|
|||||||
EmulatedNetworkManager* network_manager =
|
EmulatedNetworkManager* network_manager =
|
||||||
endpoint_to_network_manager_[endpoint];
|
endpoint_to_network_manager_[endpoint];
|
||||||
RTC_CHECK(network_manager);
|
RTC_CHECK(network_manager);
|
||||||
network_manager->EnableEndpoint(endpoint);
|
network_manager->EnableEndpoint(static_cast<EmulatedEndpointImpl*>(endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkEmulationManagerImpl::DisableEndpoint(EmulatedEndpoint* endpoint) {
|
void NetworkEmulationManagerImpl::DisableEndpoint(EmulatedEndpoint* endpoint) {
|
||||||
EmulatedNetworkManager* network_manager =
|
EmulatedNetworkManager* network_manager =
|
||||||
endpoint_to_network_manager_[endpoint];
|
endpoint_to_network_manager_[endpoint];
|
||||||
RTC_CHECK(network_manager);
|
RTC_CHECK(network_manager);
|
||||||
network_manager->DisableEndpoint(endpoint);
|
network_manager->DisableEndpoint(
|
||||||
|
static_cast<EmulatedEndpointImpl*>(endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
|
EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
|
||||||
@ -114,7 +116,8 @@ EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
|
|||||||
// provided here.
|
// provided here.
|
||||||
RTC_CHECK(!via_nodes.empty());
|
RTC_CHECK(!via_nodes.empty());
|
||||||
|
|
||||||
from->router()->SetReceiver(to->GetPeerLocalAddress(), via_nodes[0]);
|
static_cast<EmulatedEndpointImpl*>(from)->router()->SetReceiver(
|
||||||
|
to->GetPeerLocalAddress(), via_nodes[0]);
|
||||||
EmulatedNetworkNode* cur_node = via_nodes[0];
|
EmulatedNetworkNode* cur_node = via_nodes[0];
|
||||||
for (size_t i = 1; i < via_nodes.size(); ++i) {
|
for (size_t i = 1; i < via_nodes.size(); ++i) {
|
||||||
cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), via_nodes[i]);
|
cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), via_nodes[i]);
|
||||||
@ -122,8 +125,9 @@ EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
|
|||||||
}
|
}
|
||||||
cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), to);
|
cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), to);
|
||||||
|
|
||||||
std::unique_ptr<EmulatedRoute> route =
|
std::unique_ptr<EmulatedRoute> route = std::make_unique<EmulatedRoute>(
|
||||||
std::make_unique<EmulatedRoute>(from, std::move(via_nodes), to);
|
static_cast<EmulatedEndpointImpl*>(from), std::move(via_nodes),
|
||||||
|
static_cast<EmulatedEndpointImpl*>(to));
|
||||||
EmulatedRoute* out = route.get();
|
EmulatedRoute* out = route.get();
|
||||||
routes_.push_back(std::move(route));
|
routes_.push_back(std::move(route));
|
||||||
return out;
|
return out;
|
||||||
@ -231,8 +235,8 @@ FakeTcpCrossTraffic* NetworkEmulationManagerImpl::StartFakeTcpCrossTraffic(
|
|||||||
TcpMessageRoute* NetworkEmulationManagerImpl::CreateTcpRoute(
|
TcpMessageRoute* NetworkEmulationManagerImpl::CreateTcpRoute(
|
||||||
EmulatedRoute* send_route,
|
EmulatedRoute* send_route,
|
||||||
EmulatedRoute* ret_route) {
|
EmulatedRoute* ret_route) {
|
||||||
auto tcp_route = std::make_unique<TcpMessageRoute>(clock_, task_queue_.Get(),
|
auto tcp_route = std::make_unique<TcpMessageRouteImpl>(
|
||||||
send_route, ret_route);
|
clock_, task_queue_.Get(), send_route, ret_route);
|
||||||
auto* route_ptr = tcp_route.get();
|
auto* route_ptr = tcp_route.get();
|
||||||
task_queue_.PostTask([this, tcp_route = std::move(tcp_route)]() mutable {
|
task_queue_.PostTask([this, tcp_route = std::move(tcp_route)]() mutable {
|
||||||
tcp_message_routes_.push_back(std::move(tcp_route));
|
tcp_message_routes_.push_back(std::move(tcp_route));
|
||||||
@ -254,7 +258,12 @@ void NetworkEmulationManagerImpl::StopCrossTraffic(
|
|||||||
EmulatedNetworkManagerInterface*
|
EmulatedNetworkManagerInterface*
|
||||||
NetworkEmulationManagerImpl::CreateEmulatedNetworkManagerInterface(
|
NetworkEmulationManagerImpl::CreateEmulatedNetworkManagerInterface(
|
||||||
const std::vector<EmulatedEndpoint*>& endpoints) {
|
const std::vector<EmulatedEndpoint*>& endpoints) {
|
||||||
auto endpoints_container = std::make_unique<EndpointsContainer>(endpoints);
|
std::vector<EmulatedEndpointImpl*> endpoint_impls;
|
||||||
|
for (EmulatedEndpoint* endpoint : endpoints) {
|
||||||
|
endpoint_impls.push_back(static_cast<EmulatedEndpointImpl*>(endpoint));
|
||||||
|
}
|
||||||
|
auto endpoints_container =
|
||||||
|
std::make_unique<EndpointsContainer>(endpoint_impls);
|
||||||
auto network_manager = std::make_unique<EmulatedNetworkManager>(
|
auto network_manager = std::make_unique<EmulatedNetworkManager>(
|
||||||
clock_, &task_queue_, endpoints_container.get());
|
clock_, &task_queue_, endpoints_container.get());
|
||||||
for (auto* endpoint : endpoints) {
|
for (auto* endpoint : endpoints) {
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include "test/network/emulated_network_manager.h"
|
#include "test/network/emulated_network_manager.h"
|
||||||
#include "test/network/fake_network_socket_server.h"
|
#include "test/network/fake_network_socket_server.h"
|
||||||
#include "test/network/network_emulation.h"
|
#include "test/network/network_emulation.h"
|
||||||
#include "test/network/simulated_network_node.h"
|
|
||||||
#include "test/network/traffic_route.h"
|
#include "test/network/traffic_route.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -49,7 +48,7 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
|||||||
EmulatedNetworkNode* CreateEmulatedNode(
|
EmulatedNetworkNode* CreateEmulatedNode(
|
||||||
std::unique_ptr<NetworkBehaviorInterface> network_behavior) override;
|
std::unique_ptr<NetworkBehaviorInterface> network_behavior) override;
|
||||||
|
|
||||||
SimulatedNetworkNode::Builder NodeBuilder();
|
SimulatedNetworkNode::Builder NodeBuilder() override;
|
||||||
|
|
||||||
EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) override;
|
EmulatedEndpoint* CreateEndpoint(EmulatedEndpointConfig config) override;
|
||||||
void EnableEndpoint(EmulatedEndpoint* endpoint) override;
|
void EnableEndpoint(EmulatedEndpoint* endpoint) override;
|
||||||
@ -60,7 +59,7 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
|||||||
EmulatedEndpoint* to) override;
|
EmulatedEndpoint* to) override;
|
||||||
|
|
||||||
EmulatedRoute* CreateRoute(
|
EmulatedRoute* CreateRoute(
|
||||||
const std::vector<EmulatedNetworkNode*>& via_nodes);
|
const std::vector<EmulatedNetworkNode*>& via_nodes) override;
|
||||||
|
|
||||||
void ClearRoute(EmulatedRoute* route) override;
|
void ClearRoute(EmulatedRoute* route) override;
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
|||||||
FakeTcpConfig config);
|
FakeTcpConfig config);
|
||||||
|
|
||||||
TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
|
TcpMessageRoute* CreateTcpRoute(EmulatedRoute* send_route,
|
||||||
EmulatedRoute* ret_route);
|
EmulatedRoute* ret_route) override;
|
||||||
|
|
||||||
void StopCrossTraffic(FakeTcpCrossTraffic* traffic);
|
void StopCrossTraffic(FakeTcpCrossTraffic* traffic);
|
||||||
|
|
||||||
@ -105,7 +104,7 @@ class NetworkEmulationManagerImpl : public NetworkEmulationManager {
|
|||||||
std::vector<std::unique_ptr<RandomWalkCrossTraffic>> random_cross_traffics_;
|
std::vector<std::unique_ptr<RandomWalkCrossTraffic>> random_cross_traffics_;
|
||||||
std::vector<std::unique_ptr<PulsedPeaksCrossTraffic>> pulsed_cross_traffics_;
|
std::vector<std::unique_ptr<PulsedPeaksCrossTraffic>> pulsed_cross_traffics_;
|
||||||
std::list<std::unique_ptr<FakeTcpCrossTraffic>> tcp_cross_traffics_;
|
std::list<std::unique_ptr<FakeTcpCrossTraffic>> tcp_cross_traffics_;
|
||||||
std::list<std::unique_ptr<TcpMessageRoute>> tcp_message_routes_;
|
std::list<std::unique_ptr<TcpMessageRouteImpl>> tcp_message_routes_;
|
||||||
std::vector<std::unique_ptr<EndpointsContainer>> endpoints_containers_;
|
std::vector<std::unique_ptr<EndpointsContainer>> endpoints_containers_;
|
||||||
std::vector<std::unique_ptr<EmulatedNetworkManager>> network_managers_;
|
std::vector<std::unique_ptr<EmulatedNetworkManager>> network_managers_;
|
||||||
|
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Use of this source code is governed by a BSD-style license
|
|
||||||
* that can be found in the LICENSE file in the root of the source
|
|
||||||
* tree. An additional intellectual property rights grant can be found
|
|
||||||
* in the file PATENTS. All contributing project authors may
|
|
||||||
* be found in the AUTHORS file in the root of the source tree.
|
|
||||||
*/
|
|
||||||
#ifndef TEST_NETWORK_SIMULATED_NETWORK_NODE_H_
|
|
||||||
#define TEST_NETWORK_SIMULATED_NETWORK_NODE_H_
|
|
||||||
|
|
||||||
#include "api/test/network_emulation_manager.h"
|
|
||||||
#include "call/simulated_network.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
namespace test {
|
|
||||||
// Helper struct to simplify creation of simulated network behaviors.
|
|
||||||
struct SimulatedNetworkNode {
|
|
||||||
SimulatedNetwork* simulation;
|
|
||||||
EmulatedNetworkNode* node;
|
|
||||||
class Builder {
|
|
||||||
public:
|
|
||||||
Builder();
|
|
||||||
explicit Builder(NetworkEmulationManager* net);
|
|
||||||
Builder& config(SimulatedNetwork::Config config);
|
|
||||||
Builder& delay_ms(int queue_delay_ms);
|
|
||||||
Builder& capacity_kbps(int link_capacity_kbps);
|
|
||||||
Builder& capacity_Mbps(int link_capacity_Mbps);
|
|
||||||
Builder& loss(double loss_rate);
|
|
||||||
SimulatedNetworkNode Build() const;
|
|
||||||
SimulatedNetworkNode Build(NetworkEmulationManager* net) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NetworkEmulationManager* const net_ = nullptr;
|
|
||||||
SimulatedNetwork::Config config_;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} // namespace test
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // TEST_NETWORK_SIMULATED_NETWORK_NODE_H_
|
|
Reference in New Issue
Block a user