1 /*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "test/network/network_emulation_manager.h"
12
13 #include <algorithm>
14 #include <memory>
15
16 #include "api/units/time_delta.h"
17 #include "api/units/timestamp.h"
18 #include "call/simulated_network.h"
19 #include "rtc_base/fake_network.h"
20 #include "test/time_controller/real_time_controller.h"
21 #include "test/time_controller/simulated_time_controller.h"
22
23 namespace webrtc {
24 namespace test {
25 namespace {
26
27 // uint32_t representation of 192.168.0.0 address
28 constexpr uint32_t kMinIPv4Address = 0xC0A80000;
29 // uint32_t representation of 192.168.255.255 address
30 constexpr uint32_t kMaxIPv4Address = 0xC0A8FFFF;
31
CreateTimeController(TimeMode mode)32 std::unique_ptr<TimeController> CreateTimeController(TimeMode mode) {
33 switch (mode) {
34 case TimeMode::kRealTime:
35 return std::make_unique<RealTimeController>();
36 case TimeMode::kSimulated:
37 // Using an offset of 100000 to get nice fixed width and readable
38 // timestamps in typical test scenarios.
39 const Timestamp kSimulatedStartTime = Timestamp::Seconds(100000);
40 return std::make_unique<GlobalSimulatedTimeController>(
41 kSimulatedStartTime);
42 }
43 }
44 } // namespace
45
NetworkEmulationManagerImpl(TimeMode mode)46 NetworkEmulationManagerImpl::NetworkEmulationManagerImpl(TimeMode mode)
47 : time_controller_(CreateTimeController(mode)),
48 clock_(time_controller_->GetClock()),
49 next_node_id_(1),
50 next_ip4_address_(kMinIPv4Address),
51 task_queue_(time_controller_->GetTaskQueueFactory()->CreateTaskQueue(
52 "NetworkEmulation",
53 TaskQueueFactory::Priority::NORMAL)) {}
54
55 // TODO(srte): Ensure that any pending task that must be run for consistency
56 // (such as stats collection tasks) are not cancelled when the task queue is
57 // destroyed.
58 NetworkEmulationManagerImpl::~NetworkEmulationManagerImpl() = default;
59
CreateEmulatedNode(BuiltInNetworkBehaviorConfig config)60 EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
61 BuiltInNetworkBehaviorConfig config) {
62 return CreateEmulatedNode(std::make_unique<SimulatedNetwork>(config));
63 }
64
CreateEmulatedNode(std::unique_ptr<NetworkBehaviorInterface> network_behavior)65 EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
66 std::unique_ptr<NetworkBehaviorInterface> network_behavior) {
67 auto node = std::make_unique<EmulatedNetworkNode>(
68 clock_, &task_queue_, std::move(network_behavior));
69 EmulatedNetworkNode* out = node.get();
70 task_queue_.PostTask([this, node = std::move(node)]() mutable {
71 network_nodes_.push_back(std::move(node));
72 });
73 return out;
74 }
75
76 NetworkEmulationManager::SimulatedNetworkNode::Builder
NodeBuilder()77 NetworkEmulationManagerImpl::NodeBuilder() {
78 return SimulatedNetworkNode::Builder(this);
79 }
80
CreateEndpoint(EmulatedEndpointConfig config)81 EmulatedEndpoint* NetworkEmulationManagerImpl::CreateEndpoint(
82 EmulatedEndpointConfig config) {
83 absl::optional<rtc::IPAddress> ip = config.ip;
84 if (!ip) {
85 switch (config.generated_ip_family) {
86 case EmulatedEndpointConfig::IpAddressFamily::kIpv4:
87 ip = GetNextIPv4Address();
88 RTC_CHECK(ip) << "All auto generated IPv4 addresses exhausted";
89 break;
90 case EmulatedEndpointConfig::IpAddressFamily::kIpv6:
91 ip = GetNextIPv4Address();
92 RTC_CHECK(ip) << "All auto generated IPv6 addresses exhausted";
93 ip = ip->AsIPv6Address();
94 break;
95 }
96 }
97
98 bool res = used_ip_addresses_.insert(*ip).second;
99 RTC_CHECK(res) << "IP=" << ip->ToString() << " already in use";
100 auto node = std::make_unique<EmulatedEndpointImpl>(
101 next_node_id_++, *ip, config.start_as_enabled, config.type, &task_queue_,
102 clock_);
103 EmulatedEndpoint* out = node.get();
104 endpoints_.push_back(std::move(node));
105 return out;
106 }
107
EnableEndpoint(EmulatedEndpoint * endpoint)108 void NetworkEmulationManagerImpl::EnableEndpoint(EmulatedEndpoint* endpoint) {
109 EmulatedNetworkManager* network_manager =
110 endpoint_to_network_manager_[endpoint];
111 RTC_CHECK(network_manager);
112 network_manager->EnableEndpoint(static_cast<EmulatedEndpointImpl*>(endpoint));
113 }
114
DisableEndpoint(EmulatedEndpoint * endpoint)115 void NetworkEmulationManagerImpl::DisableEndpoint(EmulatedEndpoint* endpoint) {
116 EmulatedNetworkManager* network_manager =
117 endpoint_to_network_manager_[endpoint];
118 RTC_CHECK(network_manager);
119 network_manager->DisableEndpoint(
120 static_cast<EmulatedEndpointImpl*>(endpoint));
121 }
122
CreateRoute(EmulatedEndpoint * from,const std::vector<EmulatedNetworkNode * > & via_nodes,EmulatedEndpoint * to)123 EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
124 EmulatedEndpoint* from,
125 const std::vector<EmulatedNetworkNode*>& via_nodes,
126 EmulatedEndpoint* to) {
127 // Because endpoint has no send node by default at least one should be
128 // provided here.
129 RTC_CHECK(!via_nodes.empty());
130
131 static_cast<EmulatedEndpointImpl*>(from)->router()->SetReceiver(
132 to->GetPeerLocalAddress(), via_nodes[0]);
133 EmulatedNetworkNode* cur_node = via_nodes[0];
134 for (size_t i = 1; i < via_nodes.size(); ++i) {
135 cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), via_nodes[i]);
136 cur_node = via_nodes[i];
137 }
138 cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), to);
139
140 std::unique_ptr<EmulatedRoute> route = std::make_unique<EmulatedRoute>(
141 static_cast<EmulatedEndpointImpl*>(from), std::move(via_nodes),
142 static_cast<EmulatedEndpointImpl*>(to));
143 EmulatedRoute* out = route.get();
144 routes_.push_back(std::move(route));
145 return out;
146 }
147
CreateRoute(const std::vector<EmulatedNetworkNode * > & via_nodes)148 EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
149 const std::vector<EmulatedNetworkNode*>& via_nodes) {
150 EmulatedEndpoint* from = CreateEndpoint(EmulatedEndpointConfig());
151 EmulatedEndpoint* to = CreateEndpoint(EmulatedEndpointConfig());
152 return CreateRoute(from, via_nodes, to);
153 }
154
ClearRoute(EmulatedRoute * route)155 void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) {
156 RTC_CHECK(route->active) << "Route already cleared";
157 task_queue_.SendTask(
158 [route]() {
159 // Remove receiver from intermediate nodes.
160 for (auto* node : route->via_nodes) {
161 node->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
162 }
163 // Remove destination endpoint from source endpoint's router.
164 route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
165
166 route->active = false;
167 },
168 RTC_FROM_HERE);
169 }
170
CreateTrafficRoute(const std::vector<EmulatedNetworkNode * > & via_nodes)171 TrafficRoute* NetworkEmulationManagerImpl::CreateTrafficRoute(
172 const std::vector<EmulatedNetworkNode*>& via_nodes) {
173 RTC_CHECK(!via_nodes.empty());
174 EmulatedEndpoint* endpoint = CreateEndpoint(EmulatedEndpointConfig());
175
176 // Setup a route via specified nodes.
177 EmulatedNetworkNode* cur_node = via_nodes[0];
178 for (size_t i = 1; i < via_nodes.size(); ++i) {
179 cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(),
180 via_nodes[i]);
181 cur_node = via_nodes[i];
182 }
183 cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(), endpoint);
184
185 std::unique_ptr<TrafficRoute> traffic_route =
186 std::make_unique<TrafficRoute>(clock_, via_nodes[0], endpoint);
187 TrafficRoute* out = traffic_route.get();
188 traffic_routes_.push_back(std::move(traffic_route));
189 return out;
190 }
191
192 RandomWalkCrossTraffic*
CreateRandomWalkCrossTraffic(TrafficRoute * traffic_route,RandomWalkConfig config)193 NetworkEmulationManagerImpl::CreateRandomWalkCrossTraffic(
194 TrafficRoute* traffic_route,
195 RandomWalkConfig config) {
196 auto traffic =
197 std::make_unique<RandomWalkCrossTraffic>(config, traffic_route);
198 RandomWalkCrossTraffic* out = traffic.get();
199
200 task_queue_.PostTask(
201 [this, config, traffic = std::move(traffic)]() mutable {
202 auto* traffic_ptr = traffic.get();
203 random_cross_traffics_.push_back(std::move(traffic));
204 RepeatingTaskHandle::Start(task_queue_.Get(),
205 [this, config, traffic_ptr] {
206 traffic_ptr->Process(Now());
207 return config.min_packet_interval;
208 });
209 });
210 return out;
211 }
212
213 PulsedPeaksCrossTraffic*
CreatePulsedPeaksCrossTraffic(TrafficRoute * traffic_route,PulsedPeaksConfig config)214 NetworkEmulationManagerImpl::CreatePulsedPeaksCrossTraffic(
215 TrafficRoute* traffic_route,
216 PulsedPeaksConfig config) {
217 auto traffic =
218 std::make_unique<PulsedPeaksCrossTraffic>(config, traffic_route);
219 PulsedPeaksCrossTraffic* out = traffic.get();
220 task_queue_.PostTask(
221 [this, config, traffic = std::move(traffic)]() mutable {
222 auto* traffic_ptr = traffic.get();
223 pulsed_cross_traffics_.push_back(std::move(traffic));
224 RepeatingTaskHandle::Start(task_queue_.Get(),
225 [this, config, traffic_ptr] {
226 traffic_ptr->Process(Now());
227 return config.min_packet_interval;
228 });
229 });
230 return out;
231 }
232
StartFakeTcpCrossTraffic(std::vector<EmulatedNetworkNode * > send_link,std::vector<EmulatedNetworkNode * > ret_link,FakeTcpConfig config)233 FakeTcpCrossTraffic* NetworkEmulationManagerImpl::StartFakeTcpCrossTraffic(
234 std::vector<EmulatedNetworkNode*> send_link,
235 std::vector<EmulatedNetworkNode*> ret_link,
236 FakeTcpConfig config) {
237 auto traffic = std::make_unique<FakeTcpCrossTraffic>(
238 clock_, config, CreateRoute(send_link), CreateRoute(ret_link));
239 auto* traffic_ptr = traffic.get();
240 task_queue_.PostTask([this, traffic = std::move(traffic)]() mutable {
241 traffic->Start(task_queue_.Get());
242 tcp_cross_traffics_.push_back(std::move(traffic));
243 });
244 return traffic_ptr;
245 }
246
CreateTcpRoute(EmulatedRoute * send_route,EmulatedRoute * ret_route)247 TcpMessageRoute* NetworkEmulationManagerImpl::CreateTcpRoute(
248 EmulatedRoute* send_route,
249 EmulatedRoute* ret_route) {
250 auto tcp_route = std::make_unique<TcpMessageRouteImpl>(
251 clock_, task_queue_.Get(), send_route, ret_route);
252 auto* route_ptr = tcp_route.get();
253 task_queue_.PostTask([this, tcp_route = std::move(tcp_route)]() mutable {
254 tcp_message_routes_.push_back(std::move(tcp_route));
255 });
256 return route_ptr;
257 }
258
StopCrossTraffic(FakeTcpCrossTraffic * traffic)259 void NetworkEmulationManagerImpl::StopCrossTraffic(
260 FakeTcpCrossTraffic* traffic) {
261 task_queue_.PostTask([=]() {
262 traffic->Stop();
263 tcp_cross_traffics_.remove_if(
264 [=](const std::unique_ptr<FakeTcpCrossTraffic>& ptr) {
265 return ptr.get() == traffic;
266 });
267 });
268 }
269
270 EmulatedNetworkManagerInterface*
CreateEmulatedNetworkManagerInterface(const std::vector<EmulatedEndpoint * > & endpoints)271 NetworkEmulationManagerImpl::CreateEmulatedNetworkManagerInterface(
272 const std::vector<EmulatedEndpoint*>& endpoints) {
273 std::vector<EmulatedEndpointImpl*> endpoint_impls;
274 for (EmulatedEndpoint* endpoint : endpoints) {
275 endpoint_impls.push_back(static_cast<EmulatedEndpointImpl*>(endpoint));
276 }
277 auto endpoints_container =
278 std::make_unique<EndpointsContainer>(endpoint_impls);
279 auto network_manager = std::make_unique<EmulatedNetworkManager>(
280 time_controller_.get(), &task_queue_, endpoints_container.get());
281 for (auto* endpoint : endpoints) {
282 // Associate endpoint with network manager.
283 bool insertion_result =
284 endpoint_to_network_manager_.insert({endpoint, network_manager.get()})
285 .second;
286 RTC_CHECK(insertion_result)
287 << "Endpoint ip=" << endpoint->GetPeerLocalAddress().ToString()
288 << " is already used for another network";
289 }
290
291 EmulatedNetworkManagerInterface* out = network_manager.get();
292
293 endpoints_containers_.push_back(std::move(endpoints_container));
294 network_managers_.push_back(std::move(network_manager));
295 return out;
296 }
297
298 absl::optional<rtc::IPAddress>
GetNextIPv4Address()299 NetworkEmulationManagerImpl::GetNextIPv4Address() {
300 uint32_t addresses_count = kMaxIPv4Address - kMinIPv4Address;
301 for (uint32_t i = 0; i < addresses_count; i++) {
302 rtc::IPAddress ip(next_ip4_address_);
303 if (next_ip4_address_ == kMaxIPv4Address) {
304 next_ip4_address_ = kMinIPv4Address;
305 } else {
306 next_ip4_address_++;
307 }
308 if (used_ip_addresses_.find(ip) == used_ip_addresses_.end()) {
309 return ip;
310 }
311 }
312 return absl::nullopt;
313 }
314
Now() const315 Timestamp NetworkEmulationManagerImpl::Now() const {
316 return clock_->CurrentTime();
317 }
318
319 } // namespace test
320 } // namespace webrtc
321