xref: /aosp_15_r20/external/webrtc/api/test/network_emulation/network_emulation_interfaces.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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