• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test/network_emulation_manager.h"
24 #include "api/test/simulated_network.h"
25 #include "api/units/timestamp.h"
26 #include "rtc_base/copy_on_write_buffer.h"
27 #include "rtc_base/network.h"
28 #include "rtc_base/network_constants.h"
29 #include "rtc_base/socket_address.h"
30 #include "rtc_base/task_queue_for_test.h"
31 #include "rtc_base/task_utils/repeating_task.h"
32 #include "rtc_base/thread_checker.h"
33 #include "system_wrappers/include/clock.h"
34 
35 namespace webrtc {
36 
37 
38 class LinkEmulation : public EmulatedNetworkReceiverInterface {
39  public:
LinkEmulation(Clock * clock,rtc::TaskQueue * task_queue,std::unique_ptr<NetworkBehaviorInterface> network_behavior,EmulatedNetworkReceiverInterface * receiver)40   LinkEmulation(Clock* clock,
41                 rtc::TaskQueue* task_queue,
42                 std::unique_ptr<NetworkBehaviorInterface> network_behavior,
43                 EmulatedNetworkReceiverInterface* receiver)
44       : clock_(clock),
45         task_queue_(task_queue),
46         network_behavior_(std::move(network_behavior)),
47         receiver_(receiver) {}
48   void OnPacketReceived(EmulatedIpPacket packet) override;
49 
50  private:
51   struct StoredPacket {
52     uint64_t id;
53     EmulatedIpPacket packet;
54     bool removed;
55   };
56   void Process(Timestamp at_time) RTC_RUN_ON(task_queue_);
57 
58   Clock* const clock_;
59   rtc::TaskQueue* const task_queue_;
60   const std::unique_ptr<NetworkBehaviorInterface> network_behavior_
61       RTC_GUARDED_BY(task_queue_);
62   EmulatedNetworkReceiverInterface* const receiver_;
63   RepeatingTaskHandle process_task_ RTC_GUARDED_BY(task_queue_);
64   std::deque<StoredPacket> packets_ RTC_GUARDED_BY(task_queue_);
65   uint64_t next_packet_id_ RTC_GUARDED_BY(task_queue_) = 1;
66 };
67 
68 class NetworkRouterNode : public EmulatedNetworkReceiverInterface {
69  public:
70   explicit NetworkRouterNode(rtc::TaskQueue* task_queue);
71 
72   void OnPacketReceived(EmulatedIpPacket packet) override;
73   void SetReceiver(const rtc::IPAddress& dest_ip,
74                    EmulatedNetworkReceiverInterface* receiver);
75   void RemoveReceiver(const rtc::IPAddress& dest_ip);
76   void SetWatcher(std::function<void(const EmulatedIpPacket&)> watcher);
77   void SetFilter(std::function<bool(const EmulatedIpPacket&)> filter);
78 
79  private:
80   rtc::TaskQueue* const task_queue_;
81   std::map<rtc::IPAddress, EmulatedNetworkReceiverInterface*> routing_
82       RTC_GUARDED_BY(task_queue_);
83   std::function<void(const EmulatedIpPacket&)> watcher_
84       RTC_GUARDED_BY(task_queue_);
85   std::function<bool(const EmulatedIpPacket&)> filter_
86       RTC_GUARDED_BY(task_queue_);
87 };
88 
89 // Represents node in the emulated network. Nodes can be connected with each
90 // other to form different networks with different behavior. The behavior of
91 // the node itself is determined by a concrete implementation of
92 // NetworkBehaviorInterface that is provided on construction.
93 class EmulatedNetworkNode : public EmulatedNetworkReceiverInterface {
94  public:
95   // Creates node based on |network_behavior|. The specified |packet_overhead|
96   // is added to the size of each packet in the information provided to
97   // |network_behavior|.
98   // |task_queue| is used to process packets and to forward the packets when
99   // they are ready.
100   EmulatedNetworkNode(
101       Clock* clock,
102       rtc::TaskQueue* task_queue,
103       std::unique_ptr<NetworkBehaviorInterface> network_behavior);
104   ~EmulatedNetworkNode() override;
105   RTC_DISALLOW_COPY_AND_ASSIGN(EmulatedNetworkNode);
106 
107   void OnPacketReceived(EmulatedIpPacket packet) override;
108 
link()109   LinkEmulation* link() { return &link_; }
router()110   NetworkRouterNode* router() { return &router_; }
111 
112   // Creates a route for the given receiver_ip over all the given nodes to the
113   // given receiver.
114   static void CreateRoute(const rtc::IPAddress& receiver_ip,
115                           std::vector<EmulatedNetworkNode*> nodes,
116                           EmulatedNetworkReceiverInterface* receiver);
117   static void ClearRoute(const rtc::IPAddress& receiver_ip,
118                          std::vector<EmulatedNetworkNode*> nodes);
119 
120  private:
121   NetworkRouterNode router_;
122   LinkEmulation link_;
123 };
124 
125 // Represents single network interface on the device.
126 // It will be used as sender from socket side to send data to the network and
127 // will act as packet receiver from emulated network side to receive packets
128 // from other EmulatedNetworkNodes.
129 class EmulatedEndpointImpl : public EmulatedEndpoint {
130  public:
131   EmulatedEndpointImpl(uint64_t id,
132                        const rtc::IPAddress& ip,
133                        bool is_enabled,
134                        rtc::AdapterType type,
135                        rtc::TaskQueue* task_queue,
136                        Clock* clock);
137   ~EmulatedEndpointImpl() override;
138 
139   uint64_t GetId() const;
140 
router()141   NetworkRouterNode* router() { return &router_; }
142 
143   void SendPacket(const rtc::SocketAddress& from,
144                   const rtc::SocketAddress& to,
145                   rtc::CopyOnWriteBuffer packet_data,
146                   uint16_t application_overhead = 0) override;
147 
148   absl::optional<uint16_t> BindReceiver(
149       uint16_t desired_port,
150       EmulatedNetworkReceiverInterface* receiver) override;
151   void UnbindReceiver(uint16_t port) override;
152 
153   rtc::IPAddress GetPeerLocalAddress() const override;
154 
155   // Will be called to deliver packet into endpoint from network node.
156   void OnPacketReceived(EmulatedIpPacket packet) override;
157 
158   void Enable();
159   void Disable();
160   bool Enabled() const;
161 
network()162   const rtc::Network& network() const { return *network_.get(); }
163 
164   EmulatedNetworkStats stats() override;
165 
166  private:
167   static constexpr uint16_t kFirstEphemeralPort = 49152;
168   uint16_t NextPort() RTC_EXCLUSIVE_LOCKS_REQUIRED(receiver_lock_);
169   void UpdateReceiveStats(const EmulatedIpPacket& packet);
170 
171   rtc::RecursiveCriticalSection receiver_lock_;
172   rtc::ThreadChecker enabled_state_checker_;
173 
174   uint64_t id_;
175   // Peer's local IP address for this endpoint network interface.
176   const rtc::IPAddress peer_local_addr_;
177   bool is_enabled_ RTC_GUARDED_BY(enabled_state_checker_);
178   const rtc::AdapterType type_;
179   Clock* const clock_;
180   rtc::TaskQueue* const task_queue_;
181   std::unique_ptr<rtc::Network> network_;
182   NetworkRouterNode router_;
183 
184   uint16_t next_port_ RTC_GUARDED_BY(receiver_lock_);
185   std::map<uint16_t, EmulatedNetworkReceiverInterface*> port_to_receiver_
186       RTC_GUARDED_BY(receiver_lock_);
187 
188   EmulatedNetworkStats stats_ RTC_GUARDED_BY(task_queue_);
189 };
190 
191 class EmulatedRoute {
192  public:
EmulatedRoute(EmulatedEndpointImpl * from,std::vector<EmulatedNetworkNode * > via_nodes,EmulatedEndpointImpl * to)193   EmulatedRoute(EmulatedEndpointImpl* from,
194                 std::vector<EmulatedNetworkNode*> via_nodes,
195                 EmulatedEndpointImpl* to)
196       : from(from), via_nodes(std::move(via_nodes)), to(to), active(true) {}
197 
198   EmulatedEndpointImpl* from;
199   std::vector<EmulatedNetworkNode*> via_nodes;
200   EmulatedEndpointImpl* to;
201   bool active;
202 };
203 
204 class EndpointsContainer {
205  public:
206   explicit EndpointsContainer(
207       const std::vector<EmulatedEndpointImpl*>& endpoints);
208 
209   EmulatedEndpointImpl* LookupByLocalAddress(
210       const rtc::IPAddress& local_ip) const;
211   bool HasEndpoint(EmulatedEndpointImpl* endpoint) const;
212   // Returns list of networks for enabled endpoints. Caller takes ownership of
213   // returned rtc::Network objects.
214   std::vector<std::unique_ptr<rtc::Network>> GetEnabledNetworks() const;
215   EmulatedNetworkStats GetStats() const;
216 
217  private:
218   const std::vector<EmulatedEndpointImpl*> endpoints_;
219 };
220 
221 template <typename FakePacketType>
222 class FakePacketRoute : public EmulatedNetworkReceiverInterface {
223  public:
FakePacketRoute(EmulatedRoute * route,std::function<void (FakePacketType,Timestamp)> action)224   FakePacketRoute(EmulatedRoute* route,
225                   std::function<void(FakePacketType, Timestamp)> action)
226       : route_(route),
227         action_(std::move(action)),
228         send_addr_(route_->from->GetPeerLocalAddress(), 0),
229         recv_addr_(route_->to->GetPeerLocalAddress(),
230                    *route_->to->BindReceiver(0, this)) {}
231 
~FakePacketRoute()232   ~FakePacketRoute() { route_->to->UnbindReceiver(recv_addr_.port()); }
233 
SendPacket(size_t size,FakePacketType packet)234   void SendPacket(size_t size, FakePacketType packet) {
235     RTC_CHECK_GE(size, sizeof(int));
236     sent_.emplace(next_packet_id_, packet);
237     rtc::CopyOnWriteBuffer buf(size);
238     reinterpret_cast<int*>(buf.data())[0] = next_packet_id_++;
239     route_->from->SendPacket(send_addr_, recv_addr_, buf);
240   }
241 
OnPacketReceived(EmulatedIpPacket packet)242   void OnPacketReceived(EmulatedIpPacket packet) override {
243     int packet_id = reinterpret_cast<int*>(packet.data.data())[0];
244     action_(std::move(sent_[packet_id]), packet.arrival_time);
245     sent_.erase(packet_id);
246   }
247 
248  private:
249   EmulatedRoute* const route_;
250   const std::function<void(FakePacketType, Timestamp)> action_;
251   const rtc::SocketAddress send_addr_;
252   const rtc::SocketAddress recv_addr_;
253   int next_packet_id_ = 0;
254   std::map<int, FakePacketType> sent_;
255 };
256 
257 template <typename RequestPacketType, typename ResponsePacketType>
258 class TwoWayFakeTrafficRoute {
259  public:
260   class TrafficHandlerInterface {
261    public:
262     virtual void OnRequest(RequestPacketType, Timestamp) = 0;
263     virtual void OnResponse(ResponsePacketType, Timestamp) = 0;
264     virtual ~TrafficHandlerInterface() = default;
265   };
TwoWayFakeTrafficRoute(TrafficHandlerInterface * handler,EmulatedRoute * send_route,EmulatedRoute * ret_route)266   TwoWayFakeTrafficRoute(TrafficHandlerInterface* handler,
267                          EmulatedRoute* send_route,
268                          EmulatedRoute* ret_route)
269       : handler_(handler),
270         request_handler_{send_route,
271                          [&](RequestPacketType packet, Timestamp arrival_time) {
272                            handler_->OnRequest(std::move(packet), arrival_time);
273                          }},
274         response_handler_{
275             ret_route, [&](ResponsePacketType packet, Timestamp arrival_time) {
276               handler_->OnResponse(std::move(packet), arrival_time);
277             }} {}
SendRequest(size_t size,RequestPacketType packet)278   void SendRequest(size_t size, RequestPacketType packet) {
279     request_handler_.SendPacket(size, std::move(packet));
280   }
SendResponse(size_t size,ResponsePacketType packet)281   void SendResponse(size_t size, ResponsePacketType packet) {
282     response_handler_.SendPacket(size, std::move(packet));
283   }
284 
285  private:
286   TrafficHandlerInterface* handler_;
287   FakePacketRoute<RequestPacketType> request_handler_;
288   FakePacketRoute<ResponsePacketType> response_handler_;
289 };
290 }  // namespace webrtc
291 
292 #endif  // TEST_NETWORK_NETWORK_EMULATION_H_
293