diff --git a/rtc-ice/src/agent/agent_selector.rs b/rtc-ice/src/agent/agent_selector.rs index eb787bb..d0dd508 100644 --- a/rtc-ice/src/agent/agent_selector.rs +++ b/rtc-ice/src/agent/agent_selector.rs @@ -13,29 +13,29 @@ use crate::candidate::{candidate_pair::*, *}; trait ControllingSelector { fn start(&mut self); fn contact_candidates(&mut self); - fn ping_candidate(&mut self, local: usize, remote: usize); + fn ping_candidate(&mut self, local_index: usize, remote_index: usize); fn handle_success_response( &mut self, m: &Message, - local: usize, - remote: usize, + local_index: usize, + remote_index: usize, remote_addr: SocketAddr, ); - fn handle_binding_request(&mut self, m: &Message, local: usize, remote: usize); + fn handle_binding_request(&mut self, m: &Message, local_index: usize, remote_index: usize); } trait ControlledSelector { fn start(&mut self); fn contact_candidates(&mut self); - fn ping_candidate(&mut self, local: usize, remote: usize); + fn ping_candidate(&mut self, local_index: usize, remote_index: usize); fn handle_success_response( &mut self, m: &Message, - local: usize, - remote: usize, + local_index: usize, + remote_index: usize, remote_addr: SocketAddr, ); - fn handle_binding_request(&mut self, m: &Message, local: usize, remote: usize); + fn handle_binding_request(&mut self, m: &Message, local_index: usize, remote_index: usize); } impl Agent { @@ -99,11 +99,11 @@ impl Agent { } else { log::trace!( "ping STUN (nominate candidate pair from {} to {}", - self.local_candidates[pair.local], - self.remote_candidates[pair.remote], + self.local_candidates[pair.local_index], + self.remote_candidates[pair.remote_index], ); - let local = pair.local; - let remote = pair.remote; + let local = pair.local_index; + let remote = pair.remote_index; Some((msg, local, remote)) } } else { @@ -132,33 +132,50 @@ impl Agent { } } - pub(crate) fn ping_candidate(&mut self, local: usize, remote: usize) { + pub(crate) fn ping_candidate(&mut self, local_index: usize, remote_index: usize) { if self.is_controlling { - ControllingSelector::ping_candidate(self, local, remote); + ControllingSelector::ping_candidate(self, local_index, remote_index); } else { - ControlledSelector::ping_candidate(self, local, remote); + ControlledSelector::ping_candidate(self, local_index, remote_index); } } pub(crate) fn handle_success_response( &mut self, m: &Message, - local: usize, - remote: usize, + local_index: usize, + remote_index: usize, remote_addr: SocketAddr, ) { if self.is_controlling { - ControllingSelector::handle_success_response(self, m, local, remote, remote_addr); + ControllingSelector::handle_success_response( + self, + m, + local_index, + remote_index, + remote_addr, + ); } else { - ControlledSelector::handle_success_response(self, m, local, remote, remote_addr); + ControlledSelector::handle_success_response( + self, + m, + local_index, + remote_index, + remote_addr, + ); } } - pub(crate) fn handle_binding_request(&mut self, m: &Message, local: usize, remote: usize) { + pub(crate) fn handle_binding_request( + &mut self, + m: &Message, + local_index: usize, + remote_index: usize, + ) { if self.is_controlling { - ControllingSelector::handle_binding_request(self, m, local, remote); + ControllingSelector::handle_binding_request(self, m, local_index, remote_index); } else { - ControlledSelector::handle_binding_request(self, m, local, remote); + ControlledSelector::handle_binding_request(self, m, local_index, remote_index); } } } @@ -189,7 +206,8 @@ impl ControllingSelector for Agent { let has_nominated_pair = if let Some(pair_index) = self.get_best_valid_candidate_pair() { let p = self.candidate_pairs[pair_index]; - self.is_nominatable(p.local, true) && self.is_nominatable(p.remote, false) + self.is_nominatable(p.local_index, true) + && self.is_nominatable(p.remote_index, false) } else { false }; @@ -199,8 +217,8 @@ impl ControllingSelector for Agent { let p = &mut self.candidate_pairs[pair_index]; log::trace!( "Nominatable pair found, nominating ({}, {})", - self.local_candidates[p.local], - self.remote_candidates[p.remote], + self.local_candidates[p.local_index], + self.remote_candidates[p.remote_index], ); p.nominated = true; self.nominated_pair = Some(pair_index); @@ -213,7 +231,7 @@ impl ControllingSelector for Agent { } } - fn ping_candidate(&mut self, local: usize, remote: usize) { + fn ping_candidate(&mut self, local_index: usize, remote_index: usize) { let (msg, result) = { let ufrag_pwd = &self.ufrag_pwd; let username = ufrag_pwd.remote_ufrag.clone() + ":" + ufrag_pwd.local_ufrag.as_str(); @@ -223,7 +241,7 @@ impl ControllingSelector for Agent { Box::new(TransactionId::new()), Box::new(Username::new(ATTR_USERNAME, username)), Box::new(AttrControlling(self.tie_breaker)), - Box::new(PriorityAttr(self.local_candidates[local].priority())), + Box::new(PriorityAttr(self.local_candidates[local_index].priority())), Box::new(MessageIntegrity::new_short_term_integrity( ufrag_pwd.remote_pwd.clone(), )), @@ -235,15 +253,15 @@ impl ControllingSelector for Agent { if let Err(err) = result { log::error!("{}", err); } else { - self.send_binding_request(&msg, local, remote); + self.send_binding_request(&msg, local_index, remote_index); } } fn handle_success_response( &mut self, m: &Message, - local: usize, - remote: usize, + local_index: usize, + remote_index: usize, remote_addr: SocketAddr, ) { if let Some(pending_request) = self.handle_inbound_binding_success(m.transaction_id) { @@ -252,18 +270,18 @@ impl ControllingSelector for Agent { // Assert that NAT is not symmetric // https://tools.ietf.org/html/rfc8445#section-7.2.5.2.1 if transaction_addr != remote_addr { - log::debug!("discard message: transaction source and destination does not match expected({}), actual({})", transaction_addr, remote); + log::debug!("discard message: transaction source and destination does not match expected({}), actual({})", transaction_addr, remote_index); return; } log::trace!( "inbound STUN (SuccessResponse) from {} to {}", - remote, - local + remote_index, + local_index ); let selected_pair_is_none = self.get_selected_pair().is_none(); - if let Some(pair_index) = self.find_pair(local, remote) { + if let Some(pair_index) = self.find_pair(local_index, remote_index) { let p = &mut self.candidate_pairs[pair_index]; p.state = CandidatePairState::Succeeded; log::trace!( @@ -283,17 +301,17 @@ impl ControllingSelector for Agent { } else { log::warn!( "discard message from ({}), unknown TransactionID 0x{:?}", - remote, + remote_index, m.transaction_id ); } } - fn handle_binding_request(&mut self, m: &Message, local: usize, remote: usize) { - self.send_binding_success(m, local, remote); + fn handle_binding_request(&mut self, m: &Message, local_index: usize, remote_index: usize) { + self.send_binding_success(m, local_index, remote_index); log::trace!("controllingSelector: sendBindingSuccess"); - if let Some(pair_index) = self.find_pair(local, remote) { + if let Some(pair_index) = self.find_pair(local_index, remote_index) { let p = &self.candidate_pairs[pair_index]; let nominated_pair_is_none = self.nominated_pair.is_none(); @@ -314,11 +332,11 @@ impl ControllingSelector for Agent { best_pair_index ); if best_pair_index == pair_index - && self.is_nominatable(p.local, true) - && self.is_nominatable(p.remote, false) + && self.is_nominatable(p.local_index, true) + && self.is_nominatable(p.remote_index, false) { log::trace!("The candidate ({}, {}) is the best candidate available, marking it as nominated", - p.local, p.remote); + p.local_index, p.remote_index); self.nominated_pair = Some(pair_index); self.nominate_pair(); } @@ -328,7 +346,7 @@ impl ControllingSelector for Agent { } } else { log::trace!("controllingSelector: addPair"); - self.add_pair(local, remote); + self.add_pair(local_index, remote_index); } } } @@ -350,7 +368,7 @@ impl ControlledSelector for Agent { } } - fn ping_candidate(&mut self, local: usize, remote: usize) { + fn ping_candidate(&mut self, local_index: usize, remote_index: usize) { let (msg, result) = { let ufrag_pwd = &self.ufrag_pwd; let username = ufrag_pwd.remote_ufrag.clone() + ":" + ufrag_pwd.local_ufrag.as_str(); @@ -360,7 +378,7 @@ impl ControlledSelector for Agent { Box::new(TransactionId::new()), Box::new(Username::new(ATTR_USERNAME, username)), Box::new(AttrControlled(self.tie_breaker)), - Box::new(PriorityAttr(self.local_candidates[local].priority())), + Box::new(PriorityAttr(self.local_candidates[local_index].priority())), Box::new(MessageIntegrity::new_short_term_integrity( ufrag_pwd.remote_pwd.clone(), )), @@ -372,15 +390,15 @@ impl ControlledSelector for Agent { if let Err(err) = result { log::error!("{}", err); } else { - self.send_binding_request(&msg, local, remote); + self.send_binding_request(&msg, local_index, remote_index); } } fn handle_success_response( &mut self, m: &Message, - local: usize, - remote: usize, + local_index: usize, + remote_index: usize, remote_addr: SocketAddr, ) { // https://tools.ietf.org/html/rfc8445#section-7.3.1.5 @@ -395,17 +413,17 @@ impl ControlledSelector for Agent { // Assert that NAT is not symmetric // https://tools.ietf.org/html/rfc8445#section-7.2.5.2.1 if transaction_addr != remote_addr { - log::debug!("discard message: transaction source and destination does not match expected({}), actual({})", transaction_addr, remote); + log::debug!("discard message: transaction source and destination does not match expected({}), actual({})", transaction_addr, remote_index); return; } log::trace!( "inbound STUN (SuccessResponse) from {} to {}", - remote, - local + remote_index, + local_index ); - if let Some(pair_index) = self.find_pair(local, remote) { + if let Some(pair_index) = self.find_pair(local_index, remote_index) { let p = &mut self.candidate_pairs[pair_index]; p.state = CandidatePairState::Succeeded; log::trace!("Found valid candidate pair: {}", *p); @@ -416,18 +434,18 @@ impl ControlledSelector for Agent { } else { log::warn!( "discard message from ({}), unknown TransactionID 0x{:?}", - remote, + remote_index, m.transaction_id ); } } - fn handle_binding_request(&mut self, m: &Message, local: usize, remote: usize) { - if self.find_pair(local, remote).is_none() { - self.add_pair(local, remote); + fn handle_binding_request(&mut self, m: &Message, local_index: usize, remote_index: usize) { + if self.find_pair(local_index, remote_index).is_none() { + self.add_pair(local_index, remote_index); } - if let Some(pair_index) = self.find_pair(local, remote) { + if let Some(pair_index) = self.find_pair(local_index, remote_index) { let p = &self.candidate_pairs[pair_index]; let use_candidate = m.contains(ATTR_USE_CANDIDATE); if use_candidate { @@ -441,7 +459,7 @@ impl ControlledSelector for Agent { if self.get_selected_pair().is_none() { self.set_selected_pair(Some(pair_index)); } - self.send_binding_success(m, local, remote); + self.send_binding_success(m, local_index, remote_index); } else { // If the received Binding request triggered a new check to be // enqueued in the triggered-check queue (Section 7.3.1.4), once the @@ -451,11 +469,11 @@ impl ControlledSelector for Agent { // MUST remove the candidate pair from the valid list, set the // candidate pair state to Failed, and set the checklist state to // Failed. - self.ping_candidate(local, remote); + self.ping_candidate(local_index, remote_index); } } else { - self.send_binding_success(m, local, remote); - self.ping_candidate(local, remote); + self.send_binding_success(m, local_index, remote_index); + self.ping_candidate(local_index, remote_index); } } } diff --git a/rtc-ice/src/agent/agent_stats.rs b/rtc-ice/src/agent/agent_stats.rs index 2c5d011..2874857 100644 --- a/rtc-ice/src/agent/agent_stats.rs +++ b/rtc-ice/src/agent/agent_stats.rs @@ -205,8 +205,8 @@ impl Agent { for cp in &self.candidate_pairs { let stat = CandidatePairStats { timestamp: Instant::now(), - local_candidate_id: self.local_candidates[cp.local].id(), - remote_candidate_id: self.remote_candidates[cp.remote].id(), + local_candidate_id: self.local_candidates[cp.local_index].id(), + remote_candidate_id: self.remote_candidates[cp.remote_index].id(), state: cp.state, nominated: cp.nominated, ..CandidatePairStats::default() diff --git a/rtc-ice/src/agent/mod.rs b/rtc-ice/src/agent/mod.rs index dbbd4d6..14f7d41 100644 --- a/rtc-ice/src/agent/mod.rs +++ b/rtc-ice/src/agent/mod.rs @@ -572,8 +572,8 @@ impl Agent { p.state = CandidatePairState::Failed; } else { p.binding_request_count += 1; - let local = p.local; - let remote = p.remote; + let local = p.local_index; + let remote = p.remote_index; pairs.push((local, remote)); } } @@ -584,20 +584,20 @@ impl Agent { } } - pub(crate) fn add_pair(&mut self, local: usize, remote: usize) { + pub(crate) fn add_pair(&mut self, local_index: usize, remote_index: usize) { let p = CandidatePair::new( - local, - remote, - self.local_candidates[local].priority(), - self.remote_candidates[remote].priority(), + local_index, + remote_index, + self.local_candidates[local_index].priority(), + self.remote_candidates[remote_index].priority(), self.is_controlling, ); self.candidate_pairs.push(p); } - pub(crate) fn find_pair(&self, local: usize, remote: usize) -> Option { + pub(crate) fn find_pair(&self, local_index: usize, remote_index: usize) -> Option { for (index, p) in self.candidate_pairs.iter().enumerate() { - if p.local == local && p.remote == remote { + if p.local_index == local_index && p.remote_index == remote_index { return Some(index); } } @@ -611,10 +611,10 @@ impl Agent { self.selected_pair.as_ref().map_or_else( || (false, Duration::from_secs(0)), |&pair_index| { - let remote = self.candidate_pairs[pair_index].remote; + let remote_index = self.candidate_pairs[pair_index].remote_index; let disconnected_time = Instant::now() - .duration_since(self.remote_candidates[remote].last_received()); + .duration_since(self.remote_candidates[remote_index].last_received()); (true, disconnected_time) }, ) @@ -646,20 +646,21 @@ impl Agent { /// if no packet has been sent on that pair in the last keepaliveInterval. /// Note: the caller should hold the agent lock. pub(crate) fn check_keepalive(&mut self) { - let (local, remote) = { + let (local_index, remote_index) = { self.selected_pair .as_ref() .map_or((None, None), |&pair_index| { let p = &self.candidate_pairs[pair_index]; - (Some(p.local), Some(p.remote)) + (Some(p.local_index), Some(p.remote_index)) }) }; - if let (Some(local), Some(remote)) = (local, remote) { - let last_sent = Instant::now().duration_since(self.local_candidates[local].last_sent()); + if let (Some(local_index), Some(remote_index)) = (local_index, remote_index) { + let last_sent = + Instant::now().duration_since(self.local_candidates[local_index].last_sent()); let last_received = - Instant::now().duration_since(self.remote_candidates[remote].last_received()); + Instant::now().duration_since(self.remote_candidates[remote_index].last_received()); if (self.keepalive_interval != Duration::from_secs(0)) && ((last_sent > self.keepalive_interval) @@ -667,7 +668,7 @@ impl Agent { { // we use binding request instead of indication to support refresh consent schemas // see https://tools.ietf.org/html/rfc7675 - self.ping_candidate(local, remote); + self.ping_candidate(local_index, remote_index); } } } @@ -710,12 +711,17 @@ impl Agent { None } - pub(crate) fn send_binding_request(&mut self, m: &Message, local: usize, remote: usize) { + pub(crate) fn send_binding_request( + &mut self, + m: &Message, + local_index: usize, + remote_index: usize, + ) { log::trace!( "[{}]: ping STUN from {} to {}", self.get_name(), - local, - remote + local_index, + remote_index ); self.invalidate_pending_binding_requests(Instant::now()); @@ -723,16 +729,21 @@ impl Agent { self.pending_binding_requests.push(BindingRequest { timestamp: Instant::now(), transaction_id: m.transaction_id, - destination: self.remote_candidates[remote].addr(), + destination: self.remote_candidates[remote_index].addr(), is_use_candidate: m.contains(ATTR_USE_CANDIDATE), }); } - self.send_stun(m, local, remote); + self.send_stun(m, local_index, remote_index); } - pub(crate) fn send_binding_success(&mut self, m: &Message, local: usize, remote: usize) { - let addr = self.remote_candidates[remote].addr(); + pub(crate) fn send_binding_success( + &mut self, + m: &Message, + local_index: usize, + remote_index: usize, + ) { + let addr = self.remote_candidates[remote_index].addr(); let (ip, port) = (addr.ip(), addr.port()); let local_pwd = self.ufrag_pwd.local_pwd.clone(); @@ -752,12 +763,12 @@ impl Agent { log::warn!( "[{}]: Failed to handle inbound ICE from: {} to: {} error: {}", self.get_name(), - local, - remote, + local_index, + remote_index, err ); } else { - self.send_stun(&out, local, remote); + self.send_stun(&out, local_index, remote_index); } } @@ -813,7 +824,7 @@ impl Agent { pub(crate) fn handle_inbound( &mut self, m: &mut Message, - local: usize, + local_index: usize, remote_addr: SocketAddr, ) { if m.typ.method != METHOD_BINDING @@ -825,7 +836,7 @@ impl Agent { "[{}]: unhandled STUN from {} to {} class({}) method({})", self.get_name(), remote_addr, - local, + local_index, m.typ.class, m.typ.method ); @@ -871,8 +882,8 @@ impl Agent { } } - if let Some(remote) = &remote_candidate_index { - self.handle_success_response(m, local, *remote, remote_addr); + if let Some(remote_index) = &remote_candidate_index { + self.handle_success_response(m, local_index, *remote_index, remote_addr); } else { log::warn!( "[{}]: discard success message from ({}), no such remote", @@ -949,16 +960,16 @@ impl Agent { "[{}]: inbound STUN (Request) from {} to {}", self.get_name(), remote_addr, - local + local_index ); - if let Some(remote) = &remote_candidate_index { - self.handle_binding_request(m, local, *remote); + if let Some(remote_index) = &remote_candidate_index { + self.handle_binding_request(m, local_index, *remote_index); } } - if let Some(remote) = remote_candidate_index { - self.remote_candidates[remote].seen(false); + if let Some(remote_index) = remote_candidate_index { + self.remote_candidates[remote_index].seen(false); } } @@ -966,15 +977,15 @@ impl Agent { // remote candidate. pub(crate) fn validate_non_stun_traffic(&mut self, remote_addr: SocketAddr) -> bool { self.find_remote_candidate(remote_addr) - .map_or(false, |remote| { - self.remote_candidates[remote].seen(false); + .map_or(false, |remote_index| { + self.remote_candidates[remote_index].seen(false); true }) } - pub(crate) fn send_stun(&mut self, msg: &Message, local: usize, remote: usize) { - let remote_addr = self.remote_candidates[remote].addr(); - if let Err(err) = self.local_candidates[local].write(&msg.raw, remote_addr) { + pub(crate) fn send_stun(&mut self, msg: &Message, local_index: usize, remote_index: usize) { + let remote_addr = self.remote_candidates[remote_index].addr(); + if let Err(err) = self.local_candidates[local_index].write(&msg.raw, remote_addr) { log::trace!( "[{}]: failed to send STUN message: {}", self.get_name(), @@ -1117,7 +1128,7 @@ impl Agent { fn handle_inbound_candidate_msg( &mut self, - local: usize, + local_index: usize, buf: &[u8], src_addr: SocketAddr, addr: SocketAddr, @@ -1139,7 +1150,7 @@ impl Agent { err ); } else { - self.handle_inbound(&mut m, local, src_addr); + self.handle_inbound(&mut m, local_index, src_addr); } } else if !self.validate_non_stun_traffic(src_addr) { log::warn!( diff --git a/rtc-ice/src/candidate/candidate_pair.rs b/rtc-ice/src/candidate/candidate_pair.rs index 1ed4da8..bf09de7 100644 --- a/rtc-ice/src/candidate/candidate_pair.rs +++ b/rtc-ice/src/candidate/candidate_pair.rs @@ -60,11 +60,11 @@ impl fmt::Display for CandidatePairState { /// Represents a combination of a local and remote candidate. #[derive(Clone, Copy)] pub struct CandidatePair { - pub(crate) ice_role_controlling: bool, - pub remote: usize, - pub local: usize, - pub remote_priority: u32, + pub local_index: usize, + pub remote_index: usize, pub local_priority: u32, + pub remote_priority: u32, + pub(crate) ice_role_controlling: bool, pub(crate) binding_request_count: u16, pub(crate) state: CandidatePairState, pub(crate) nominated: bool, @@ -77,8 +77,8 @@ impl fmt::Debug for CandidatePair { "prio {} (local, prio {}) {} <-> {} (remote, prio {})", self.priority(), self.local_priority, - self.local, - self.remote, + self.local_index, + self.remote_index, self.remote_priority, ) } @@ -91,8 +91,8 @@ impl fmt::Display for CandidatePair { "prio {} (local, prio {}) {} <-> {} (remote, prio {})", self.priority(), self.local_priority, - self.local, - self.remote, + self.local_index, + self.remote_index, self.remote_priority, ) } @@ -100,25 +100,25 @@ impl fmt::Display for CandidatePair { impl PartialEq for CandidatePair { fn eq(&self, other: &Self) -> bool { - self.local == other.local && self.remote == other.remote + self.local_index == other.local_index && self.remote_index == other.remote_index } } impl CandidatePair { #[must_use] pub fn new( - local: usize, - remote: usize, + local_index: usize, + remote_index: usize, local_priority: u32, remote_priority: u32, - controlling: bool, + ice_role_controlling: bool, ) -> Self { Self { - ice_role_controlling: controlling, - remote, - local, - remote_priority, + local_index, + remote_index, local_priority, + remote_priority, + ice_role_controlling, state: CandidatePairState::Waiting, binding_request_count: 0, nominated: false,