From 0ae15b11784cd7b709fb298881ceab8ad0327c6e Mon Sep 17 00:00:00 2001 From: yngrtc Date: Mon, 11 Mar 2024 13:38:26 -0700 Subject: [PATCH] fix ConnectionState::Failed --- rtc-ice/examples/ping_pong.rs | 6 +++++- rtc-ice/src/agent/mod.rs | 27 +++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/rtc-ice/examples/ping_pong.rs b/rtc-ice/examples/ping_pong.rs index 72842f1..f99ee6c 100644 --- a/rtc-ice/examples/ping_pong.rs +++ b/rtc-ice/examples/ping_pong.rs @@ -162,7 +162,11 @@ async fn main() -> Result<(), Error> { let port = if cli.controlling { 4000 } else { 4001 }; let udp_socket = UdpSocket::bind(("0.0.0.0", port)).await?; - let mut ice_agent = Agent::new(AgentConfig::default())?; + let mut ice_agent = Agent::new(AgentConfig { + disconnected_timeout: Some(Duration::from_secs(5)), + failed_timeout: Some(Duration::from_secs(5)), + ..Default::default() + })?; let client = Arc::new(Client::new()); diff --git a/rtc-ice/src/agent/mod.rs b/rtc-ice/src/agent/mod.rs index 83adf13..4392f24 100644 --- a/rtc-ice/src/agent/mod.rs +++ b/rtc-ice/src/agent/mod.rs @@ -127,6 +127,7 @@ pub struct Agent { pub(crate) keepalive_interval: Duration, // How often should we run our internal taskLoop to check for state changes when connecting pub(crate) check_interval: Duration, + pub(crate) checking_duration: Instant, pub(crate) last_checking_time: Instant, pub(crate) candidate_types: Vec, @@ -239,6 +240,7 @@ impl Agent { } else { config.check_interval }, + checking_duration: Instant::now(), last_checking_time: Instant::now(), last_connection_state: ConnectionState::Unspecified, @@ -421,6 +423,7 @@ impl Agent { /// Cleans up the Agent. pub fn close(&mut self) -> Result<()> { + self.set_selected_pair(None); self.delete_all_candidates(false); self.update_connection_state(ConnectionState::Closed); @@ -520,12 +523,12 @@ impl Agent { if self.connection_state == ConnectionState::Checking { // We have just entered checking for the first time so update our checking timer if self.last_connection_state != self.connection_state { - self.last_checking_time = now; + self.checking_duration = now; } // We have been in checking longer then Disconnect+Failed timeout, set the connection to Failed if now - .checked_duration_since(self.last_checking_time) + .checked_duration_since(self.checking_duration) .unwrap_or_else(|| Duration::from_secs(0)) > self.disconnected_timeout + self.failed_timeout { @@ -545,6 +548,7 @@ impl Agent { if self.connection_state != new_state { // Connection has gone to failed, release all gathered candidates if new_state == ConnectionState::Failed { + self.set_selected_pair(None); self.delete_all_candidates(false); } @@ -661,13 +665,14 @@ impl Agent { }; if valid { - // Only allow transitions to failed if a.failedTimeout is non-zero - if self.failed_timeout != Duration::from_secs(0) { - self.failed_timeout += self.disconnected_timeout; + // Only allow transitions to fail if a.failedTimeout is non-zero + let mut total_time_to_failure = self.failed_timeout; + if total_time_to_failure != Duration::from_secs(0) { + total_time_to_failure += self.disconnected_timeout; } - if self.failed_timeout != Duration::from_secs(0) - && disconnected_time > self.failed_timeout + if total_time_to_failure != Duration::from_secs(0) + && disconnected_time > total_time_to_failure { self.update_connection_state(ConnectionState::Failed); } else if self.disconnected_timeout != Duration::from_secs(0) @@ -833,12 +838,14 @@ impl Agent { } *pending_binding_requests = temp; - let bind_requests_removed = initial_size - pending_binding_requests.len(); + let bind_requests_remaining = pending_binding_requests.len(); + let bind_requests_removed = initial_size - bind_requests_remaining; if bind_requests_removed > 0 { trace!( - "[{}]: Discarded {} binding requests because they expired", + "[{}]: Discarded {} binding requests because they expired, still {} remaining", self.get_name(), - bind_requests_removed + bind_requests_removed, + bind_requests_remaining, ); } }