rtc_ice/agent/
agent_stats.rs

1use crate::agent::Agent;
2use std::time::Instant;
3
4use crate::candidate::{CandidateType, candidate_pair::CandidatePairState};
5use crate::network_type::NetworkType;
6
7/// Contains ICE candidate pair statistics.
8pub struct CandidatePairStats {
9    /// The timestamp associated with this struct.
10    pub timestamp: Instant,
11
12    /// The id of the local candidate.
13    pub local_candidate_id: String,
14
15    /// The id of the remote candidate.
16    pub remote_candidate_id: String,
17
18    /// The state of the checklist for the local and remote candidates in a pair.
19    pub state: CandidatePairState,
20
21    /// It is true when this valid pair that should be used for media,
22    /// if it is the highest-priority one amongst those whose nominated flag is set.
23    pub nominated: bool,
24
25    /// The total number of packets sent on this candidate pair.
26    pub packets_sent: u32,
27
28    /// The total number of packets received on this candidate pair.
29    pub packets_received: u32,
30
31    /// The total number of payload bytes sent on this candidate pair not including headers or
32    /// padding.
33    pub bytes_sent: u64,
34
35    /// The total number of payload bytes received on this candidate pair not including headers or
36    /// padding.
37    pub bytes_received: u64,
38
39    /// The timestamp at which the last packet was sent on this particular candidate pair, excluding
40    /// STUN packets.
41    pub last_packet_sent_timestamp: Instant,
42
43    /// The timestamp at which the last packet was received on this particular candidate pair,
44    /// excluding STUN packets.
45    pub last_packet_received_timestamp: Instant,
46
47    /// The timestamp at which the first STUN request was sent on this particular candidate pair.
48    pub first_request_timestamp: Instant,
49
50    /// The timestamp at which the last STUN request was sent on this particular candidate pair.
51    /// The average interval between two consecutive connectivity checks sent can be calculated with
52    /// (last_request_timestamp - first_request_timestamp) / requests_sent.
53    pub last_request_timestamp: Instant,
54
55    /// Timestamp at which the last STUN response was received on this particular candidate pair.
56    pub last_response_timestamp: Instant,
57
58    /// The sum of all round trip time measurements in seconds since the beginning of the session,
59    /// based on STUN connectivity check responses (responses_received), including those that reply
60    /// to requests that are sent in order to verify consent. The average round trip time can be
61    /// computed from total_round_trip_time by dividing it by responses_received.
62    pub total_round_trip_time: f64,
63
64    /// The latest round trip time measured in seconds, computed from both STUN connectivity checks,
65    /// including those that are sent for consent verification.
66    pub current_round_trip_time: f64,
67
68    /// It is calculated by the underlying congestion control by combining the available bitrate for
69    /// all the outgoing RTP streams using this candidate pair. The bitrate measurement does not
70    /// count the size of the IP or other transport layers like TCP or UDP. It is similar to the
71    /// TIAS defined in RFC 3890, i.e., it is measured in bits per second and the bitrate is
72    /// calculated over a 1 second window.
73    pub available_outgoing_bitrate: f64,
74
75    /// It is calculated by the underlying congestion control by combining the available bitrate for
76    /// all the incoming RTP streams using this candidate pair. The bitrate measurement does not
77    /// count the size of the IP or other transport layers like TCP or UDP. It is similar to the
78    /// TIAS defined in  RFC 3890, i.e., it is measured in bits per second and the bitrate is
79    /// calculated over a 1 second window.
80    pub available_incoming_bitrate: f64,
81
82    /// The number of times the circuit breaker is triggered for this particular 5-tuple,
83    /// ceasing transmission.
84    pub circuit_breaker_trigger_count: u32,
85
86    /// The total number of connectivity check requests received (including retransmissions).
87    /// It is impossible for the receiver to tell whether the request was sent in order to check
88    /// connectivity or check consent, so all connectivity checks requests are counted here.
89    pub requests_received: u64,
90
91    /// The total number of connectivity check requests sent (not including retransmissions).
92    pub requests_sent: u64,
93
94    /// The total number of connectivity check responses received.
95    pub responses_received: u64,
96
97    /// The total number of connectivity check responses sent. Since we cannot distinguish
98    /// connectivity check requests and consent requests, all responses are counted.
99    pub responses_sent: u64,
100
101    /// The total number of connectivity check request retransmissions received.
102    pub retransmissions_received: u64,
103
104    /// The total number of connectivity check request retransmissions sent.
105    pub retransmissions_sent: u64,
106
107    /// The total number of consent requests sent.
108    pub consent_requests_sent: u64,
109
110    /// The timestamp at which the latest valid STUN binding response expired.
111    pub consent_expired_timestamp: Instant,
112}
113
114impl Default for CandidatePairStats {
115    fn default() -> Self {
116        Self {
117            timestamp: Instant::now(),
118            local_candidate_id: String::new(),
119            remote_candidate_id: String::new(),
120            state: CandidatePairState::default(),
121            nominated: false,
122            packets_sent: 0,
123            packets_received: 0,
124            bytes_sent: 0,
125            bytes_received: 0,
126            last_packet_sent_timestamp: Instant::now(),
127            last_packet_received_timestamp: Instant::now(),
128            first_request_timestamp: Instant::now(),
129            last_request_timestamp: Instant::now(),
130            last_response_timestamp: Instant::now(),
131            total_round_trip_time: 0.0,
132            current_round_trip_time: 0.0,
133            available_outgoing_bitrate: 0.0,
134            available_incoming_bitrate: 0.0,
135            circuit_breaker_trigger_count: 0,
136            requests_received: 0,
137            requests_sent: 0,
138            responses_received: 0,
139            responses_sent: 0,
140            retransmissions_received: 0,
141            retransmissions_sent: 0,
142            consent_requests_sent: 0,
143            consent_expired_timestamp: Instant::now(),
144        }
145    }
146}
147
148/// Contains ICE candidate statistics related to the `ICETransport` objects.
149#[derive(Debug, Clone)]
150pub struct CandidateStats {
151    // The timestamp associated with this struct.
152    pub timestamp: Instant,
153
154    /// The candidate id.
155    pub id: String,
156
157    /// The type of network interface used by the base of a local candidate (the address the ICE
158    /// agent sends from). Only present for local candidates; it's not possible to know what type of
159    /// network interface a remote candidate is using.
160    ///
161    /// Note: This stat only tells you about the network interface used by the first "hop"; it's
162    /// possible that a connection will be bottlenecked by another type of network.  For example,
163    /// when using Wi-Fi tethering, the networkType of the relevant candidate would be "wifi", even
164    /// when the next hop is over a cellular connection.
165    pub network_type: NetworkType,
166
167    /// The IP address of the candidate, allowing for IPv4 addresses and IPv6 addresses, but fully
168    /// qualified domain names (FQDNs) are not allowed.
169    pub ip: String,
170
171    /// The port number of the candidate.
172    pub port: u16,
173
174    /// The `Type` field of the ICECandidate.
175    pub candidate_type: CandidateType,
176
177    /// The `priority` field of the ICECandidate.
178    pub priority: u32,
179
180    /// The url of the TURN or STUN server indicated in the that translated this IP address.
181    /// It is the url address surfaced in an PeerConnectionICEEvent.
182    pub url: String,
183
184    /// The protocol used by the endpoint to communicate with the TURN server. This is only present
185    /// for local candidates. Valid values for the TURN url protocol is one of udp, tcp, or tls.
186    pub relay_protocol: String,
187
188    /// It is true if the candidate has been deleted/freed. For host candidates, this means that any
189    /// network resources (typically a socket) associated with the candidate have been released. For
190    /// TURN candidates, this means the TURN allocation is no longer active.
191    ///
192    /// Only defined for local candidates. For remote candidates, this property is not applicable.
193    pub deleted: bool,
194}
195
196impl Default for CandidateStats {
197    fn default() -> Self {
198        Self {
199            timestamp: Instant::now(),
200            id: String::new(),
201            network_type: NetworkType::default(),
202            ip: String::new(),
203            port: 0,
204            candidate_type: CandidateType::default(),
205            priority: 0,
206            url: String::new(),
207            relay_protocol: String::new(),
208            deleted: false,
209        }
210    }
211}
212
213impl Agent {
214    /// Returns a list of candidate pair stats.
215    pub fn get_candidate_pairs_stats(&self) -> Vec<CandidatePairStats> {
216        let mut res = Vec::with_capacity(self.candidate_pairs.len());
217        for cp in &self.candidate_pairs {
218            let stat = CandidatePairStats {
219                timestamp: Instant::now(),
220                local_candidate_id: self.local_candidates[cp.local_index].id(),
221                remote_candidate_id: self.remote_candidates[cp.remote_index].id(),
222                state: cp.state,
223                nominated: cp.nominated,
224                ..CandidatePairStats::default()
225            };
226            res.push(stat);
227        }
228        res
229    }
230
231    /// Returns a list of local candidates stats.
232    pub fn get_local_candidates_stats(&self) -> Vec<CandidateStats> {
233        let mut res = Vec::with_capacity(self.local_candidates.len());
234        for c in &self.local_candidates {
235            let stat = CandidateStats {
236                timestamp: Instant::now(),
237                id: c.id(),
238                network_type: c.network_type(),
239                ip: c.address().to_owned(),
240                port: c.port(),
241                candidate_type: c.candidate_type(),
242                priority: c.priority(),
243                // URL string
244                relay_protocol: "udp".to_owned(),
245                // Deleted bool
246                ..CandidateStats::default()
247            };
248            res.push(stat);
249        }
250        res
251    }
252
253    /// Returns a list of remote candidates stats.
254    pub fn get_remote_candidates_stats(&self) -> Vec<CandidateStats> {
255        let mut res = Vec::with_capacity(self.remote_candidates.len());
256        for c in &self.remote_candidates {
257            let stat = CandidateStats {
258                timestamp: Instant::now(),
259                id: c.id(),
260                network_type: c.network_type(),
261                ip: c.address().to_owned(),
262                port: c.port(),
263                candidate_type: c.candidate_type(),
264                priority: c.priority(),
265                // URL string
266                relay_protocol: "udp".to_owned(),
267                // Deleted bool
268                ..CandidateStats::default()
269            };
270            res.push(stat);
271        }
272        res
273    }
274}