feat(client): retain QUIC datagram diagnostics
Client connection setup already fails when QUIC DATAGRAM is unavailable and clamps the advertised datagram budget before sending hello. Keep that clamped value on ClientSession and expose it through QuicDiagnostics so the Windows client can report the negotiated budget without recomputing handshake details. The value remains owned by client-core because it is derived from the live quinn connection and the configured client budget during handshake. TAP and UI code can sample the snapshot later alongside tunnel counters. Test Plan: - cargo fmt --check - cargo test -p lanparty-client-core - cargo clippy -p lanparty-client-core --all-targets -- -D warnings - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - git diff --check Refs: PLAN.md
This commit is contained in:
@@ -22,7 +22,7 @@ use lanparty_ctrl::{
|
||||
CONTROL_LENGTH_PREFIX_LEN, ControlMessage, EndpointHello, MAX_CONTROL_MESSAGE_LEN, RELAY_ALPN,
|
||||
RoomCode, ServerWelcome, decode_control_frame, encode_control_message,
|
||||
};
|
||||
use lanparty_obs::TunnelStats;
|
||||
use lanparty_obs::{QuicDiagnostics, TunnelStats};
|
||||
use lanparty_proto::{EthernetFrame, FrameType, MacAddr, decode_datagram, encode_datagram};
|
||||
use quinn::{ClientConfig, Endpoint, crypto::rustls::QuicClientConfig};
|
||||
use rustls::pki_types::CertificateDer;
|
||||
@@ -214,6 +214,7 @@ pub struct ClientSession {
|
||||
connection: quinn::Connection,
|
||||
config: ClientSessionConfig,
|
||||
welcome: ServerWelcome,
|
||||
quic_max_datagram_size: u16,
|
||||
stats: Arc<ClientTunnelStats>,
|
||||
}
|
||||
|
||||
@@ -246,6 +247,16 @@ impl ClientSession {
|
||||
&self.welcome
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn quic_max_datagram_size(&self) -> u16 {
|
||||
self.quic_max_datagram_size
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn quic_diagnostics(&self) -> QuicDiagnostics {
|
||||
QuicDiagnostics::new(true, Some(self.quic_max_datagram_size))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn relay_io(&self) -> ClientRelayIo {
|
||||
ClientRelayIo::new(
|
||||
@@ -415,9 +426,8 @@ pub async fn connect_client(config: ClientSessionConfig) -> Result<ClientSession
|
||||
let peer_datagram_size = connection
|
||||
.max_datagram_size()
|
||||
.context("relay did not negotiate QUIC DATAGRAM support")?;
|
||||
let hello_datagram_size = usize::from(config.max_datagram_size())
|
||||
.min(peer_datagram_size)
|
||||
.min(usize::from(u16::MAX)) as u16;
|
||||
let hello_datagram_size =
|
||||
negotiated_quic_datagram_size(config.max_datagram_size(), peer_datagram_size);
|
||||
let hello = EndpointHello::client(
|
||||
config.room().clone(),
|
||||
config.virtual_mac(),
|
||||
@@ -432,6 +442,7 @@ pub async fn connect_client(config: ClientSessionConfig) -> Result<ClientSession
|
||||
connection,
|
||||
config,
|
||||
welcome,
|
||||
quic_max_datagram_size: hello_datagram_size,
|
||||
stats: Arc::default(),
|
||||
}),
|
||||
ControlMessage::Reject(reject) => bail!(
|
||||
@@ -443,6 +454,11 @@ pub async fn connect_client(config: ClientSessionConfig) -> Result<ClientSession
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn negotiated_quic_datagram_size(configured: u16, peer: usize) -> u16 {
|
||||
usize::from(configured).min(peer).min(usize::from(u16::MAX)) as u16
|
||||
}
|
||||
|
||||
fn relay_client_config(relay_ca_cert_der: &[u8]) -> Result<ClientConfig> {
|
||||
let mut roots = rustls::RootCertStore::empty();
|
||||
roots
|
||||
@@ -550,6 +566,16 @@ mod tests {
|
||||
assert!(identity.virtual_mac().is_valid_client_identity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clamps_negotiated_quic_datagram_size() {
|
||||
assert_eq!(negotiated_quic_datagram_size(1400, 1350), 1350);
|
||||
assert_eq!(negotiated_quic_datagram_size(1300, 1400), 1300);
|
||||
assert_eq!(
|
||||
negotiated_quic_datagram_size(u16::MAX, usize::MAX),
|
||||
u16::MAX
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn identity_store_creates_and_reuses_mac() {
|
||||
let path = unique_temp_identity_path();
|
||||
@@ -648,6 +674,12 @@ mod tests {
|
||||
);
|
||||
assert_eq!(client.welcome().room_id(), 7);
|
||||
assert_eq!(client.welcome().peer_id(), 2);
|
||||
assert!(client.quic_max_datagram_size() <= 1400);
|
||||
assert!(client.quic_diagnostics().datagram_supported());
|
||||
assert_eq!(
|
||||
client.quic_diagnostics().max_datagram_size(),
|
||||
Some(client.quic_max_datagram_size())
|
||||
);
|
||||
let relay_io = client.relay_io();
|
||||
assert_eq!(relay_io.welcome().peer_id(), 2);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user