1 #[cfg(test)] 2 mod setting_engine_test; 3 4 use crate::dtls_transport::dtls_role::DTLSRole; 5 use crate::ice_transport::ice_candidate_type::RTCIceCandidateType; 6 use dtls::extension::extension_use_srtp::SrtpProtectionProfile; 7 use ice::agent::agent_config::{InterfaceFilterFn, IpFilterFn}; 8 use ice::mdns::MulticastDnsMode; 9 use ice::network_type::NetworkType; 10 use ice::udp_network::UDPNetwork; 11 12 use crate::error::{Error, Result}; 13 14 use crate::RECEIVE_MTU; 15 use std::sync::Arc; 16 use tokio::time::Duration; 17 use util::vnet::net::*; 18 19 #[derive(Default, Clone)] 20 pub struct Detach { 21 pub data_channels: bool, 22 } 23 24 #[derive(Default, Clone)] 25 pub struct Timeout { 26 pub ice_disconnected_timeout: Option<Duration>, 27 pub ice_failed_timeout: Option<Duration>, 28 pub ice_keepalive_interval: Option<Duration>, 29 pub ice_host_acceptance_min_wait: Option<Duration>, 30 pub ice_srflx_acceptance_min_wait: Option<Duration>, 31 pub ice_prflx_acceptance_min_wait: Option<Duration>, 32 pub ice_relay_acceptance_min_wait: Option<Duration>, 33 } 34 35 #[derive(Default, Clone)] 36 pub struct Candidates { 37 pub ice_lite: bool, 38 pub ice_network_types: Vec<NetworkType>, 39 pub interface_filter: Arc<Option<InterfaceFilterFn>>, 40 pub ip_filter: Arc<Option<IpFilterFn>>, 41 pub nat_1to1_ips: Vec<String>, 42 pub nat_1to1_ip_candidate_type: RTCIceCandidateType, 43 pub multicast_dns_mode: MulticastDnsMode, 44 pub multicast_dns_host_name: String, 45 pub username_fragment: String, 46 pub password: String, 47 } 48 49 #[derive(Default, Clone)] 50 pub struct ReplayProtection { 51 pub dtls: usize, 52 pub srtp: usize, 53 pub srtcp: usize, 54 } 55 56 /// SettingEngine allows influencing behavior in ways that are not 57 /// supported by the WebRTC API. This allows us to support additional 58 /// use-cases without deviating from the WebRTC API elsewhere. 59 #[derive(Default, Clone)] 60 pub struct SettingEngine { 61 pub(crate) detach: Detach, 62 pub(crate) timeout: Timeout, 63 pub(crate) candidates: Candidates, 64 pub(crate) replay_protection: ReplayProtection, 65 pub(crate) sdp_media_level_fingerprints: bool, 66 pub(crate) answering_dtls_role: DTLSRole, 67 pub(crate) disable_certificate_fingerprint_verification: bool, 68 pub(crate) allow_insecure_verification_algorithm: bool, 69 pub(crate) disable_srtp_replay_protection: bool, 70 pub(crate) disable_srtcp_replay_protection: bool, 71 pub(crate) vnet: Option<Arc<Net>>, 72 //BufferFactory :func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser, 73 //iceTCPMux :ice.TCPMux,? 74 //iceProxyDialer :proxy.Dialer,? 75 pub(crate) udp_network: UDPNetwork, 76 pub(crate) disable_media_engine_copy: bool, 77 pub(crate) srtp_protection_profiles: Vec<SrtpProtectionProfile>, 78 pub(crate) receive_mtu: usize, 79 pub(crate) mid_generator: Option<Arc<dyn Fn(isize) -> String + Send + Sync>>, 80 } 81 82 impl SettingEngine { 83 /// get_receive_mtu returns the configured MTU. If SettingEngine's MTU is configured to 0 it returns the default get_receive_mtu(&self) -> usize84 pub(crate) fn get_receive_mtu(&self) -> usize { 85 if self.receive_mtu != 0 { 86 self.receive_mtu 87 } else { 88 RECEIVE_MTU 89 } 90 } 91 /// detach_data_channels enables detaching data channels. When enabled 92 /// data channels have to be detached in the OnOpen callback using the 93 /// DataChannel.Detach method. detach_data_channels(&mut self)94 pub fn detach_data_channels(&mut self) { 95 self.detach.data_channels = true; 96 } 97 98 /// set_srtp_protection_profiles allows the user to override the default srtp Protection Profiles 99 /// The default srtp protection profiles are provided by the function `defaultSrtpProtectionProfiles` set_srtp_protection_profiles(&mut self, profiles: Vec<SrtpProtectionProfile>)100 pub fn set_srtp_protection_profiles(&mut self, profiles: Vec<SrtpProtectionProfile>) { 101 self.srtp_protection_profiles = profiles 102 } 103 104 /// set_ice_timeouts sets the behavior around ICE Timeouts 105 /// * disconnected_timeout is the duration without network activity before a Agent is considered disconnected. Default is 5 Seconds 106 /// * failed_timeout is the duration without network activity before a Agent is considered failed after disconnected. Default is 25 Seconds 107 /// * keep_alive_interval is how often the ICE Agent sends extra traffic if there is no activity, if media is flowing no traffic will be sent. Default is 2 seconds set_ice_timeouts( &mut self, disconnected_timeout: Option<Duration>, failed_timeout: Option<Duration>, keep_alive_interval: Option<Duration>, )108 pub fn set_ice_timeouts( 109 &mut self, 110 disconnected_timeout: Option<Duration>, 111 failed_timeout: Option<Duration>, 112 keep_alive_interval: Option<Duration>, 113 ) { 114 self.timeout.ice_disconnected_timeout = disconnected_timeout; 115 self.timeout.ice_failed_timeout = failed_timeout; 116 self.timeout.ice_keepalive_interval = keep_alive_interval; 117 } 118 119 /// set_host_acceptance_min_wait sets the icehost_acceptance_min_wait set_host_acceptance_min_wait(&mut self, t: Option<Duration>)120 pub fn set_host_acceptance_min_wait(&mut self, t: Option<Duration>) { 121 self.timeout.ice_host_acceptance_min_wait = t; 122 } 123 124 /// set_srflx_acceptance_min_wait sets the icesrflx_acceptance_min_wait set_srflx_acceptance_min_wait(&mut self, t: Option<Duration>)125 pub fn set_srflx_acceptance_min_wait(&mut self, t: Option<Duration>) { 126 self.timeout.ice_srflx_acceptance_min_wait = t; 127 } 128 129 /// set_prflx_acceptance_min_wait sets the iceprflx_acceptance_min_wait set_prflx_acceptance_min_wait(&mut self, t: Option<Duration>)130 pub fn set_prflx_acceptance_min_wait(&mut self, t: Option<Duration>) { 131 self.timeout.ice_prflx_acceptance_min_wait = t; 132 } 133 134 /// set_relay_acceptance_min_wait sets the icerelay_acceptance_min_wait set_relay_acceptance_min_wait(&mut self, t: Option<Duration>)135 pub fn set_relay_acceptance_min_wait(&mut self, t: Option<Duration>) { 136 self.timeout.ice_relay_acceptance_min_wait = t; 137 } 138 139 /// set_udp_network allows ICE traffic to come through Ephemeral or UDPMux. 140 /// UDPMux drastically simplifying deployments where ports will need to be opened/forwarded. 141 /// UDPMux should be started prior to creating PeerConnections. set_udp_network(&mut self, udp_network: UDPNetwork)142 pub fn set_udp_network(&mut self, udp_network: UDPNetwork) { 143 self.udp_network = udp_network; 144 } 145 146 /// set_lite configures whether or not the ice agent should be a lite agent set_lite(&mut self, lite: bool)147 pub fn set_lite(&mut self, lite: bool) { 148 self.candidates.ice_lite = lite; 149 } 150 151 /// set_network_types configures what types of candidate networks are supported 152 /// during local and server reflexive gathering. set_network_types(&mut self, candidate_types: Vec<NetworkType>)153 pub fn set_network_types(&mut self, candidate_types: Vec<NetworkType>) { 154 self.candidates.ice_network_types = candidate_types; 155 } 156 157 /// set_interface_filter sets the filtering functions when gathering ICE candidates 158 /// This can be used to exclude certain network interfaces from ICE. Which may be 159 /// useful if you know a certain interface will never succeed, or if you wish to reduce 160 /// the amount of information you wish to expose to the remote peer set_interface_filter(&mut self, filter: InterfaceFilterFn)161 pub fn set_interface_filter(&mut self, filter: InterfaceFilterFn) { 162 self.candidates.interface_filter = Arc::new(Some(filter)); 163 } 164 165 /// set_ip_filter sets the filtering functions when gathering ICE candidates 166 /// This can be used to exclude certain ip from ICE. Which may be 167 /// useful if you know a certain ip will never succeed, or if you wish to reduce 168 /// the amount of information you wish to expose to the remote peer set_ip_filter(&mut self, filter: IpFilterFn)169 pub fn set_ip_filter(&mut self, filter: IpFilterFn) { 170 self.candidates.ip_filter = Arc::new(Some(filter)); 171 } 172 173 /// set_nat_1to1_ips sets a list of external IP addresses of 1:1 (D)NAT 174 /// and a candidate type for which the external IP address is used. 175 /// This is useful when you are host a server using Pion on an AWS EC2 instance 176 /// which has a private address, behind a 1:1 DNAT with a public IP (e.g. 177 /// Elastic IP). In this case, you can give the public IP address so that 178 /// Pion will use the public IP address in its candidate instead of the private 179 /// IP address. The second argument, candidate_type, is used to tell Pion which 180 /// type of candidate should use the given public IP address. 181 /// Two types of candidates are supported: 182 /// 183 /// ICECandidateTypeHost: 184 /// The public IP address will be used for the host candidate in the SDP. 185 /// ICECandidateTypeSrflx: 186 /// A server reflexive candidate with the given public IP address will be added 187 /// to the SDP. 188 /// 189 /// Please note that if you choose ICECandidateTypeHost, then the private IP address 190 /// won't be advertised with the peer. Also, this option cannot be used along with mDNS. 191 /// 192 /// If you choose ICECandidateTypeSrflx, it simply adds a server reflexive candidate 193 /// with the public IP. The host candidate is still available along with mDNS 194 /// capabilities unaffected. Also, you cannot give STUN server URL at the same time. 195 /// It will result in an error otherwise. set_nat_1to1_ips(&mut self, ips: Vec<String>, candidate_type: RTCIceCandidateType)196 pub fn set_nat_1to1_ips(&mut self, ips: Vec<String>, candidate_type: RTCIceCandidateType) { 197 self.candidates.nat_1to1_ips = ips; 198 self.candidates.nat_1to1_ip_candidate_type = candidate_type; 199 } 200 201 /// set_answering_dtls_role sets the dtls_transport role that is selected when offering 202 /// The dtls_transport role controls if the WebRTC Client as a client or server. This 203 /// may be useful when interacting with non-compliant clients or debugging issues. 204 /// 205 /// DTLSRoleActive: 206 /// Act as dtls_transport Client, send the ClientHello and starts the handshake 207 /// DTLSRolePassive: 208 /// Act as dtls_transport Server, wait for ClientHello set_answering_dtls_role(&mut self, role: DTLSRole) -> Result<()>209 pub fn set_answering_dtls_role(&mut self, role: DTLSRole) -> Result<()> { 210 if role != DTLSRole::Client && role != DTLSRole::Server { 211 return Err(Error::ErrSettingEngineSetAnsweringDTLSRole); 212 } 213 214 self.answering_dtls_role = role; 215 Ok(()) 216 } 217 218 /// set_vnet sets the VNet instance that is passed to ice 219 /// VNet is a virtual network layer, allowing users to simulate 220 /// different topologies, latency, loss and jitter. This can be useful for 221 /// learning WebRTC concepts or testing your application in a lab environment set_vnet(&mut self, vnet: Option<Arc<Net>>)222 pub fn set_vnet(&mut self, vnet: Option<Arc<Net>>) { 223 self.vnet = vnet; 224 } 225 226 /// set_ice_multicast_dns_mode controls if ice queries and generates mDNS ICE Candidates set_ice_multicast_dns_mode(&mut self, multicast_dns_mode: ice::mdns::MulticastDnsMode)227 pub fn set_ice_multicast_dns_mode(&mut self, multicast_dns_mode: ice::mdns::MulticastDnsMode) { 228 self.candidates.multicast_dns_mode = multicast_dns_mode 229 } 230 231 /// set_multicast_dns_host_name sets a static HostName to be used by ice instead of generating one on startup 232 /// This should only be used for a single PeerConnection. Having multiple PeerConnections with the same HostName will cause 233 /// undefined behavior set_multicast_dns_host_name(&mut self, host_name: String)234 pub fn set_multicast_dns_host_name(&mut self, host_name: String) { 235 self.candidates.multicast_dns_host_name = host_name; 236 } 237 238 /// set_ice_credentials sets a staic uFrag/uPwd to be used by ice 239 /// This is useful if you want to do signalless WebRTC session, or having a reproducible environment with static credentials set_ice_credentials(&mut self, username_fragment: String, password: String)240 pub fn set_ice_credentials(&mut self, username_fragment: String, password: String) { 241 self.candidates.username_fragment = username_fragment; 242 self.candidates.password = password; 243 } 244 245 /// disable_certificate_fingerprint_verification disables fingerprint verification after dtls_transport Handshake has finished disable_certificate_fingerprint_verification(&mut self, is_disabled: bool)246 pub fn disable_certificate_fingerprint_verification(&mut self, is_disabled: bool) { 247 self.disable_certificate_fingerprint_verification = is_disabled; 248 } 249 250 /// allow_insecure_verification_algorithm allows the usage of certain signature verification 251 /// algorithm that are known to be vulnerable or deprecated. allow_insecure_verification_algorithm(&mut self, is_allowed: bool)252 pub fn allow_insecure_verification_algorithm(&mut self, is_allowed: bool) { 253 self.allow_insecure_verification_algorithm = is_allowed; 254 } 255 /// set_dtls_replay_protection_window sets a replay attack protection window size of dtls_transport connection. set_dtls_replay_protection_window(&mut self, n: usize)256 pub fn set_dtls_replay_protection_window(&mut self, n: usize) { 257 self.replay_protection.dtls = n; 258 } 259 260 /// set_srtp_replay_protection_window sets a replay attack protection window size of srtp session. set_srtp_replay_protection_window(&mut self, n: usize)261 pub fn set_srtp_replay_protection_window(&mut self, n: usize) { 262 self.disable_srtp_replay_protection = false; 263 self.replay_protection.srtp = n; 264 } 265 266 /// set_srtcp_replay_protection_window sets a replay attack protection window size of srtcp session. set_srtcp_replay_protection_window(&mut self, n: usize)267 pub fn set_srtcp_replay_protection_window(&mut self, n: usize) { 268 self.disable_srtcp_replay_protection = false; 269 self.replay_protection.srtcp = n; 270 } 271 272 /// disable_srtp_replay_protection disables srtp replay protection. disable_srtp_replay_protection(&mut self, is_disabled: bool)273 pub fn disable_srtp_replay_protection(&mut self, is_disabled: bool) { 274 self.disable_srtp_replay_protection = is_disabled; 275 } 276 277 /// disable_srtcp_replay_protection disables srtcp replay protection. disable_srtcp_replay_protection(&mut self, is_disabled: bool)278 pub fn disable_srtcp_replay_protection(&mut self, is_disabled: bool) { 279 self.disable_srtcp_replay_protection = is_disabled; 280 } 281 282 /// set_sdp_media_level_fingerprints configures the logic for dtls_transport Fingerprint insertion 283 /// If true, fingerprints will be inserted in the sdp at the fingerprint 284 /// level, instead of the session level. This helps with compatibility with 285 /// some webrtc implementations. set_sdp_media_level_fingerprints(&mut self, sdp_media_level_fingerprints: bool)286 pub fn set_sdp_media_level_fingerprints(&mut self, sdp_media_level_fingerprints: bool) { 287 self.sdp_media_level_fingerprints = sdp_media_level_fingerprints; 288 } 289 290 // SetICETCPMux enables ICE-TCP when set to a non-nil value. Make sure that 291 // NetworkTypeTCP4 or NetworkTypeTCP6 is enabled as well. 292 //pub fn SetICETCPMux(&mut self, tcpMux ice.TCPMux) { 293 // self.iceTCPMux = tcpMux 294 //} 295 296 // SetICEProxyDialer sets the proxy dialer interface based on golang.org/x/net/proxy. 297 //pub fn SetICEProxyDialer(&mut self, d proxy.Dialer) { 298 // self.iceProxyDialer = d 299 //} 300 301 /// disable_media_engine_copy stops the MediaEngine from being copied. This allows a user to modify 302 /// the MediaEngine after the PeerConnection has been constructed. This is useful if you wish to 303 /// modify codecs after signaling. Make sure not to share MediaEngines between PeerConnections. disable_media_engine_copy(&mut self, is_disabled: bool)304 pub fn disable_media_engine_copy(&mut self, is_disabled: bool) { 305 self.disable_media_engine_copy = is_disabled; 306 } 307 308 /// set_receive_mtu sets the size of read buffer that copies incoming packets. This is optional. 309 /// Leave this 0 for the default receive_mtu set_receive_mtu(&mut self, receive_mtu: usize)310 pub fn set_receive_mtu(&mut self, receive_mtu: usize) { 311 self.receive_mtu = receive_mtu; 312 } 313 314 /// Sets a callback used to generate mid for transceivers created by this side of the RTCPeerconnection. 315 /// By having separate "naming schemes" for mids generated by either side of a connection, it's 316 /// possible to reduce complexity when handling SDP offers/answers clashing. 317 /// 318 /// The `isize` argument is currently greatest seen _numeric_ mid. Since mids don't need to be numeric 319 /// this doesn't necessarily indicating anything. 320 /// 321 /// Note that the spec says: All MID values MUST be generated in a fashion that does not leak user 322 /// information, e.g., randomly or using a per-PeerConnection counter, and SHOULD be 3 bytes or less, 323 /// to allow them to efficiently fit into the RTP header extension set_mid_generator(&mut self, f: impl Fn(isize) -> String + Send + Sync + 'static)324 pub fn set_mid_generator(&mut self, f: impl Fn(isize) -> String + Send + Sync + 'static) { 325 self.mid_generator = Some(Arc::new(f)); 326 } 327 } 328