xref: /aosp_15_r20/external/webrtc/test/network/network_emulation.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2018 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 #ifndef TEST_NETWORK_NETWORK_EMULATION_H_
12 #define TEST_NETWORK_NETWORK_EMULATION_H_
13 
14 #include <cstdint>
15 #include <deque>
16 #include <map>
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include "absl/types/optional.h"
23 #include "api/array_view.h"
24 #include "api/numerics/samples_stats_counter.h"
25 #include "api/sequence_checker.h"
26 #include "api/test/network_emulation/network_emulation_interfaces.h"
27 #include "api/test/network_emulation_manager.h"
28 #include "api/test/simulated_network.h"
29 #include "api/units/time_delta.h"
30 #include "api/units/timestamp.h"
31 #include "rtc_base/copy_on_write_buffer.h"
32 #include "rtc_base/network.h"
33 #include "rtc_base/network_constants.h"
34 #include "rtc_base/socket_address.h"
35 #include "rtc_base/synchronization/mutex.h"
36 #include "rtc_base/system/no_unique_address.h"
37 #include "rtc_base/task_queue_for_test.h"
38 #include "rtc_base/task_utils/repeating_task.h"
39 #include "rtc_base/thread_annotations.h"
40 #include "system_wrappers/include/clock.h"
41 
42 namespace webrtc {
43 
44 // All methods of EmulatedNetworkOutgoingStatsBuilder have to be used on a
45 // single thread. It may be created on another thread.
46 class EmulatedNetworkOutgoingStatsBuilder {
47  public:
48   explicit EmulatedNetworkOutgoingStatsBuilder(
49       EmulatedNetworkStatsGatheringMode stats_gathering_mode);
50 
51   void OnPacketSent(Timestamp sent_time, DataSize packet_size);
52 
53   void AddOutgoingStats(const EmulatedNetworkOutgoingStats& stats);
54 
55   EmulatedNetworkOutgoingStats Build() const;
56 
57  private:
58   const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
59 
60   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
61   EmulatedNetworkOutgoingStats stats_ RTC_GUARDED_BY(sequence_checker_);
62 };
63 
64 // All methods of EmulatedNetworkIncomingStatsBuilder have to be used on a
65 // single thread. It may be created on another thread.
66 class EmulatedNetworkIncomingStatsBuilder {
67  public:
68   explicit EmulatedNetworkIncomingStatsBuilder(
69       EmulatedNetworkStatsGatheringMode stats_gathering_mode);
70 
71   void OnPacketDropped(DataSize packet_size);
72 
73   void OnPacketReceived(Timestamp received_time, DataSize packet_size);
74 
75   // Adds stats collected from another endpoints to the builder.
76   void AddIncomingStats(const EmulatedNetworkIncomingStats& stats);
77 
78   EmulatedNetworkIncomingStats Build() const;
79 
80  private:
81   const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
82 
83   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
84   EmulatedNetworkIncomingStats stats_ RTC_GUARDED_BY(sequence_checker_);
85 };
86 
87 // All methods of EmulatedNetworkStatsBuilder have to be used on a single
88 // thread. It may be created on another thread.
89 class EmulatedNetworkStatsBuilder {
90  public:
91   explicit EmulatedNetworkStatsBuilder(
92       EmulatedNetworkStatsGatheringMode stats_gathering_mode);
93   explicit EmulatedNetworkStatsBuilder(
94       rtc::IPAddress local_ip,
95       EmulatedNetworkStatsGatheringMode stats_gathering_mode);
96 
97   void OnPacketSent(Timestamp queued_time,
98                     Timestamp sent_time,
99                     rtc::IPAddress destination_ip,
100                     DataSize packet_size);
101 
102   void OnPacketDropped(rtc::IPAddress source_ip, DataSize packet_size);
103 
104   void OnPacketReceived(Timestamp received_time,
105                         rtc::IPAddress source_ip,
106                         DataSize packet_size);
107 
108   void AddEmulatedNetworkStats(const EmulatedNetworkStats& stats);
109 
110   EmulatedNetworkStats Build() const;
111 
112  private:
113   const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
114 
115   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
116   std::vector<rtc::IPAddress> local_addresses_
117       RTC_GUARDED_BY(sequence_checker_);
118   SamplesStatsCounter sent_packets_queue_wait_time_us_;
119   std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkOutgoingStatsBuilder>>
120       outgoing_stats_per_destination_ RTC_GUARDED_BY(sequence_checker_);
121   std::map<rtc::IPAddress, std::unique_ptr<EmulatedNetworkIncomingStatsBuilder>>
122       incoming_stats_per_source_ RTC_GUARDED_BY(sequence_checker_);
123 };
124 
125 // All methods of EmulatedNetworkNodeStatsBuilder have to be used on a
126 // single thread. It may be created on another thread.
127 class EmulatedNetworkNodeStatsBuilder {
128  public:
129   explicit EmulatedNetworkNodeStatsBuilder(
130       EmulatedNetworkStatsGatheringMode stats_gathering_mode);
131 
132   void AddPacketTransportTime(TimeDelta time, size_t packet_size);
133 
134   void AddEmulatedNetworkNodeStats(const EmulatedNetworkNodeStats& stats);
135 
136   EmulatedNetworkNodeStats Build() const;
137 
138  private:
139   const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
140 
141   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
142   EmulatedNetworkNodeStats stats_ RTC_GUARDED_BY(sequence_checker_);
143 };
144 
145 class LinkEmulation : public EmulatedNetworkReceiverInterface {
146  public:
LinkEmulation(Clock * clock,rtc::TaskQueue * task_queue,std::unique_ptr<NetworkBehaviorInterface> network_behavior,EmulatedNetworkReceiverInterface * receiver,EmulatedNetworkStatsGatheringMode stats_gathering_mode)147   LinkEmulation(Clock* clock,
148                 rtc::TaskQueue* task_queue,
149                 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
150                 EmulatedNetworkReceiverInterface* receiver,
151                 EmulatedNetworkStatsGatheringMode stats_gathering_mode)
152       : clock_(clock),
153         task_queue_(task_queue),
154         network_behavior_(std::move(network_behavior)),
155         receiver_(receiver),
156         stats_builder_(stats_gathering_mode) {}
157   void OnPacketReceived(EmulatedIpPacket packet) override;
158 
159   EmulatedNetworkNodeStats stats() const;
160 
161  private:
162   struct StoredPacket {
163     uint64_t id;
164     Timestamp sent_time;
165     EmulatedIpPacket packet;
166     bool removed;
167   };
168   void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
169 
170   Clock* const clock_;
171   rtc::TaskQueue* const task_queue_;
172   const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
173       RTC_GUARDED_BY(task_queue_);
174   EmulatedNetworkReceiverInterface* const receiver_;
175 
176   RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
177   std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
178   uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
179 
180   EmulatedNetworkNodeStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
181 };
182 
183 // Represents a component responsible for routing packets based on their IP
184 // address. All possible routes have to be set explicitly before packet for
185 // desired destination will be seen for the first time. If route is unknown
186 // the packet will be silently dropped.
187 class NetworkRouterNode : public EmulatedNetworkReceiverInterface {
188  public:
189   explicit NetworkRouterNode(rtc::TaskQueue* task_queue);
190 
191   void OnPacketReceived(EmulatedIpPacket packet) override;
192   void SetReceiver(const rtc::IPAddress& dest_ip,
193                    EmulatedNetworkReceiverInterface* receiver);
194   void RemoveReceiver(const rtc::IPAddress& dest_ip);
195   // Sets a default receive that will be used for all incoming packets for which
196   // there is no specific receiver binded to their destination port.
197   void SetDefaultReceiver(EmulatedNetworkReceiverInterface* receiver);
198   void RemoveDefaultReceiver();
199   void SetWatcher(std::function<void(const EmulatedIpPacket&)> watcher);
200   void SetFilter(std::function<bool(const EmulatedIpPacket&)> filter);
201 
202  private:
203   rtc::TaskQueue* const task_queue_;
204   absl::optional<EmulatedNetworkReceiverInterface*> default_receiver_
205       RTC_GUARDED_BY(task_queue_);
206   std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
207       RTC_GUARDED_BY(task_queue_);
208   std::function<void(const EmulatedIpPacket&)> watcher_
209       RTC_GUARDED_BY(task_queue_);
210   std::function<bool(const EmulatedIpPacket&)> filter_
211       RTC_GUARDED_BY(task_queue_);
212 };
213 
214 // Represents node in the emulated network. Nodes can be connected with each
215 // other to form different networks with different behavior. The behavior of
216 // the node itself is determined by a concrete implementation of
217 // NetworkBehaviorInterface that is provided on construction.
218 class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
219  public:
220   // Creates node based on `network_behavior`. The specified `packet_overhead`
221   // is added to the size of each packet in the information provided to
222   // `network_behavior`.
223   // `task_queue` is used to process packets and to forward the packets when
224   // they are ready.
225   EmulatedNetworkNode(
226       Clock* clock,
227       rtc::TaskQueue* task_queue,
228       std::unique_ptr<NetworkBehaviorInterface> network_behavior,
229       EmulatedNetworkStatsGatheringMode stats_gathering_mode);
230   ~EmulatedNetworkNode() override;
231 
232   EmulatedNetworkNode(const EmulatedNetworkNode&) = delete;
233   EmulatedNetworkNode& operator=(const EmulatedNetworkNode&) = delete;
234 
235   void OnPacketReceived(EmulatedIpPacket packet) override;
236 
link()237   LinkEmulation* link() { return &link_; }
router()238   NetworkRouterNode* router() { return &router_; }
239   EmulatedNetworkNodeStats stats() const;
240 
241   // Creates a route for the given receiver_ip over all the given nodes to the
242   // given receiver.
243   static void CreateRoute(const rtc::IPAddress& receiver_ip,
244                           std::vector<EmulatedNetworkNode*> nodes,
245                           EmulatedNetworkReceiverInterface* receiver);
246   static void ClearRoute(const rtc::IPAddress& receiver_ip,
247                          std::vector<EmulatedNetworkNode*> nodes);
248 
249  private:
250   NetworkRouterNode router_;
251   LinkEmulation link_;
252 };
253 
254 // Represents single network interface on the device.
255 // It will be used as sender from socket side to send data to the network and
256 // will act as packet receiver from emulated network side to receive packets
257 // from other EmulatedNetworkNodes.
258 class EmulatedEndpointImpl : public EmulatedEndpoint {
259  public:
260   struct Options {
261     Options(uint64_t id,
262             const rtc::IPAddress& ip,
263             const EmulatedEndpointConfig& config,
264             EmulatedNetworkStatsGatheringMode stats_gathering_mode);
265 
266     // TODO(titovartem) check if we can remove id.
267     uint64_t id;
268     // Endpoint local IP address.
269     rtc::IPAddress ip;
270     EmulatedNetworkStatsGatheringMode stats_gathering_mode;
271     rtc::AdapterType type;
272     // Allow endpoint to send packets specifying source IP address different to
273     // the current endpoint IP address. If false endpoint will crash if attempt
274     // to send such packet will be done.
275     bool allow_send_packet_with_different_source_ip;
276     // Allow endpoint to receive packet with destination IP address different to
277     // the current endpoint IP address. If false endpoint will crash if such
278     // packet will arrive.
279     bool allow_receive_packets_with_different_dest_ip;
280     // Name of the endpoint used for logging purposes.
281     std::string log_name;
282   };
283 
284   EmulatedEndpointImpl(const Options& options,
285                        bool is_enabled,
286                        rtc::TaskQueue* task_queue,
287                        Clock* clock);
288   ~EmulatedEndpointImpl() override;
289 
290   uint64_t GetId() const;
291 
router()292   NetworkRouterNode* router() { return &router_; }
293 
294   void SendPacket(const rtc::SocketAddress& from,
295                   const rtc::SocketAddress& to,
296                   rtc::CopyOnWriteBuffer packet_data,
297                   uint16_t application_overhead = 0) override;
298 
299   absl::optional<uint16_t> BindReceiver(
300       uint16_t desired_port,
301       EmulatedNetworkReceiverInterface* receiver) override;
302   // Binds a receiver, and automatically removes the binding after first call to
303   // OnPacketReceived.
304   absl::optional<uint16_t> BindOneShotReceiver(
305       uint16_t desired_port,
306       EmulatedNetworkReceiverInterface* receiver);
307   void UnbindReceiver(uint16_t port) override;
308   void BindDefaultReceiver(EmulatedNetworkReceiverInterface* receiver) override;
309   void UnbindDefaultReceiver() override;
310 
311   rtc::IPAddress GetPeerLocalAddress() const override;
312 
313   // Will be called to deliver packet into endpoint from network node.
314   void OnPacketReceived(EmulatedIpPacket packet) override;
315 
316   void Enable();
317   void Disable();
318   bool Enabled() const;
319 
network()320   const rtc::Network& network() const { return *network_.get(); }
321 
322   EmulatedNetworkStats stats() const;
323 
324  private:
325   struct ReceiverBinding {
326     EmulatedNetworkReceiverInterface* receiver;
327     bool is_one_shot;
328   };
329 
330   absl::optional<uint16_t> BindReceiverInternal(
331       uint16_t desired_port,
332       EmulatedNetworkReceiverInterface* receiver,
333       bool is_one_shot);
334 
335   static constexpr uint16_t kFirstEphemeralPort = 49152;
336   uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);
337 
338   Mutex receiver_lock_;
339   RTC_NO_UNIQUE_ADDRESS SequenceChecker enabled_state_checker_;
340 
341   const Options options_;
342   bool is_enabled_ RTC_GUARDED_BY(enabled_state_checker_);
343   Clock* const clock_;
344   rtc::TaskQueue* const task_queue_;
345   std::unique_ptr<rtc::Network> network_;
346   NetworkRouterNode router_;
347 
348   uint16_t next_port_ RTC_GUARDED_BY(receiver_lock_);
349   absl::optional<EmulatedNetworkReceiverInterface*> default_receiver_
350       RTC_GUARDED_BY(receiver_lock_);
351   std::map<uint16_t, ReceiverBinding> port_to_receiver_
352       RTC_GUARDED_BY(receiver_lock_);
353 
354   EmulatedNetworkStatsBuilder stats_builder_ RTC_GUARDED_BY(task_queue_);
355 };
356 
357 class EmulatedRoute {
358  public:
EmulatedRoute(EmulatedEndpointImpl * from,std::vector<EmulatedNetworkNode * > via_nodes,EmulatedEndpointImpl * to,bool is_default)359   EmulatedRoute(EmulatedEndpointImpl* from,
360                 std::vector<EmulatedNetworkNode*> via_nodes,
361                 EmulatedEndpointImpl* to,
362                 bool is_default)
363       : from(from),
364         via_nodes(std::move(via_nodes)),
365         to(to),
366         active(true),
367         is_default(is_default) {}
368 
369   EmulatedEndpointImpl* from;
370   std::vector<EmulatedNetworkNode*> via_nodes;
371   EmulatedEndpointImpl* to;
372   bool active;
373   bool is_default;
374 };
375 
376 // This object is immutable and so thread safe.
377 class EndpointsContainer {
378  public:
379   EndpointsContainer(const std::vector<EmulatedEndpointImpl*>& endpoints,
380                      EmulatedNetworkStatsGatheringMode stats_gathering_mode);
381 
382   EmulatedEndpointImpl* LookupByLocalAddress(
383       const rtc::IPAddress& local_ip) const;
384   bool HasEndpoint(EmulatedEndpointImpl* endpoint) const;
385   // Returns list of networks for enabled endpoints. Caller takes ownership of
386   // returned rtc::Network objects.
387   std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
388   std::vector<EmulatedEndpoint*> GetEndpoints() const;
389   EmulatedNetworkStats GetStats() const;
390 
391  private:
392   const std::vector<EmulatedEndpointImpl*> endpoints_;
393   const EmulatedNetworkStatsGatheringMode stats_gathering_mode_;
394 };
395 
396 template <typename FakePacketType>
397 class FakePacketRoute : public EmulatedNetworkReceiverInterface {
398  public:
FakePacketRoute(EmulatedRoute * route,std::function<void (FakePacketType,Timestamp)> action)399   FakePacketRoute(EmulatedRoute* route,
400                   std::function<void(FakePacketType, Timestamp)> action)
401       : route_(route),
402         action_(std::move(action)),
403         send_addr_(route_->from->GetPeerLocalAddress(), 0),
404         recv_addr_(route_->to->GetPeerLocalAddress(),
405                    *route_->to->BindReceiver(0, this)) {}
406 
~FakePacketRoute()407   ~FakePacketRoute() { route_->to->UnbindReceiver(recv_addr_.port()); }
408 
SendPacket(size_t size,FakePacketType packet)409   void SendPacket(size_t size, FakePacketType packet) {
410     RTC_CHECK_GE(size, sizeof(int));
411     sent_.emplace(next_packet_id_, packet);
412     rtc::CopyOnWriteBuffer buf(size);
413     reinterpret_cast<int*>(buf.MutableData())[0] = next_packet_id_++;
414     route_->from->SendPacket(send_addr_, recv_addr_, buf);
415   }
416 
OnPacketReceived(EmulatedIpPacket packet)417   void OnPacketReceived(EmulatedIpPacket packet) override {
418     int packet_id = reinterpret_cast<const int*>(packet.data.data())[0];
419     action_(std::move(sent_[packet_id]), packet.arrival_time);
420     sent_.erase(packet_id);
421   }
422 
423  private:
424   EmulatedRoute* const route_;
425   const std::function<void(FakePacketType, Timestamp)> action_;
426   const rtc::SocketAddress send_addr_;
427   const rtc::SocketAddress recv_addr_;
428   int next_packet_id_ = 0;
429   std::map<int, FakePacketType> sent_;
430 };
431 
432 template <typename RequestPacketType, typename ResponsePacketType>
433 class TwoWayFakeTrafficRoute {
434  public:
435   class TrafficHandlerInterface {
436    public:
437     virtual void OnRequest(RequestPacketType, Timestamp) = 0;
438     virtual void OnResponse(ResponsePacketType, Timestamp) = 0;
439     virtual ~TrafficHandlerInterface() = default;
440   };
TwoWayFakeTrafficRoute(TrafficHandlerInterface * handler,EmulatedRoute * send_route,EmulatedRoute * ret_route)441   TwoWayFakeTrafficRoute(TrafficHandlerInterface* handler,
442                          EmulatedRoute* send_route,
443                          EmulatedRoute* ret_route)
444       : handler_(handler),
445         request_handler_{send_route,
446                          [&](RequestPacketType packet, Timestamp arrival_time) {
447                            handler_->OnRequest(std::move(packet), arrival_time);
448                          }},
449         response_handler_{
450             ret_route, [&](ResponsePacketType packet, Timestamp arrival_time) {
451               handler_->OnResponse(std::move(packet), arrival_time);
452             }} {}
SendRequest(size_t size,RequestPacketType packet)453   void SendRequest(size_t size, RequestPacketType packet) {
454     request_handler_.SendPacket(size, std::move(packet));
455   }
SendResponse(size_t size,ResponsePacketType packet)456   void SendResponse(size_t size, ResponsePacketType packet) {
457     response_handler_.SendPacket(size, std::move(packet));
458   }
459 
460  private:
461   TrafficHandlerInterface* handler_;
462   FakePacketRoute<RequestPacketType> request_handler_;
463   FakePacketRoute<ResponsePacketType> response_handler_;
464 };
465 }  // namespace webrtc
466 
467 #endif  // TEST_NETWORK_NETWORK_EMULATION_H_
468