• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "test/network/emulated_turn_server.h"
20 #include "test/network/traffic_route.h"
21 #include "test/time_controller/real_time_controller.h"
22 #include "test/time_controller/simulated_time_controller.h"
23 
24 namespace webrtc {
25 namespace test {
26 namespace {
27 
28 // uint32_t representation of 192.168.0.0 address
29 constexpr uint32_t kMinIPv4Address = 0xC0A80000;
30 // uint32_t representation of 192.168.255.255 address
31 constexpr uint32_t kMaxIPv4Address = 0xC0A8FFFF;
32 
CreateTimeController(TimeMode mode)33 std::unique_ptr<TimeController> CreateTimeController(TimeMode mode) {
34   switch (mode) {
35     case TimeMode::kRealTime:
36       return std::make_unique<RealTimeController>();
37     case TimeMode::kSimulated:
38       // Using an offset of 100000 to get nice fixed width and readable
39       // timestamps in typical test scenarios.
40       const Timestamp kSimulatedStartTime = Timestamp::Seconds(100000);
41       return std::make_unique<GlobalSimulatedTimeController>(
42           kSimulatedStartTime);
43   }
44 }
45 }  // namespace
46 
NetworkEmulationManagerImpl(TimeMode mode,EmulatedNetworkStatsGatheringMode stats_gathering_mode)47 NetworkEmulationManagerImpl::NetworkEmulationManagerImpl(
48     TimeMode mode,
49     EmulatedNetworkStatsGatheringMode stats_gathering_mode)
50     : time_mode_(mode),
51       stats_gathering_mode_(stats_gathering_mode),
52       time_controller_(CreateTimeController(mode)),
53       clock_(time_controller_->GetClock()),
54       next_node_id_(1),
55       next_ip4_address_(kMinIPv4Address),
56       task_queue_(time_controller_->GetTaskQueueFactory()->CreateTaskQueue(
57           "NetworkEmulation",
58           TaskQueueFactory::Priority::NORMAL)) {}
59 
60 // TODO(srte): Ensure that any pending task that must be run for consistency
61 // (such as stats collection tasks) are not cancelled when the task queue is
62 // destroyed.
~NetworkEmulationManagerImpl()63 NetworkEmulationManagerImpl::~NetworkEmulationManagerImpl() {
64   for (auto& turn_server : turn_servers_) {
65     turn_server->Stop();
66   }
67 }
68 
CreateEmulatedNode(BuiltInNetworkBehaviorConfig config,uint64_t random_seed)69 EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
70     BuiltInNetworkBehaviorConfig config,
71     uint64_t random_seed) {
72   return CreateEmulatedNode(
73       std::make_unique<SimulatedNetwork>(config, random_seed));
74 }
75 
CreateEmulatedNode(std::unique_ptr<NetworkBehaviorInterface> network_behavior)76 EmulatedNetworkNode* NetworkEmulationManagerImpl::CreateEmulatedNode(
77     std::unique_ptr<NetworkBehaviorInterface> network_behavior) {
78   auto node = std::make_unique<EmulatedNetworkNode>(
79       clock_, &task_queue_, std::move(network_behavior), stats_gathering_mode_);
80   EmulatedNetworkNode* out = node.get();
81   task_queue_.PostTask([this, node = std::move(node)]() mutable {
82     network_nodes_.push_back(std::move(node));
83   });
84   return out;
85 }
86 
87 NetworkEmulationManager::SimulatedNetworkNode::Builder
NodeBuilder()88 NetworkEmulationManagerImpl::NodeBuilder() {
89   return SimulatedNetworkNode::Builder(this);
90 }
91 
CreateEndpoint(EmulatedEndpointConfig config)92 EmulatedEndpointImpl* NetworkEmulationManagerImpl::CreateEndpoint(
93     EmulatedEndpointConfig config) {
94   absl::optional<rtc::IPAddress> ip = config.ip;
95   if (!ip) {
96     switch (config.generated_ip_family) {
97       case EmulatedEndpointConfig::IpAddressFamily::kIpv4:
98         ip = GetNextIPv4Address();
99         RTC_CHECK(ip) << "All auto generated IPv4 addresses exhausted";
100         break;
101       case EmulatedEndpointConfig::IpAddressFamily::kIpv6:
102         ip = GetNextIPv4Address();
103         RTC_CHECK(ip) << "All auto generated IPv6 addresses exhausted";
104         ip = ip->AsIPv6Address();
105         break;
106     }
107   }
108 
109   bool res = used_ip_addresses_.insert(*ip).second;
110   RTC_CHECK(res) << "IP=" << ip->ToString() << " already in use";
111   auto node = std::make_unique<EmulatedEndpointImpl>(
112       EmulatedEndpointImpl::Options(next_node_id_++, *ip, config,
113                                     stats_gathering_mode_),
114       config.start_as_enabled, &task_queue_, clock_);
115   EmulatedEndpointImpl* out = node.get();
116   endpoints_.push_back(std::move(node));
117   return out;
118 }
119 
EnableEndpoint(EmulatedEndpoint * endpoint)120 void NetworkEmulationManagerImpl::EnableEndpoint(EmulatedEndpoint* endpoint) {
121   EmulatedNetworkManager* network_manager =
122       endpoint_to_network_manager_[endpoint];
123   RTC_CHECK(network_manager);
124   network_manager->EnableEndpoint(static_cast<EmulatedEndpointImpl*>(endpoint));
125 }
126 
DisableEndpoint(EmulatedEndpoint * endpoint)127 void NetworkEmulationManagerImpl::DisableEndpoint(EmulatedEndpoint* endpoint) {
128   EmulatedNetworkManager* network_manager =
129       endpoint_to_network_manager_[endpoint];
130   RTC_CHECK(network_manager);
131   network_manager->DisableEndpoint(
132       static_cast<EmulatedEndpointImpl*>(endpoint));
133 }
134 
CreateRoute(EmulatedEndpoint * from,const std::vector<EmulatedNetworkNode * > & via_nodes,EmulatedEndpoint * to)135 EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
136     EmulatedEndpoint* from,
137     const std::vector<EmulatedNetworkNode*>& via_nodes,
138     EmulatedEndpoint* to) {
139   // Because endpoint has no send node by default at least one should be
140   // provided here.
141   RTC_CHECK(!via_nodes.empty());
142 
143   static_cast<EmulatedEndpointImpl*>(from)->router()->SetReceiver(
144       to->GetPeerLocalAddress(), via_nodes[0]);
145   EmulatedNetworkNode* cur_node = via_nodes[0];
146   for (size_t i = 1; i < via_nodes.size(); ++i) {
147     cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), via_nodes[i]);
148     cur_node = via_nodes[i];
149   }
150   cur_node->router()->SetReceiver(to->GetPeerLocalAddress(), to);
151 
152   std::unique_ptr<EmulatedRoute> route = std::make_unique<EmulatedRoute>(
153       static_cast<EmulatedEndpointImpl*>(from), std::move(via_nodes),
154       static_cast<EmulatedEndpointImpl*>(to), /*is_default=*/false);
155   EmulatedRoute* out = route.get();
156   routes_.push_back(std::move(route));
157   return out;
158 }
159 
CreateRoute(const std::vector<EmulatedNetworkNode * > & via_nodes)160 EmulatedRoute* NetworkEmulationManagerImpl::CreateRoute(
161     const std::vector<EmulatedNetworkNode*>& via_nodes) {
162   EmulatedEndpoint* from = CreateEndpoint(EmulatedEndpointConfig());
163   EmulatedEndpoint* to = CreateEndpoint(EmulatedEndpointConfig());
164   return CreateRoute(from, via_nodes, to);
165 }
166 
CreateDefaultRoute(EmulatedEndpoint * from,const std::vector<EmulatedNetworkNode * > & via_nodes,EmulatedEndpoint * to)167 EmulatedRoute* NetworkEmulationManagerImpl::CreateDefaultRoute(
168     EmulatedEndpoint* from,
169     const std::vector<EmulatedNetworkNode*>& via_nodes,
170     EmulatedEndpoint* to) {
171   // Because endpoint has no send node by default at least one should be
172   // provided here.
173   RTC_CHECK(!via_nodes.empty());
174 
175   static_cast<EmulatedEndpointImpl*>(from)->router()->SetDefaultReceiver(
176       via_nodes[0]);
177   EmulatedNetworkNode* cur_node = via_nodes[0];
178   for (size_t i = 1; i < via_nodes.size(); ++i) {
179     cur_node->router()->SetDefaultReceiver(via_nodes[i]);
180     cur_node = via_nodes[i];
181   }
182   cur_node->router()->SetDefaultReceiver(to);
183 
184   std::unique_ptr<EmulatedRoute> route = std::make_unique<EmulatedRoute>(
185       static_cast<EmulatedEndpointImpl*>(from), std::move(via_nodes),
186       static_cast<EmulatedEndpointImpl*>(to), /*is_default=*/true);
187   EmulatedRoute* out = route.get();
188   routes_.push_back(std::move(route));
189   return out;
190 }
191 
ClearRoute(EmulatedRoute * route)192 void NetworkEmulationManagerImpl::ClearRoute(EmulatedRoute* route) {
193   RTC_CHECK(route->active) << "Route already cleared";
194   task_queue_.SendTask([route]() {
195     // Remove receiver from intermediate nodes.
196     for (auto* node : route->via_nodes) {
197       if (route->is_default) {
198         node->router()->RemoveDefaultReceiver();
199       } else {
200         node->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
201       }
202     }
203     // Remove destination endpoint from source endpoint's router.
204     if (route->is_default) {
205       route->from->router()->RemoveDefaultReceiver();
206     } else {
207       route->from->router()->RemoveReceiver(route->to->GetPeerLocalAddress());
208     }
209 
210     route->active = false;
211   });
212 }
213 
CreateTcpRoute(EmulatedRoute * send_route,EmulatedRoute * ret_route)214 TcpMessageRoute* NetworkEmulationManagerImpl::CreateTcpRoute(
215     EmulatedRoute* send_route,
216     EmulatedRoute* ret_route) {
217   auto tcp_route = std::make_unique<TcpMessageRouteImpl>(
218       clock_, task_queue_.Get(), send_route, ret_route);
219   auto* route_ptr = tcp_route.get();
220   task_queue_.PostTask([this, tcp_route = std::move(tcp_route)]() mutable {
221     tcp_message_routes_.push_back(std::move(tcp_route));
222   });
223   return route_ptr;
224 }
225 
CreateCrossTrafficRoute(const std::vector<EmulatedNetworkNode * > & via_nodes)226 CrossTrafficRoute* NetworkEmulationManagerImpl::CreateCrossTrafficRoute(
227     const std::vector<EmulatedNetworkNode*>& via_nodes) {
228   RTC_CHECK(!via_nodes.empty());
229   EmulatedEndpointImpl* endpoint = CreateEndpoint(EmulatedEndpointConfig());
230 
231   // Setup a route via specified nodes.
232   EmulatedNetworkNode* cur_node = via_nodes[0];
233   for (size_t i = 1; i < via_nodes.size(); ++i) {
234     cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(),
235                                     via_nodes[i]);
236     cur_node = via_nodes[i];
237   }
238   cur_node->router()->SetReceiver(endpoint->GetPeerLocalAddress(), endpoint);
239 
240   std::unique_ptr<CrossTrafficRoute> traffic_route =
241       std::make_unique<CrossTrafficRouteImpl>(clock_, via_nodes[0], endpoint);
242   CrossTrafficRoute* out = traffic_route.get();
243   traffic_routes_.push_back(std::move(traffic_route));
244   return out;
245 }
246 
StartCrossTraffic(std::unique_ptr<CrossTrafficGenerator> generator)247 CrossTrafficGenerator* NetworkEmulationManagerImpl::StartCrossTraffic(
248     std::unique_ptr<CrossTrafficGenerator> generator) {
249   CrossTrafficGenerator* out = generator.get();
250   task_queue_.PostTask([this, generator = std::move(generator)]() mutable {
251     auto* generator_ptr = generator.get();
252 
253     auto repeating_task_handle =
254         RepeatingTaskHandle::Start(task_queue_.Get(), [this, generator_ptr] {
255           generator_ptr->Process(Now());
256           return generator_ptr->GetProcessInterval();
257         });
258 
259     cross_traffics_.push_back(CrossTrafficSource(
260         std::move(generator), std::move(repeating_task_handle)));
261   });
262   return out;
263 }
264 
StopCrossTraffic(CrossTrafficGenerator * generator)265 void NetworkEmulationManagerImpl::StopCrossTraffic(
266     CrossTrafficGenerator* generator) {
267   task_queue_.PostTask([=]() {
268     auto it = std::find_if(cross_traffics_.begin(), cross_traffics_.end(),
269                            [=](const CrossTrafficSource& el) {
270                              return el.first.get() == generator;
271                            });
272     it->second.Stop();
273     cross_traffics_.erase(it);
274   });
275 }
276 
277 EmulatedNetworkManagerInterface*
CreateEmulatedNetworkManagerInterface(const std::vector<EmulatedEndpoint * > & endpoints)278 NetworkEmulationManagerImpl::CreateEmulatedNetworkManagerInterface(
279     const std::vector<EmulatedEndpoint*>& endpoints) {
280   std::vector<EmulatedEndpointImpl*> endpoint_impls;
281   endpoint_impls.reserve(endpoints.size());
282   for (EmulatedEndpoint* endpoint : endpoints) {
283     endpoint_impls.push_back(static_cast<EmulatedEndpointImpl*>(endpoint));
284   }
285   auto endpoints_container = std::make_unique<EndpointsContainer>(
286       endpoint_impls, stats_gathering_mode_);
287   auto network_manager = std::make_unique<EmulatedNetworkManager>(
288       time_controller_.get(), &task_queue_, endpoints_container.get());
289   for (auto* endpoint : endpoints) {
290     // Associate endpoint with network manager.
291     bool insertion_result =
292         endpoint_to_network_manager_.insert({endpoint, network_manager.get()})
293             .second;
294     RTC_CHECK(insertion_result)
295         << "Endpoint ip=" << endpoint->GetPeerLocalAddress().ToString()
296         << " is already used for another network";
297   }
298 
299   EmulatedNetworkManagerInterface* out = network_manager.get();
300 
301   endpoints_containers_.push_back(std::move(endpoints_container));
302   network_managers_.push_back(std::move(network_manager));
303   return out;
304 }
305 
GetStats(rtc::ArrayView<EmulatedEndpoint * const> endpoints,std::function<void (EmulatedNetworkStats)> stats_callback)306 void NetworkEmulationManagerImpl::GetStats(
307     rtc::ArrayView<EmulatedEndpoint* const> endpoints,
308     std::function<void(EmulatedNetworkStats)> stats_callback) {
309   task_queue_.PostTask([endpoints, stats_callback,
310                         stats_gathering_mode = stats_gathering_mode_]() {
311     EmulatedNetworkStatsBuilder stats_builder(stats_gathering_mode);
312     for (auto* endpoint : endpoints) {
313       // It's safe to cast here because EmulatedEndpointImpl can be the only
314       // implementation of EmulatedEndpoint, because only it has access to
315       // EmulatedEndpoint constructor.
316       auto endpoint_impl = static_cast<EmulatedEndpointImpl*>(endpoint);
317       stats_builder.AddEmulatedNetworkStats(endpoint_impl->stats());
318     }
319     stats_callback(stats_builder.Build());
320   });
321 }
322 
GetStats(rtc::ArrayView<EmulatedNetworkNode * const> nodes,std::function<void (EmulatedNetworkNodeStats)> stats_callback)323 void NetworkEmulationManagerImpl::GetStats(
324     rtc::ArrayView<EmulatedNetworkNode* const> nodes,
325     std::function<void(EmulatedNetworkNodeStats)> stats_callback) {
326   task_queue_.PostTask(
327       [nodes, stats_callback, stats_gathering_mode = stats_gathering_mode_]() {
328         EmulatedNetworkNodeStatsBuilder stats_builder(stats_gathering_mode);
329         for (auto* node : nodes) {
330           stats_builder.AddEmulatedNetworkNodeStats(node->stats());
331         }
332         stats_callback(stats_builder.Build());
333       });
334 }
335 
336 absl::optional<rtc::IPAddress>
GetNextIPv4Address()337 NetworkEmulationManagerImpl::GetNextIPv4Address() {
338   uint32_t addresses_count = kMaxIPv4Address - kMinIPv4Address;
339   for (uint32_t i = 0; i < addresses_count; i++) {
340     rtc::IPAddress ip(next_ip4_address_);
341     if (next_ip4_address_ == kMaxIPv4Address) {
342       next_ip4_address_ = kMinIPv4Address;
343     } else {
344       next_ip4_address_++;
345     }
346     if (used_ip_addresses_.find(ip) == used_ip_addresses_.end()) {
347       return ip;
348     }
349   }
350   return absl::nullopt;
351 }
352 
Now() const353 Timestamp NetworkEmulationManagerImpl::Now() const {
354   return clock_->CurrentTime();
355 }
356 
CreateTURNServer(EmulatedTURNServerConfig config)357 EmulatedTURNServerInterface* NetworkEmulationManagerImpl::CreateTURNServer(
358     EmulatedTURNServerConfig config) {
359   auto* client = CreateEndpoint(config.client_config);
360   auto* peer = CreateEndpoint(config.client_config);
361   char buf[128];
362   rtc::SimpleStringBuilder str(buf);
363   str.AppendFormat("turn_server_%u",
364                    static_cast<unsigned>(turn_servers_.size()));
365   auto turn = std::make_unique<EmulatedTURNServer>(
366       time_controller_->CreateThread(str.str()), client, peer);
367   auto out = turn.get();
368   turn_servers_.push_back(std::move(turn));
369   return out;
370 }
371 
372 }  // namespace test
373 }  // namespace webrtc
374