mirror of
https://github.com/rustdesk/hbb_common.git
synced 2026-08-27 04:37:35 +00:00
webrtc: report the family of the nominated ICE pair
The label a session is reported under names the transport that won the race, not the family ICE ended up nominating, so a WebRTC session over IPv6 read the same as one over IPv4. Take it from the remote side of the selected pair - the address the peer is actually reached at, which the rendezvous-observed address the session is otherwise identified by cannot report. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019UzcMTdYTEv2QbMHcTSUy3
This commit is contained in:
@@ -122,6 +122,19 @@ impl Stream {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether an established WebRTC transport reaches the peer over IPv6 (used to name the
|
||||
/// transport in the UI). `None` for non-WebRTC transports and before ICE selects a pair —
|
||||
/// every other transport already carries the family in the label it was raced under.
|
||||
#[inline]
|
||||
pub async fn webrtc_remote_ipv6(&self) -> Option<bool> {
|
||||
match self {
|
||||
#[cfg(feature = "webrtc")]
|
||||
Stream::WebRTC(s) => s.is_remote_ipv6().await,
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// DTLS certificate fingerprint for a WebRTC stream (`local`=true for this endpoint's own
|
||||
/// cert, false for the peer's), used to bind the channel to the signed peer identity.
|
||||
/// Returns None for non-WebRTC transports, which authenticate via the secretbox key exchange.
|
||||
|
||||
@@ -1020,6 +1020,20 @@ impl WebRTCStream {
|
||||
)
|
||||
}
|
||||
|
||||
/// Whether the nominated pair reaches the peer over IPv6 — `None` before one is selected.
|
||||
/// The remote side on purpose: it is the address the peer is actually reached at, which the
|
||||
/// rendezvous-observed address the session is otherwise identified by cannot report.
|
||||
pub async fn is_remote_ipv6(&self) -> Option<bool> {
|
||||
let dtls = self.pc.sctp().transport();
|
||||
let pair = dtls.ice_transport().get_selected_candidate_pair().await?;
|
||||
// Same `Display` parse as `is_relayed`, one token over: a side renders as
|
||||
// `(remote) <protocol> <typ> <address>:<port>`, and `protocol` is only udp/tcp, so the
|
||||
// family has to come from the address — an IPv6 literal is the only one with two colons.
|
||||
let pair = pair.to_string();
|
||||
let remote = pair.split(" <-> ").nth(1)?;
|
||||
Some(remote.split_whitespace().nth(3)?.matches(':').count() > 1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_local_ice_rx(&self) -> Option<mpsc::UnboundedReceiver<String>> {
|
||||
self.local_ice_rx.lock().ok().and_then(|mut rx| rx.take())
|
||||
|
||||
Reference in New Issue
Block a user