xref: /webrtc/ice/src/agent/agent_config.rs (revision 6d1cc959)
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