/// Datagram stats #[derive(Default, Clone, PartialEq, Eq)] pubstruct DatagramStats { /// The number of datagrams declared lost. pub lost: usize, /// The number of datagrams dropped due to being too large. pub dropped_too_big: usize, /// The number of datagrams dropped due to reaching the limit of the /// outgoing queue. pub dropped_queue_full: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)] pubenum SlowStartExitReason { /// Exited due to a congestion event (loss or ECN).
CongestionEvent, /// Exited due to a heuristic algorithm (e.g., HyStart++).
Heuristic,
}
/// Congestion event counters. /// /// `loss` and `ecn` are mutually exclusive triggers (their sum equals the total number of /// congestion events). `spurious` is an orthogonal category that applies to a subset of /// loss-triggered congestion events. #[derive(Default, Clone, PartialEq, Eq)] pubstruct CongestionEventStats { /// Congestion events triggered by packet loss. pub loss: usize, /// Congestion events triggered by ECN-CE marks. pub ecn: usize, /// Congestion events later found to be spurious, due to packets which were initially /// considered lost but later got acknowledged. pub spurious: usize,
}
/// Tracks SEARCH reset occurrences: how many times SEARCH reset and the maximum number of bins /// skipped across all resets. #[derive(Default, Clone, PartialEq, Eq)] pubstruct SearchResetStats { pub count: usize, pub max_passed_bins: Option<usize>,
}
/// Congestion Control stats #[derive(Default, Clone, PartialEq)] pubstruct CongestionControlStats { /// Congestion event counters. Includes trigger type and other qualifier flags. pub congestion_events: CongestionEventStats, /// The congestion window size (in bytes) when we exited slow start. /// None if we haven't exited slow start or if we re-entered after spurious congestion. /// When exiting via congestion event, this is the cwnd AFTER the reduction. pub slow_start_exit_cwnd: Option<usize>, /// The reason slow start was exited. None if we haven't exited slow start or if we re-entered /// after spurious congestion. pub slow_start_exit_reason: Option<SlowStartExitReason>, /// Number of times HyStart++ entered CSS (Conservative Slow Start). Only meaningful when /// HyStart++ is enabled. Higher values indicate that HyStart++ had many spurious CSS /// entries, spending more time throttling slow start growth. pub hystart_css_entries: usize, /// Number of CSS (Conservative Slow Start) rounds completed. Only meaningful when HyStart++ is /// enabled. Higher values indicate the heuristic spent more time throttling slow start growth. pub hystart_css_rounds_finished: usize, /// Drain-phase target estimate for the BDP with empty buffers. None if we haven't exited slow /// start through SEARCH. Is `u64` because Firefox uses it as such. pub search_empty_buffer_target: Option<u64>, /// Drain-phase target estimate for the BDP with full buffers. None if we haven't exited slow /// start through SEARCH. Is `u64` because Firefox uses it as such. pub search_full_buffer_target: Option<u64>, /// Records the maximum value of lookback bins needed due to RTT inflation. Fires whenever /// SEARCH can't run because there is not enough data for lookback. Is `None` if SEARCH never /// ran into this issue. pub search_lookback_bins_needed: Option<usize>, /// Records the maximum non-exiting value that the normalized difference between sent and acked /// bytes ever reached. Can be used to tune the exit threshold. `None` means that the SEARCH /// check never ran. pub search_max_norm_diff: Option<usize>, /// Records SEARCH reset occurrences. pub search_reset: SearchResetStats, /// Records the number of times per connection that SEARCH calculated zero bytes sent in the /// previous RTT. This exists to gain deeper understanding into app-limited behaviour. pub search_zero_sent_bytes: usize, /// The `latest_rtt` from the first ACK that initialized SEARCH. Used to evaluate whether the /// initial RTT sample (which sets `bin_duration`) is inflated relative to `min_rtt`. pub search_first_rtt: Option<Duration>, /// The `latest_rtt` from the second ACK processed by SEARCH. Together with `search_first_rtt`, /// allows evaluating whether `min(first, second)` would be a better initialization value. pub search_second_rtt: Option<Duration>, /// Cubic's `w_max`: the congestion window (in bytes) just before the most recent /// congestion reduction (with fast convergence applied). `None` if no congestion event has /// occurred or Cubic is not in use. Recorded as a stat to approximate a connection's ideal /// congestion window in metrics. pub w_max: Option<f64>, /// The current congestion window size (in bytes). Updated throughout the connection /// lifetime. pub cwnd: Option<usize>,
}
/// Packet types and numbers of the first ECN mark transition between two marks. #[derive(Default, Clone, PartialEq, Eq)] pubstruct EcnTransitions(EnumMap<Ecn, EnumMap<Ecn, Option<(packet::Type, packet::Number)>>>);
impl Deref for EcnTransitions { type Target = EnumMap<Ecn, EnumMap<Ecn, Option<(packet::Type, packet::Number)>>>; fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Debug for EcnTransitions { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for from in Ecn::iter() { // Don't show all-None rows. ifself.0[from].iter().all(|(_, v)| v.is_none()) { continue;
}
write!(f, " First {from:?} ")?; for to in Ecn::iter() { // Don't show transitions that were not recorded. iflet Some(pkt) = self.0[from][to] {
write!(f, "to {to:?} {pkt:?} ")?;
}
}
writeln!(f)?;
}
Ok(())
}
}
/// Received packet counts by DSCP value. #[derive(Default, Clone, PartialEq, Eq)] pubstruct DscpCount(EnumMap<Dscp, usize>);
impl Debug for DscpCount { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for (dscp, count) inself.0 { // Don't show zero counts. if count == 0 { continue;
}
write!(f, "{dscp:?}: {count} ")?;
}
Ok(())
}
}
impl Deref for DscpCount { type Target = EnumMap<Dscp, usize>; fn deref(&self) -> &Self::Target {
&self.0
}
}
/// The QUIC version in use. After the handshake completes this reflects the /// version negotiated via compatible version negotiation (RFC 9368). pub version: Version,
/// Total packets received, including all the bad ones. pub packets_rx: usize, /// Duplicate packets received. pub dups_rx: usize, /// Dropped packets or dropped garbage. pub dropped_rx: usize, /// The number of packet that were saved for later processing. pub saved_datagrams: usize,
/// Total packets sent. pub packets_tx: usize, /// Total number of packets that are declared lost. pub lost: usize, /// Late acknowledgments, for packets that were declared lost already. pub late_ack: usize, /// Acknowledgments for packets that contained data that was marked /// for retransmission when the PTO timer popped. pub pto_ack: usize, /// Number of times we had to drop an unacknowledged ACK range. pub unacked_range_dropped: usize, /// Number of PMTUD probes sent. pub pmtud_tx: usize, /// Number of PMTUD probes ACK'ed. pub pmtud_ack: usize, /// Number of PMTUD probes lost. pub pmtud_lost: usize, /// MTU of the local interface used for the most recent path. pub pmtud_iface_mtu: usize, /// The peer's `max_udp_payload_size` transport parameter. pub pmtud_peer_max_udp_payload: Option<usize>, /// Probed PMTU of the current path. pub pmtud_pmtu: usize,
/// Whether the connection was resumed successfully. pub resumed: bool,
/// The current, estimated round-trip time on the primary path. pub rtt: Duration, /// The current, estimated round-trip time variation on the primary path. pub rttvar: Duration, /// The current minimum RTT observed on the primary path. pub min_rtt: Duration, /// Whether the first RTT sample was guessed from a discarded packet. pub rtt_init_guess: bool,
/// Count PTOs. Single PTOs, 2 PTOs in a row, 3 PTOs in row, etc. are counted /// separately. pub pto_counts: [usize; Self::MAX_PTO_COUNTS],
/// The number of incoming datagrams dropped due to reaching the limit /// of the incoming queue. pub incoming_datagram_dropped: usize,
pub datagram_tx: DatagramStats,
pub cc: CongestionControlStats,
/// ECN path validation count, indexed by validation outcome. pub ecn_path_validation: ecn::ValidationCount, /// ECN counts for outgoing UDP datagrams, recorded locally. For coalesced packets, /// counts increase for all packet types in the coalesced datagram. pub ecn_tx: EcnCount, /// ECN counts for outgoing UDP datagrams, returned by remote through QUIC ACKs. /// /// Note: Given that QUIC ACKs only carry [`Ect0`], [`Ect1`] and [`Ce`], but /// never [`NotEct`], the [`NotEct`] value will always be 0. /// /// See also <https://www.rfc-editor.org/rfc/rfc9000.html#section-19.3.2>. /// /// [`Ect0`]: neqo_common::tos::Ecn::Ect0 /// [`Ect1`]: neqo_common::tos::Ecn::Ect1 /// [`Ce`]: neqo_common::tos::Ecn::Ce /// [`NotEct`]: neqo_common::tos::Ecn::NotEct pub ecn_tx_acked: EcnCount, /// ECN counts for incoming UDP datagrams, read from IP TOS header. For coalesced packets, /// counts increase for all packet types in the coalesced datagram. pub ecn_rx: EcnCount, /// Packet numbers of the first observed (received) ECN mark transition between two marks. pub ecn_last_mark: Option<Ecn>, pub ecn_rx_transition: EcnTransitions,
/// Counters for DSCP values received. pub dscp_rx: DscpCount,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.