use super::*;
use mdns::{MDNS_PORT, MdnsEvent};
impl sansio::Protocol<TaggedBytesMut, (), ()> for Agent {
type Rout = TaggedBytesMut;
type Wout = TaggedBytesMut;
type Eout = Event;
type Error = Error;
type Time = Instant;
fn handle_read(&mut self, msg: TaggedBytesMut) -> Result<()> {
if msg.transport.peer_addr.port() == MDNS_PORT {
let remote_candidates = if let Some(mdns_conn) = &mut self.mdns {
mdns_conn.handle_read(msg)?;
let mut remote_candidates = vec![];
while let Some(event) = mdns_conn.poll_event() {
match event {
MdnsEvent::QueryAnswered(id, addr) => {
if let Some(mut c) = self.mdns_queries.remove(&id)
&& c.set_ip(&addr).is_ok()
{
debug!(
"mDNS query id {} answered Candidate {} with resolved_addr {} is added into remote candidates",
id,
c,
c.addr()
);
remote_candidates.push(c);
}
}
MdnsEvent::QueryTimeout(id) => {
if let Some(c) = self.mdns_queries.remove(&id) {
error!("mDNS Query {} timed out for {}", id, c.address());
}
}
}
}
remote_candidates
} else {
vec![]
};
self.trigger_request_connectivity_check(remote_candidates);
Ok(())
} else if let Some(local_index) =
self.find_local_candidate(msg.transport.local_addr, msg.transport.transport_protocol)
{
self.handle_inbound_candidate_msg(local_index, msg)
} else {
warn!(
"[{}]: Discarded message, not a valid local candidate from {:?}:{}",
self.get_name(),
msg.transport.transport_protocol,
msg.transport.local_addr,
);
Err(Error::ErrUnhandledStunpacket)
}
}
fn poll_read(&mut self) -> Option<Self::Rout> {
None
}
fn handle_write(&mut self, _msg: ()) -> std::result::Result<(), Self::Error> {
Ok(())
}
fn poll_write(&mut self) -> Option<Self::Wout> {
if let Some(mdns_conn) = &mut self.mdns {
while let Some(msg) = mdns_conn.poll_write() {
self.write_outs.push_back(msg);
}
}
self.write_outs.pop_front()
}
fn handle_event(&mut self, _evt: ()) -> std::result::Result<(), Self::Error> {
Ok(())
}
fn poll_event(&mut self) -> Option<Self::Eout> {
self.event_outs.pop_front()
}
fn handle_timeout(&mut self, now: Self::Time) -> std::result::Result<(), Self::Error> {
let remote_candidates = if let Some(mdns_conn) = &mut self.mdns {
let _ = mdns_conn.handle_timeout(now);
let mut remote_candidates = vec![];
while let Some(event) = mdns_conn.poll_event() {
match event {
MdnsEvent::QueryAnswered(id, addr) => {
if let Some(mut c) = self.mdns_queries.remove(&id)
&& c.set_ip(&addr).is_ok()
{
debug!(
"mDNS query id {} answered Candidate {} with resolved_addr {} is added into remote candidates",
id,
c,
c.addr()
);
remote_candidates.push(c);
}
}
MdnsEvent::QueryTimeout(id) => {
if let Some(c) = self.mdns_queries.remove(&id) {
error!("mDNS Query {} timed out for {}", id, c.address());
}
}
}
}
remote_candidates
} else {
vec![]
};
self.trigger_request_connectivity_check(remote_candidates);
if self.ufrag_pwd.remote_credentials.is_some()
&& self.last_checking_time + self.get_timeout_interval() <= now
{
self.contact(now);
}
Ok(())
}
fn poll_timeout(&mut self) -> Option<Self::Time> {
let mdns_timeout = if let Some(mdns_conn) = &mut self.mdns {
mdns_conn.poll_timeout()
} else {
None
};
let ice_timeout = if self.ufrag_pwd.remote_credentials.is_some() {
Some(self.last_checking_time + self.get_timeout_interval())
} else {
None
};
[mdns_timeout, ice_timeout].into_iter().flatten().min()
}
fn close(&mut self) -> std::result::Result<(), Self::Error> {
self.set_selected_pair(None);
self.delete_all_candidates(false);
self.update_connection_state(ConnectionState::Closed);
if let Some(mdns_conn) = &mut self.mdns {
mdns_conn.close()?;
}
Ok(())
}
}