rtc_ice/agent/
agent_proto.rs

1use super::*;
2use mdns::{MDNS_PORT, MdnsEvent};
3
4impl sansio::Protocol<TaggedBytesMut, (), ()> for Agent {
5    type Rout = TaggedBytesMut;
6    type Wout = TaggedBytesMut;
7    type Eout = Event;
8    type Error = Error;
9    type Time = Instant;
10
11    fn handle_read(&mut self, msg: TaggedBytesMut) -> Result<()> {
12        // demuxing mDNS packet from STUN packet whether peer addr port is MDNS_PORT
13        if msg.transport.peer_addr.port() == MDNS_PORT {
14            let remote_candidates = if let Some(mdns_conn) = &mut self.mdns {
15                mdns_conn.handle_read(msg)?;
16
17                let mut remote_candidates = vec![];
18                // After mdns handle_read, check any query result
19                while let Some(event) = mdns_conn.poll_event() {
20                    match event {
21                        MdnsEvent::QueryAnswered(id, addr) => {
22                            if let Some(mut c) = self.mdns_queries.remove(&id)
23                                && c.set_ip(&addr).is_ok()
24                            {
25                                debug!(
26                                    "mDNS query id {} answered Candidate {} with resolved_addr {} is added into remote candidates",
27                                    id,
28                                    c,
29                                    c.addr()
30                                );
31                                remote_candidates.push(c);
32                            }
33                        }
34                        MdnsEvent::QueryTimeout(id) => {
35                            if let Some(c) = self.mdns_queries.remove(&id) {
36                                error!("mDNS Query {} timed out for {}", id, c.address());
37                            }
38                        }
39                    }
40                }
41                remote_candidates
42            } else {
43                vec![]
44            };
45
46            self.trigger_request_connectivity_check(remote_candidates);
47
48            Ok(())
49        } else if let Some(local_index) =
50            self.find_local_candidate(msg.transport.local_addr, msg.transport.transport_protocol)
51        {
52            self.handle_inbound_candidate_msg(local_index, msg)
53        } else {
54            warn!(
55                "[{}]: Discarded message, not a valid local candidate from {:?}:{}",
56                self.get_name(),
57                msg.transport.transport_protocol,
58                msg.transport.local_addr,
59            );
60            Err(Error::ErrUnhandledStunpacket)
61        }
62    }
63
64    fn poll_read(&mut self) -> Option<Self::Rout> {
65        None
66    }
67
68    fn handle_write(&mut self, _msg: ()) -> std::result::Result<(), Self::Error> {
69        Ok(())
70    }
71
72    fn poll_write(&mut self) -> Option<Self::Wout> {
73        if let Some(mdns_conn) = &mut self.mdns {
74            while let Some(msg) = mdns_conn.poll_write() {
75                self.write_outs.push_back(msg);
76            }
77        }
78
79        self.write_outs.pop_front()
80    }
81
82    fn handle_event(&mut self, _evt: ()) -> std::result::Result<(), Self::Error> {
83        Ok(())
84    }
85
86    fn poll_event(&mut self) -> Option<Self::Eout> {
87        self.event_outs.pop_front()
88    }
89
90    fn handle_timeout(&mut self, now: Self::Time) -> std::result::Result<(), Self::Error> {
91        let remote_candidates = if let Some(mdns_conn) = &mut self.mdns {
92            let _ = mdns_conn.handle_timeout(now);
93
94            let mut remote_candidates = vec![];
95            // After mdns handle_timeout, check any query result
96            while let Some(event) = mdns_conn.poll_event() {
97                match event {
98                    MdnsEvent::QueryAnswered(id, addr) => {
99                        if let Some(mut c) = self.mdns_queries.remove(&id)
100                            && c.set_ip(&addr).is_ok()
101                        {
102                            debug!(
103                                "mDNS query id {} answered Candidate {} with resolved_addr {} is added into remote candidates",
104                                id,
105                                c,
106                                c.addr()
107                            );
108                            remote_candidates.push(c);
109                        }
110                    }
111                    MdnsEvent::QueryTimeout(id) => {
112                        if let Some(c) = self.mdns_queries.remove(&id) {
113                            error!("mDNS Query {} timed out for {}", id, c.address());
114                        }
115                    }
116                }
117            }
118            remote_candidates
119        } else {
120            vec![]
121        };
122        self.trigger_request_connectivity_check(remote_candidates);
123
124        if self.ufrag_pwd.remote_credentials.is_some()
125            && self.last_checking_time + self.get_timeout_interval() <= now
126        {
127            self.contact(now);
128        }
129        Ok(())
130    }
131
132    fn poll_timeout(&mut self) -> Option<Self::Time> {
133        let mdns_timeout = if let Some(mdns_conn) = &mut self.mdns {
134            mdns_conn.poll_timeout()
135        } else {
136            None
137        };
138
139        let ice_timeout = if self.ufrag_pwd.remote_credentials.is_some() {
140            Some(self.last_checking_time + self.get_timeout_interval())
141        } else {
142            None
143        };
144
145        // This treats the two options as a collection and picks the minimum
146        [mdns_timeout, ice_timeout].into_iter().flatten().min()
147    }
148
149    fn close(&mut self) -> std::result::Result<(), Self::Error> {
150        self.set_selected_pair(None);
151        self.delete_all_candidates(false);
152        self.update_connection_state(ConnectionState::Closed);
153        if let Some(mdns_conn) = &mut self.mdns {
154            mdns_conn.close()?;
155        }
156        Ok(())
157    }
158}