mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-22 18:16:28 +00:00
net/quinn: Add stats property for connection statistics
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1613>
This commit is contained in:
parent
2b35f009fb
commit
e00ebca63f
6 changed files with 132 additions and 5 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2704,6 +2704,7 @@ dependencies = [
|
|||
"gstreamer-check",
|
||||
"once_cell",
|
||||
"quinn",
|
||||
"quinn-proto",
|
||||
"rcgen",
|
||||
"rustls 0.23.10",
|
||||
"rustls-pemfile 2.1.2",
|
||||
|
|
|
@ -4243,6 +4243,18 @@
|
|||
"type": "guint",
|
||||
"writable": true
|
||||
},
|
||||
"stats": {
|
||||
"blurb": "Connection statistics",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "stats;",
|
||||
"mutable": "null",
|
||||
"readable": true,
|
||||
"type": "GstStructure",
|
||||
"writable": false
|
||||
},
|
||||
"timeout": {
|
||||
"blurb": "Value in seconds to timeout QUIC endpoint requests (0 = No timeout).",
|
||||
"conditionally-available": false,
|
||||
|
@ -4551,6 +4563,18 @@
|
|||
"type": "guint",
|
||||
"writable": true
|
||||
},
|
||||
"stats": {
|
||||
"blurb": "Connection statistics",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "stats;",
|
||||
"mutable": "null",
|
||||
"readable": true,
|
||||
"type": "GstStructure",
|
||||
"writable": false
|
||||
},
|
||||
"timeout": {
|
||||
"blurb": "Value in seconds to timeout QUIC endpoint requests (0 = No timeout).",
|
||||
"conditionally-available": false,
|
||||
|
|
|
@ -17,6 +17,7 @@ once_cell.workspace = true
|
|||
tokio = { version = "1.36.0", default-features = false, features = ["time", "rt-multi-thread"] }
|
||||
futures = "0.3.30"
|
||||
quinn = { version = "0.11.2", default-features = true, features = ["ring"]}
|
||||
quinn-proto = "0.11.2"
|
||||
rustls = { version = "0.23", default-features = false, features = ["ring", "std"]}
|
||||
rustls-pemfile = "2"
|
||||
rustls-pki-types = "1"
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use crate::utils::{
|
||||
client_endpoint, make_socket_addr, server_endpoint, wait, QuinnQuicEndpointConfig, WaitError,
|
||||
CONNECTION_CLOSE_CODE, CONNECTION_CLOSE_MSG,
|
||||
client_endpoint, get_stats, make_socket_addr, server_endpoint, wait, QuinnQuicEndpointConfig,
|
||||
WaitError, CONNECTION_CLOSE_CODE, CONNECTION_CLOSE_MSG,
|
||||
};
|
||||
use crate::{common::*, utils};
|
||||
use bytes::Bytes;
|
||||
|
@ -264,6 +264,11 @@ impl ObjectImpl for QuinnQuicSink {
|
|||
.nick("Datagram Send Buffer Size")
|
||||
.blurb("Maximum number of outgoing application datagram bytes to buffer")
|
||||
.build(),
|
||||
glib::ParamSpecBoxed::builder::<gst::Structure>("stats")
|
||||
.nick("Connection statistics")
|
||||
.blurb("Connection statistics")
|
||||
.read_only()
|
||||
.build()
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -399,6 +404,16 @@ impl ObjectImpl for QuinnQuicSink {
|
|||
"datagram-send-buffer-size" => {
|
||||
(settings.transport_config.datagram_send_buffer_size as u64).to_value()
|
||||
}
|
||||
"stats" => {
|
||||
let state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
State::Started(ref state) => {
|
||||
let connection = state.connection.clone();
|
||||
get_stats(Some(connection)).to_value()
|
||||
}
|
||||
State::Stopped => get_stats(None).to_value(),
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use crate::utils::{
|
||||
client_endpoint, make_socket_addr, server_endpoint, wait, Canceller, QuinnQuicEndpointConfig,
|
||||
WaitError, CONNECTION_CLOSE_CODE, CONNECTION_CLOSE_MSG,
|
||||
client_endpoint, get_stats, make_socket_addr, server_endpoint, wait, Canceller,
|
||||
QuinnQuicEndpointConfig, WaitError, CONNECTION_CLOSE_CODE, CONNECTION_CLOSE_MSG,
|
||||
};
|
||||
use crate::{common::*, utils};
|
||||
use bytes::Bytes;
|
||||
|
@ -273,6 +273,11 @@ impl ObjectImpl for QuinnQuicSrc {
|
|||
.nick("Datagram Send Buffer Size")
|
||||
.blurb("Maximum number of outgoing application datagram bytes to buffer")
|
||||
.build(),
|
||||
glib::ParamSpecBoxed::builder::<gst::Structure>("stats")
|
||||
.nick("Connection statistics")
|
||||
.blurb("Connection statistics")
|
||||
.read_only()
|
||||
.build()
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -418,6 +423,16 @@ impl ObjectImpl for QuinnQuicSrc {
|
|||
"datagram-send-buffer-size" => {
|
||||
(settings.transport_config.datagram_send_buffer_size as u64).to_value()
|
||||
}
|
||||
"stats" => {
|
||||
let state = self.state.lock().unwrap();
|
||||
match *state {
|
||||
State::Started(ref state) => {
|
||||
let connection = state.connection.clone();
|
||||
get_stats(Some(connection)).to_value()
|
||||
}
|
||||
State::Stopped => get_stats(None).to_value(),
|
||||
}
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,10 @@ use gst::ErrorMessage;
|
|||
use once_cell::sync::Lazy;
|
||||
use quinn::{
|
||||
crypto::rustls::QuicClientConfig, crypto::rustls::QuicServerConfig, default_runtime,
|
||||
ClientConfig, Endpoint, EndpointConfig, MtuDiscoveryConfig, ServerConfig, TransportConfig,
|
||||
ClientConfig, Connection, Endpoint, EndpointConfig, MtuDiscoveryConfig, ServerConfig,
|
||||
TransportConfig,
|
||||
};
|
||||
use quinn_proto::{ConnectionStats, FrameStats, PathStats, UdpStats};
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
@ -416,3 +418,72 @@ pub fn client_endpoint(ep_config: &QuinnQuicEndpointConfig) -> Result<Endpoint,
|
|||
|
||||
Ok(endpoint)
|
||||
}
|
||||
|
||||
pub fn get_stats(connection: Option<Connection>) -> gst::Structure {
|
||||
match connection {
|
||||
Some(conn) => {
|
||||
// See quinn_proto::ConnectionStats
|
||||
let stats = conn.stats();
|
||||
let udp_stats = |udp: UdpStats, name: String| -> gst::Structure {
|
||||
gst::Structure::builder(name)
|
||||
.field("datagrams", udp.datagrams)
|
||||
.field("bytes", udp.bytes)
|
||||
.field("ios", udp.ios)
|
||||
.build()
|
||||
};
|
||||
let frame_stats = |frame: FrameStats, name: String| -> gst::Structure {
|
||||
gst::Structure::builder(name)
|
||||
.field("acks", frame.acks)
|
||||
.field("ack-frequency", frame.ack_frequency)
|
||||
.field("crypto", frame.crypto)
|
||||
.field("connection-close", frame.connection_close)
|
||||
.field("data-blocked", frame.data_blocked)
|
||||
.field("datagram", frame.datagram)
|
||||
.field("handshake-done", frame.handshake_done)
|
||||
.field("immediate-ack", frame.immediate_ack)
|
||||
.field("max-data", frame.max_data)
|
||||
.field("max-stream-data", frame.max_stream_data)
|
||||
.field("max-streams-bidi", frame.max_streams_bidi)
|
||||
.field("max-streams-uni", frame.max_streams_uni)
|
||||
.field("new-connection-id", frame.new_connection_id)
|
||||
.field("new-token", frame.new_token)
|
||||
.field("path-challenge", frame.path_challenge)
|
||||
.field("path-response", frame.path_response)
|
||||
.field("ping", frame.ping)
|
||||
.field("reset-stream", frame.reset_stream)
|
||||
.field("retire-connection-id", frame.retire_connection_id)
|
||||
.field("stream-data-blocked", frame.stream_data_blocked)
|
||||
.field("streams-blocked-bidi", frame.streams_blocked_bidi)
|
||||
.field("streams-blocked-uni", frame.streams_blocked_uni)
|
||||
.field("stop-sending", frame.stop_sending)
|
||||
.field("stream", frame.stream)
|
||||
.build()
|
||||
};
|
||||
let path_stats = gst::Structure::builder("path")
|
||||
.field("cwnd", stats.path.cwnd)
|
||||
.field("congestion-events", stats.path.congestion_events)
|
||||
.field("lost-packets", stats.path.lost_packets)
|
||||
.field("lost-bytes", stats.path.lost_bytes)
|
||||
.field("sent-packets", stats.path.sent_packets)
|
||||
.field("sent-plpmtud-probes", stats.path.sent_plpmtud_probes)
|
||||
.field("lost-plpmtud-probes", stats.path.lost_plpmtud_probes)
|
||||
.field("black-holes-detected", stats.path.black_holes_detected)
|
||||
.build();
|
||||
|
||||
gst::Structure::builder("stats")
|
||||
.field("udp-tx", udp_stats(stats.udp_tx, "udp-tx".to_string()))
|
||||
.field("udp-rx", udp_stats(stats.udp_rx, "udp-rx".to_string()))
|
||||
.field("path", path_stats)
|
||||
.field(
|
||||
"frame-tx",
|
||||
frame_stats(stats.frame_tx, "frame-tx".to_string()),
|
||||
)
|
||||
.field(
|
||||
"frame-rx",
|
||||
frame_stats(stats.frame_rx, "frame-rx".to_string()),
|
||||
)
|
||||
.build()
|
||||
}
|
||||
None => gst::Structure::new_empty("stats"),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue