From ad40081a5d705ab0f7d771df17bbc132baca357f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Monnom?= Date: Thu, 2 Nov 2023 23:11:49 -0700 Subject: [PATCH] fix: invalid stats panic (#231) --- libwebrtc/src/native/peer_connection.rs | 5 +++++ libwebrtc/src/native/rtp_receiver.rs | 5 +++++ libwebrtc/src/native/rtp_sender.rs | 5 +++++ livekit/src/room/track/local_audio_track.rs | 2 +- livekit/src/room/track/local_track.rs | 14 +++++++++++++- livekit/src/room/track/local_video_track.rs | 2 +- livekit/src/room/track/mod.rs | 10 ---------- livekit/src/room/track/remote_audio_track.rs | 2 +- livekit/src/room/track/remote_track.rs | 10 +++++++++- livekit/src/room/track/remote_video_track.rs | 2 +- 10 files changed, 41 insertions(+), 16 deletions(-) diff --git a/libwebrtc/src/native/peer_connection.rs b/libwebrtc/src/native/peer_connection.rs index 9c751dad6..9346b418d 100644 --- a/libwebrtc/src/native/peer_connection.rs +++ b/libwebrtc/src/native/peer_connection.rs @@ -452,6 +452,11 @@ impl PeerConnection { .downcast::, RtcError>>>() .unwrap(); + if stats.is_empty() { + let _ = tx.send(Ok(vec![])); + return; + } + // Unwrap because it should not happens let vec = serde_json::from_str(&stats).unwrap(); let _ = tx.send(Ok(vec)); diff --git a/libwebrtc/src/native/rtp_receiver.rs b/libwebrtc/src/native/rtp_receiver.rs index ce59e92b4..c8e39d9a6 100644 --- a/libwebrtc/src/native/rtp_receiver.rs +++ b/libwebrtc/src/native/rtp_receiver.rs @@ -46,6 +46,11 @@ impl RtpReceiver { .downcast::, RtcError>>>() .unwrap(); + if stats.is_empty() { + let _ = tx.send(Ok(vec![])); + return; + } + // Unwrap because it should not happens let vec = serde_json::from_str(&stats).unwrap(); let _ = tx.send(Ok(vec)); diff --git a/libwebrtc/src/native/rtp_sender.rs b/libwebrtc/src/native/rtp_sender.rs index fcb7b06f4..506c93433 100644 --- a/libwebrtc/src/native/rtp_sender.rs +++ b/libwebrtc/src/native/rtp_sender.rs @@ -46,6 +46,11 @@ impl RtpSender { .downcast::, RtcError>>>() .unwrap(); + if stats.is_empty() { + let _ = tx.send(Ok(vec![])); + return; + } + // Unwrap because it should not happens let vec = serde_json::from_str(&stats).unwrap(); let _ = tx.send(Ok(vec)); diff --git a/livekit/src/room/track/local_audio_track.rs b/livekit/src/room/track/local_audio_track.rs index d3990e519..d37f538c9 100644 --- a/livekit/src/room/track/local_audio_track.rs +++ b/livekit/src/room/track/local_audio_track.rs @@ -121,7 +121,7 @@ impl LocalAudioTrack { } pub async fn get_stats(&self) -> RoomResult> { - super::get_stats(&self.inner).await + super::local_track::get_stats(&self.inner).await } pub(crate) fn on_muted(&self, f: impl Fn(Track) + Send + 'static) { diff --git a/livekit/src/room/track/local_track.rs b/livekit/src/room/track/local_track.rs index 8ca4f1a82..1fed93559 100644 --- a/livekit/src/room/track/local_track.rs +++ b/livekit/src/room/track/local_track.rs @@ -12,9 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::track_dispatch; +use std::sync::Arc; + +use super::{track_dispatch, TrackInner}; use crate::prelude::*; use libwebrtc::prelude::*; +use libwebrtc::stats::RtcStats; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; @@ -61,3 +64,12 @@ impl TryFrom for LocalTrack { } } } + +pub(super) async fn get_stats(inner: &Arc) -> RoomResult> { + let transceiver = inner.info.read().transceiver.clone(); + let Some(transceiver) = transceiver.as_ref() else { + return Err(RoomError::Internal("no transceiver found for track".into())); + }; + + Ok(transceiver.sender().get_stats().await?) +} diff --git a/livekit/src/room/track/local_video_track.rs b/livekit/src/room/track/local_video_track.rs index 3bd8abab0..9202cde0e 100644 --- a/livekit/src/room/track/local_video_track.rs +++ b/livekit/src/room/track/local_video_track.rs @@ -121,7 +121,7 @@ impl LocalVideoTrack { } pub async fn get_stats(&self) -> RoomResult> { - super::get_stats(&self.inner).await + super::local_track::get_stats(&self.inner).await } pub(crate) fn on_muted(&self, f: impl Fn(Track) + Send + 'static) { diff --git a/livekit/src/room/track/mod.rs b/livekit/src/room/track/mod.rs index 770e86b3c..7954b7d3d 100644 --- a/livekit/src/room/track/mod.rs +++ b/livekit/src/room/track/mod.rs @@ -173,16 +173,6 @@ pub(super) fn new_inner( } } -pub(super) async fn get_stats(inner: &Arc) -> RoomResult> { - let transceiver = inner.info.read().transceiver.clone(); - let Some(transceiver) = transceiver.as_ref() else { - return Err(RoomError::Internal("no transceiver found for track".into())); - }; - - let rtp_receiver = transceiver.receiver(); - Ok(rtp_receiver.get_stats().await?) -} - /// This is only called for local tracks pub(super) fn set_muted(inner: &Arc, track: &Track, muted: bool) { let info = inner.info.read(); diff --git a/livekit/src/room/track/remote_audio_track.rs b/livekit/src/room/track/remote_audio_track.rs index 9672615b7..9a5e4965f 100644 --- a/livekit/src/room/track/remote_audio_track.rs +++ b/livekit/src/room/track/remote_audio_track.rs @@ -91,7 +91,7 @@ impl RemoteAudioTrack { } pub async fn get_stats(&self) -> RoomResult> { - super::get_stats(&self.inner).await + super::remote_track::get_stats(&self.inner).await } pub(crate) fn on_muted(&self, f: impl Fn(Track) + Send + 'static) { diff --git a/livekit/src/room/track/remote_track.rs b/livekit/src/room/track/remote_track.rs index 242625365..62fb3955f 100644 --- a/livekit/src/room/track/remote_track.rs +++ b/livekit/src/room/track/remote_track.rs @@ -16,7 +16,6 @@ use super::track_dispatch; use super::TrackInner; use crate::prelude::*; use libwebrtc::prelude::*; -use libwebrtc::stats::InboundRtpStats; use libwebrtc::stats::RtcStats; use livekit_protocol as proto; use livekit_protocol::enum_dispatch; @@ -40,6 +39,15 @@ impl RemoteTrack { } } +pub(super) async fn get_stats(inner: &Arc) -> RoomResult> { + let transceiver = inner.info.read().transceiver.clone(); + let Some(transceiver) = transceiver.as_ref() else { + return Err(RoomError::Internal("no transceiver found for track".into())); + }; + + Ok(transceiver.receiver().get_stats().await?) +} + pub(super) fn update_info(inner: &Arc, track: &Track, new_info: proto::TrackInfo) { super::update_info(inner, track, new_info.clone()); super::set_muted(inner, track, new_info.muted); diff --git a/livekit/src/room/track/remote_video_track.rs b/livekit/src/room/track/remote_video_track.rs index e146c91ab..f051ade49 100644 --- a/livekit/src/room/track/remote_video_track.rs +++ b/livekit/src/room/track/remote_video_track.rs @@ -92,7 +92,7 @@ impl RemoteVideoTrack { } pub async fn get_stats(&self) -> RoomResult> { - super::get_stats(&self.inner).await + super::remote_track::get_stats(&self.inner).await } pub(crate) fn on_muted(&self, f: impl Fn(Track) + Send + 'static) {