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 #ifndef API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_ 11 #define API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_ 12 13 #include <map> 14 #include <memory> 15 #include <vector> 16 17 #include "absl/types/optional.h" 18 #include "api/array_view.h" 19 #include "api/numerics/samples_stats_counter.h" 20 #include "api/units/data_rate.h" 21 #include "api/units/data_size.h" 22 #include "api/units/timestamp.h" 23 #include "rtc_base/copy_on_write_buffer.h" 24 #include "rtc_base/ip_address.h" 25 #include "rtc_base/socket_address.h" 26 27 namespace webrtc { 28 29 struct EmulatedIpPacket { 30 public: 31 EmulatedIpPacket(const rtc::SocketAddress& from, 32 const rtc::SocketAddress& to, 33 rtc::CopyOnWriteBuffer data, 34 Timestamp arrival_time, 35 uint16_t application_overhead = 0); 36 ~EmulatedIpPacket() = default; 37 // This object is not copyable or assignable. 38 EmulatedIpPacket(const EmulatedIpPacket&) = delete; 39 EmulatedIpPacket& operator=(const EmulatedIpPacket&) = delete; 40 // This object is only moveable. 41 EmulatedIpPacket(EmulatedIpPacket&&) = default; 42 EmulatedIpPacket& operator=(EmulatedIpPacket&&) = default; 43 sizeEmulatedIpPacket44 size_t size() const { return data.size(); } cdataEmulatedIpPacket45 const uint8_t* cdata() const { return data.cdata(); } 46 ip_packet_sizeEmulatedIpPacket47 size_t ip_packet_size() const { return size() + headers_size; } 48 rtc::SocketAddress from; 49 rtc::SocketAddress to; 50 // Holds the UDP payload. 51 rtc::CopyOnWriteBuffer data; 52 uint16_t headers_size; 53 Timestamp arrival_time; 54 }; 55 56 // Interface for handling IP packets from an emulated network. This is used with 57 // EmulatedEndpoint to receive packets on a specific port. 58 class EmulatedNetworkReceiverInterface { 59 public: 60 virtual ~EmulatedNetworkReceiverInterface() = default; 61 62 virtual void OnPacketReceived(EmulatedIpPacket packet) = 0; 63 }; 64 65 struct EmulatedNetworkOutgoingStats { 66 int64_t packets_sent = 0; 67 68 DataSize bytes_sent = DataSize::Zero(); 69 70 // Sizes of all sent packets. 71 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. 72 SamplesStatsCounter sent_packets_size; 73 74 DataSize first_sent_packet_size = DataSize::Zero(); 75 76 // Time of the first packet sent or infinite value if no packets were sent. 77 Timestamp first_packet_sent_time = Timestamp::PlusInfinity(); 78 79 // Time of the last packet sent or infinite value if no packets were sent. 80 Timestamp last_packet_sent_time = Timestamp::MinusInfinity(); 81 82 // Returns average send rate. Requires that at least 2 packets were sent. 83 DataRate AverageSendRate() const; 84 }; 85 86 struct EmulatedNetworkIncomingStats { 87 // Total amount of packets received with or without destination. 88 int64_t packets_received = 0; 89 90 // Total amount of bytes in received packets. 91 DataSize bytes_received = DataSize::Zero(); 92 93 // Sizes of all received packets. 94 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. 95 SamplesStatsCounter received_packets_size; 96 97 // Total amount of packets that were received, but no destination was found. 98 int64_t packets_discarded_no_receiver = 0; 99 100 // Total amount of bytes in discarded packets. 101 DataSize bytes_discarded_no_receiver = DataSize::Zero(); 102 103 // Sizes of all packets that were received, but no destination was found. 104 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. 105 SamplesStatsCounter packets_discarded_no_receiver_size; 106 107 DataSize first_received_packet_size = DataSize::Zero(); 108 109 // Time of the first packet received or infinite value if no packets were 110 // received. 111 Timestamp first_packet_received_time = Timestamp::PlusInfinity(); 112 113 // Time of the last packet received or infinite value if no packets were 114 // received. 115 Timestamp last_packet_received_time = Timestamp::MinusInfinity(); 116 117 DataRate AverageReceiveRate() const; 118 }; 119 120 struct EmulatedNetworkStats { PacketsSentEmulatedNetworkStats121 int64_t PacketsSent() const { return overall_outgoing_stats.packets_sent; } 122 BytesSentEmulatedNetworkStats123 DataSize BytesSent() const { return overall_outgoing_stats.bytes_sent; } 124 125 // Returns the timestamped sizes of all sent packets. 126 // Returned reference is valid until the next call to a non-const method. 127 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. SentPacketsSizeCounterEmulatedNetworkStats128 const SamplesStatsCounter& SentPacketsSizeCounter() const { 129 return overall_outgoing_stats.sent_packets_size; 130 } 131 FirstSentPacketSizeEmulatedNetworkStats132 DataSize FirstSentPacketSize() const { 133 return overall_outgoing_stats.first_sent_packet_size; 134 } 135 136 // Returns time of the first packet sent or infinite value if no packets were 137 // sent. FirstPacketSentTimeEmulatedNetworkStats138 Timestamp FirstPacketSentTime() const { 139 return overall_outgoing_stats.first_packet_sent_time; 140 } 141 142 // Returns time of the last packet sent or infinite value if no packets were 143 // sent. LastPacketSentTimeEmulatedNetworkStats144 Timestamp LastPacketSentTime() const { 145 return overall_outgoing_stats.last_packet_sent_time; 146 } 147 AverageSendRateEmulatedNetworkStats148 DataRate AverageSendRate() const { 149 return overall_outgoing_stats.AverageSendRate(); 150 } 151 152 // Total amount of packets received regardless of the destination address. PacketsReceivedEmulatedNetworkStats153 int64_t PacketsReceived() const { 154 return overall_incoming_stats.packets_received; 155 } 156 157 // Total amount of bytes in received packets. BytesReceivedEmulatedNetworkStats158 DataSize BytesReceived() const { 159 return overall_incoming_stats.bytes_received; 160 } 161 162 // Returns the timestamped sizes of all received packets. 163 // Returned reference is valid until the next call to a non-const method. 164 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. ReceivedPacketsSizeCounterEmulatedNetworkStats165 const SamplesStatsCounter& ReceivedPacketsSizeCounter() const { 166 return overall_incoming_stats.received_packets_size; 167 } 168 169 // Total amount of packets that were received, but no destination was found. PacketsDiscardedNoReceiverEmulatedNetworkStats170 int64_t PacketsDiscardedNoReceiver() const { 171 return overall_incoming_stats.packets_discarded_no_receiver; 172 } 173 174 // Total amount of bytes in dropped packets. BytesDiscardedNoReceiverEmulatedNetworkStats175 DataSize BytesDiscardedNoReceiver() const { 176 return overall_incoming_stats.bytes_discarded_no_receiver; 177 } 178 179 // Returns counter with timestamped sizes of all packets that were received, 180 // but no destination was found. 181 // Returned reference is valid until the next call to a non-const method. 182 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. PacketsDiscardedNoReceiverSizeCounterEmulatedNetworkStats183 const SamplesStatsCounter& PacketsDiscardedNoReceiverSizeCounter() const { 184 return overall_incoming_stats.packets_discarded_no_receiver_size; 185 } 186 FirstReceivedPacketSizeEmulatedNetworkStats187 DataSize FirstReceivedPacketSize() const { 188 return overall_incoming_stats.first_received_packet_size; 189 } 190 191 // Returns time of the first packet received or infinite value if no packets 192 // were received. FirstPacketReceivedTimeEmulatedNetworkStats193 Timestamp FirstPacketReceivedTime() const { 194 return overall_incoming_stats.first_packet_received_time; 195 } 196 197 // Returns time of the last packet received or infinite value if no packets 198 // were received. LastPacketReceivedTimeEmulatedNetworkStats199 Timestamp LastPacketReceivedTime() const { 200 return overall_incoming_stats.last_packet_received_time; 201 } 202 AverageReceiveRateEmulatedNetworkStats203 DataRate AverageReceiveRate() const { 204 return overall_incoming_stats.AverageReceiveRate(); 205 } 206 207 // List of IP addresses that were used to send data considered in this stats 208 // object. 209 std::vector<rtc::IPAddress> local_addresses; 210 211 // Overall outgoing stats for all IP addresses which were requested. 212 EmulatedNetworkOutgoingStats overall_outgoing_stats; 213 214 // Overall incoming stats for all IP addresses from which data was received 215 // on requested interfaces. 216 EmulatedNetworkIncomingStats overall_incoming_stats; 217 218 std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats> 219 outgoing_stats_per_destination; 220 std::map<rtc::IPAddress, EmulatedNetworkIncomingStats> 221 incoming_stats_per_source; 222 223 // Duration between packet was received on network interface and was 224 // dispatched to the network in microseconds. 225 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. 226 SamplesStatsCounter sent_packets_queue_wait_time_us; 227 }; 228 229 struct EmulatedNetworkNodeStats { 230 // Amount of time each packet spent in the emulated network node for which 231 // stats were collected. 232 // 233 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. 234 SamplesStatsCounter packet_transport_time; 235 236 // For each packet contains its size divided on the amount of time which it 237 // spent in the emulated network node for which stats were collected. 238 // 239 // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled. 240 SamplesStatsCounter size_to_packet_transport_time; 241 }; 242 243 // EmulatedEndpoint is an abstraction for network interface on device. Instances 244 // of this are created by NetworkEmulationManager::CreateEndpoint and 245 // thread safe. 246 class EmulatedEndpoint : public EmulatedNetworkReceiverInterface { 247 public: 248 // Send packet into network. 249 // `from` will be used to set source address for the packet in destination 250 // socket. 251 // `to` will be used for routing verification and picking right socket by port 252 // on destination endpoint. 253 virtual void SendPacket(const rtc::SocketAddress& from, 254 const rtc::SocketAddress& to, 255 rtc::CopyOnWriteBuffer packet_data, 256 uint16_t application_overhead = 0) = 0; 257 258 // Binds receiver to this endpoint to send and receive data. 259 // `desired_port` is a port that should be used. If it is equal to 0, 260 // endpoint will pick the first available port starting from 261 // `kFirstEphemeralPort`. 262 // 263 // Returns the port, that should be used (it will be equals to desired, if 264 // `desired_port` != 0 and is free or will be the one, selected by endpoint) 265 // or absl::nullopt if desired_port in used. Also fails if there are no more 266 // free ports to bind to. 267 // 268 // The Bind- and Unbind-methods must not be called from within a bound 269 // receiver's OnPacketReceived method. 270 virtual absl::optional<uint16_t> BindReceiver( 271 uint16_t desired_port, 272 EmulatedNetworkReceiverInterface* receiver) = 0; 273 // Unbinds receiver from the specified port. Do nothing if no receiver was 274 // bound before. After this method returns, no more packets can be delivered 275 // to the receiver, and it is safe to destroy it. 276 virtual void UnbindReceiver(uint16_t port) = 0; 277 // Binds receiver that will accept all packets which arrived on any port 278 // for which there are no bound receiver. 279 virtual void BindDefaultReceiver( 280 EmulatedNetworkReceiverInterface* receiver) = 0; 281 // Unbinds default receiver. Do nothing if no default receiver was bound 282 // before. 283 virtual void UnbindDefaultReceiver() = 0; 284 virtual rtc::IPAddress GetPeerLocalAddress() const = 0; 285 286 private: 287 // Ensure that there can be no other subclass than EmulatedEndpointImpl. This 288 // means that it's always safe to downcast EmulatedEndpoint instances to 289 // EmulatedEndpointImpl. 290 friend class EmulatedEndpointImpl; 291 EmulatedEndpoint() = default; 292 }; 293 294 // Simulates a TCP connection, this roughly implements the Reno algorithm. In 295 // difference from TCP this only support sending messages with a fixed length, 296 // no streaming. This is useful to simulate signaling and cross traffic using 297 // message based protocols such as HTTP. It differs from UDP messages in that 298 // they are guranteed to be delivered eventually, even on lossy networks. 299 class TcpMessageRoute { 300 public: 301 // Sends a TCP message of the given `size` over the route, `on_received` is 302 // called when the message has been delivered. Note that the connection 303 // parameters are reset iff there's no currently pending message on the route. 304 virtual void SendMessage(size_t size, std::function<void()> on_received) = 0; 305 306 protected: 307 ~TcpMessageRoute() = default; 308 }; 309 } // namespace webrtc 310 311 #endif // API_TEST_NETWORK_EMULATION_NETWORK_EMULATION_INTERFACES_H_ 312