1 use super::*;
2 use crate::error::*;
3 use crate::mdns::*;
4 use crate::network_type::*;
5 use crate::udp_network::UDPNetwork;
6 use crate::url::*;
7
8 use util::vnet::net::*;
9
10 use std::net::IpAddr;
11 use std::time::Duration;
12
13 /// The interval at which the agent performs candidate checks in the connecting phase.
14 pub(crate) const DEFAULT_CHECK_INTERVAL: Duration = Duration::from_millis(200);
15
16 /// The interval used to keep candidates alive.
17 pub(crate) const DEFAULT_KEEPALIVE_INTERVAL: Duration = Duration::from_secs(2);
18
19 /// The default time till an Agent transitions disconnected.
20 pub(crate) const DEFAULT_DISCONNECTED_TIMEOUT: Duration = Duration::from_secs(5);
21
22 /// The default time till an Agent transitions to failed after disconnected.
23 pub(crate) const DEFAULT_FAILED_TIMEOUT: Duration = Duration::from_secs(25);
24
25 /// Wait time before nominating a host candidate.
26 pub(crate) const DEFAULT_HOST_ACCEPTANCE_MIN_WAIT: Duration = Duration::from_secs(0);
27
28 /// Wait time before nominating a srflx candidate.
29 pub(crate) const DEFAULT_SRFLX_ACCEPTANCE_MIN_WAIT: Duration = Duration::from_millis(500);
30
31 /// Wait time before nominating a prflx candidate.
32 pub(crate) const DEFAULT_PRFLX_ACCEPTANCE_MIN_WAIT: Duration = Duration::from_millis(1000);
33
34 /// Wait time before nominating a relay candidate.
35 pub(crate) const DEFAULT_RELAY_ACCEPTANCE_MIN_WAIT: Duration = Duration::from_millis(2000);
36
37 /// Max binding request before considering a pair failed.
38 pub(crate) const DEFAULT_MAX_BINDING_REQUESTS: u16 = 7;
39
40 /// The number of bytes that can be buffered before we start to error.
41 pub(crate) const MAX_BUFFER_SIZE: usize = 1000 * 1000; // 1MB
42
43 /// Wait time before binding requests can be deleted.
44 pub(crate) const MAX_BINDING_REQUEST_TIMEOUT: Duration = Duration::from_millis(4000);
45
default_candidate_types() -> Vec<CandidateType>46 pub(crate) fn default_candidate_types() -> Vec<CandidateType> {
47 vec![
48 CandidateType::Host,
49 CandidateType::ServerReflexive,
50 CandidateType::Relay,
51 ]
52 }
53
54 pub type InterfaceFilterFn = Box<dyn (Fn(&str) -> bool) + Send + Sync>;
55 pub type IpFilterFn = Box<dyn (Fn(IpAddr) -> bool) + Send + Sync>;
56
57 /// Collects the arguments to `ice::Agent` construction into a single structure, for
58 /// future-proofness of the interface.
59 #[derive(Default)]
60 pub struct AgentConfig {
61 pub urls: Vec<Url>,
62
63 /// Controls how the UDP network stack works.
64 /// See [`UDPNetwork`]
65 pub udp_network: UDPNetwork,
66
67 /// It is used to perform connectivity checks. The values MUST be unguessable, with at least
68 /// 128 bits of random number generator output used to generate the password, and at least 24
69 /// bits of output to generate the username fragment.
70 pub local_ufrag: String,
71 /// It is used to perform connectivity checks. The values MUST be unguessable, with at least
72 /// 128 bits of random number generator output used to generate the password, and at least 24
73 /// bits of output to generate the username fragment.
74 pub local_pwd: String,
75
76 /// Controls mDNS behavior for the ICE agent.
77 pub multicast_dns_mode: MulticastDnsMode,
78
79 /// Controls the hostname for this agent. If none is specified a random one will be generated.
80 pub multicast_dns_host_name: String,
81
82 /// Control mDNS destination address
83 pub multicast_dns_dest_addr: String,
84
85 /// Defaults to 5 seconds when this property is nil.
86 /// If the duration is 0, the ICE Agent will never go to disconnected.
87 pub disconnected_timeout: Option<Duration>,
88
89 /// Defaults to 25 seconds when this property is nil.
90 /// If the duration is 0, we will never go to failed.
91 pub failed_timeout: Option<Duration>,
92
93 /// Determines how often should we send ICE keepalives (should be less then connectiontimeout
94 /// above) when this is nil, it defaults to 10 seconds.
95 /// A keepalive interval of 0 means we never send keepalive packets
96 pub keepalive_interval: Option<Duration>,
97
98 /// An optional configuration for disabling or enabling support for specific network types.
99 pub network_types: Vec<NetworkType>,
100
101 /// An optional configuration for disabling or enabling support for specific candidate types.
102 pub candidate_types: Vec<CandidateType>,
103
104 //LoggerFactory logging.LoggerFactory
105 /// Controls how often our internal task loop runs when in the connecting state.
106 /// Only useful for testing.
107 pub check_interval: Duration,
108
109 /// The max amount of binding requests the agent will send over a candidate pair for validation
110 /// or nomination, if after max_binding_requests the candidate is yet to answer a binding
111 /// request or a nomination we set the pair as failed.
112 pub max_binding_requests: Option<u16>,
113
114 pub is_controlling: bool,
115
116 /// lite agents do not perform connectivity check and only provide host candidates.
117 pub lite: bool,
118
119 /// It is used along with nat1to1ips to specify which candidate type the 1:1 NAT IP addresses
120 /// should be mapped to. If unspecified or CandidateTypeHost, nat1to1ips are used to replace
121 /// host candidate IPs. If CandidateTypeServerReflexive, it will insert a srflx candidate (as
122 /// if it was dervied from a STUN server) with its port number being the one for the actual host
123 /// candidate. Other values will result in an error.
124 pub nat_1to1_ip_candidate_type: CandidateType,
125
126 /// Contains a list of public IP addresses that are to be used as a host candidate or srflx
127 /// candidate. This is used typically for servers that are behind 1:1 D-NAT (e.g. AWS EC2
128 /// instances) and to eliminate the need of server reflexisive candidate gathering.
129 pub nat_1to1_ips: Vec<String>,
130
131 /// Specify a minimum wait time before selecting host candidates.
132 pub host_acceptance_min_wait: Option<Duration>,
133 /// Specify a minimum wait time before selecting srflx candidates.
134 pub srflx_acceptance_min_wait: Option<Duration>,
135 /// Specify a minimum wait time before selecting prflx candidates.
136 pub prflx_acceptance_min_wait: Option<Duration>,
137 /// Specify a minimum wait time before selecting relay candidates.
138 pub relay_acceptance_min_wait: Option<Duration>,
139
140 /// Net is the our abstracted network interface for internal development purpose only
141 /// (see (github.com/pion/transport/vnet)[github.com/pion/transport/vnet]).
142 pub net: Option<Arc<Net>>,
143
144 /// A function that you can use in order to whitelist or blacklist the interfaces which are
145 /// used to gather ICE candidates.
146 pub interface_filter: Arc<Option<InterfaceFilterFn>>,
147
148 /// A function that you can use in order to whitelist or blacklist
149 /// the ips which are used to gather ICE candidates.
150 pub ip_filter: Arc<Option<IpFilterFn>>,
151
152 /// Controls if self-signed certificates are accepted when connecting to TURN servers via TLS or
153 /// DTLS.
154 pub insecure_skip_verify: bool,
155 }
156
157 impl AgentConfig {
158 /// Populates an agent and falls back to defaults if fields are unset.
init_with_defaults(&self, a: &mut AgentInternal)159 pub(crate) fn init_with_defaults(&self, a: &mut AgentInternal) {
160 if let Some(max_binding_requests) = self.max_binding_requests {
161 a.max_binding_requests = max_binding_requests;
162 } else {
163 a.max_binding_requests = DEFAULT_MAX_BINDING_REQUESTS;
164 }
165
166 if let Some(host_acceptance_min_wait) = self.host_acceptance_min_wait {
167 a.host_acceptance_min_wait = host_acceptance_min_wait;
168 } else {
169 a.host_acceptance_min_wait = DEFAULT_HOST_ACCEPTANCE_MIN_WAIT;
170 }
171
172 if let Some(srflx_acceptance_min_wait) = self.srflx_acceptance_min_wait {
173 a.srflx_acceptance_min_wait = srflx_acceptance_min_wait;
174 } else {
175 a.srflx_acceptance_min_wait = DEFAULT_SRFLX_ACCEPTANCE_MIN_WAIT;
176 }
177
178 if let Some(prflx_acceptance_min_wait) = self.prflx_acceptance_min_wait {
179 a.prflx_acceptance_min_wait = prflx_acceptance_min_wait;
180 } else {
181 a.prflx_acceptance_min_wait = DEFAULT_PRFLX_ACCEPTANCE_MIN_WAIT;
182 }
183
184 if let Some(relay_acceptance_min_wait) = self.relay_acceptance_min_wait {
185 a.relay_acceptance_min_wait = relay_acceptance_min_wait;
186 } else {
187 a.relay_acceptance_min_wait = DEFAULT_RELAY_ACCEPTANCE_MIN_WAIT;
188 }
189
190 if let Some(disconnected_timeout) = self.disconnected_timeout {
191 a.disconnected_timeout = disconnected_timeout;
192 } else {
193 a.disconnected_timeout = DEFAULT_DISCONNECTED_TIMEOUT;
194 }
195
196 if let Some(failed_timeout) = self.failed_timeout {
197 a.failed_timeout = failed_timeout;
198 } else {
199 a.failed_timeout = DEFAULT_FAILED_TIMEOUT;
200 }
201
202 if let Some(keepalive_interval) = self.keepalive_interval {
203 a.keepalive_interval = keepalive_interval;
204 } else {
205 a.keepalive_interval = DEFAULT_KEEPALIVE_INTERVAL;
206 }
207
208 if self.check_interval == Duration::from_secs(0) {
209 a.check_interval = DEFAULT_CHECK_INTERVAL;
210 } else {
211 a.check_interval = self.check_interval;
212 }
213 }
214
init_ext_ip_mapping( &self, mdns_mode: MulticastDnsMode, candidate_types: &[CandidateType], ) -> Result<Option<ExternalIpMapper>>215 pub(crate) fn init_ext_ip_mapping(
216 &self,
217 mdns_mode: MulticastDnsMode,
218 candidate_types: &[CandidateType],
219 ) -> Result<Option<ExternalIpMapper>> {
220 if let Some(ext_ip_mapper) =
221 ExternalIpMapper::new(self.nat_1to1_ip_candidate_type, &self.nat_1to1_ips)?
222 {
223 if ext_ip_mapper.candidate_type == CandidateType::Host {
224 if mdns_mode == MulticastDnsMode::QueryAndGather {
225 return Err(Error::ErrMulticastDnsWithNat1to1IpMapping);
226 }
227 let mut candi_host_enabled = false;
228 for candi_type in candidate_types {
229 if *candi_type == CandidateType::Host {
230 candi_host_enabled = true;
231 break;
232 }
233 }
234 if !candi_host_enabled {
235 return Err(Error::ErrIneffectiveNat1to1IpMappingHost);
236 }
237 } else if ext_ip_mapper.candidate_type == CandidateType::ServerReflexive {
238 let mut candi_srflx_enabled = false;
239 for candi_type in candidate_types {
240 if *candi_type == CandidateType::ServerReflexive {
241 candi_srflx_enabled = true;
242 break;
243 }
244 }
245 if !candi_srflx_enabled {
246 return Err(Error::ErrIneffectiveNat1to1IpMappingSrflx);
247 }
248 }
249
250 Ok(Some(ext_ip_mapper))
251 } else {
252 Ok(None)
253 }
254 }
255 }
256