• 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 "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