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