github.com/pion/webrtc/v3@v3.2.24/settingengine.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 //go:build !js 5 // +build !js 6 7 package webrtc 8 9 import ( 10 "context" 11 "crypto/x509" 12 "io" 13 "net" 14 "time" 15 16 "github.com/pion/dtls/v2" 17 dtlsElliptic "github.com/pion/dtls/v2/pkg/crypto/elliptic" 18 "github.com/pion/ice/v2" 19 "github.com/pion/logging" 20 "github.com/pion/transport/v2" 21 "github.com/pion/transport/v2/packetio" 22 "github.com/pion/transport/v2/vnet" 23 "golang.org/x/net/proxy" 24 ) 25 26 // SettingEngine allows influencing behavior in ways that are not 27 // supported by the WebRTC API. This allows us to support additional 28 // use-cases without deviating from the WebRTC API elsewhere. 29 type SettingEngine struct { 30 ephemeralUDP struct { 31 PortMin uint16 32 PortMax uint16 33 } 34 detach struct { 35 DataChannels bool 36 } 37 timeout struct { 38 ICEDisconnectedTimeout *time.Duration 39 ICEFailedTimeout *time.Duration 40 ICEKeepaliveInterval *time.Duration 41 ICEHostAcceptanceMinWait *time.Duration 42 ICESrflxAcceptanceMinWait *time.Duration 43 ICEPrflxAcceptanceMinWait *time.Duration 44 ICERelayAcceptanceMinWait *time.Duration 45 } 46 candidates struct { 47 ICELite bool 48 ICENetworkTypes []NetworkType 49 InterfaceFilter func(string) bool 50 IPFilter func(net.IP) bool 51 NAT1To1IPs []string 52 NAT1To1IPCandidateType ICECandidateType 53 MulticastDNSMode ice.MulticastDNSMode 54 MulticastDNSHostName string 55 UsernameFragment string 56 Password string 57 IncludeLoopbackCandidate bool 58 } 59 replayProtection struct { 60 DTLS *uint 61 SRTP *uint 62 SRTCP *uint 63 } 64 dtls struct { 65 insecureSkipHelloVerify bool 66 disableInsecureSkipVerify bool 67 retransmissionInterval time.Duration 68 ellipticCurves []dtlsElliptic.Curve 69 connectContextMaker func() (context.Context, func()) 70 extendedMasterSecret dtls.ExtendedMasterSecretType 71 clientAuth *dtls.ClientAuthType 72 clientCAs *x509.CertPool 73 rootCAs *x509.CertPool 74 keyLogWriter io.Writer 75 } 76 sctp struct { 77 maxReceiveBufferSize uint32 78 } 79 sdpMediaLevelFingerprints bool 80 answeringDTLSRole DTLSRole 81 disableCertificateFingerprintVerification bool 82 disableSRTPReplayProtection bool 83 disableSRTCPReplayProtection bool 84 net transport.Net 85 BufferFactory func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser 86 LoggerFactory logging.LoggerFactory 87 iceTCPMux ice.TCPMux 88 iceUDPMux ice.UDPMux 89 iceProxyDialer proxy.Dialer 90 iceDisableActiveTCP bool 91 disableMediaEngineCopy bool 92 srtpProtectionProfiles []dtls.SRTPProtectionProfile 93 receiveMTU uint 94 } 95 96 // getReceiveMTU returns the configured MTU. If SettingEngine's MTU is configured to 0 it returns the default 97 func (e *SettingEngine) getReceiveMTU() uint { 98 if e.receiveMTU != 0 { 99 return e.receiveMTU 100 } 101 102 return receiveMTU 103 } 104 105 // DetachDataChannels enables detaching data channels. When enabled 106 // data channels have to be detached in the OnOpen callback using the 107 // DataChannel.Detach method. 108 func (e *SettingEngine) DetachDataChannels() { 109 e.detach.DataChannels = true 110 } 111 112 // SetSRTPProtectionProfiles allows the user to override the default SRTP Protection Profiles 113 // The default srtp protection profiles are provided by the function `defaultSrtpProtectionProfiles` 114 func (e *SettingEngine) SetSRTPProtectionProfiles(profiles ...dtls.SRTPProtectionProfile) { 115 e.srtpProtectionProfiles = profiles 116 } 117 118 // SetICETimeouts sets the behavior around ICE Timeouts 119 // 120 // disconnectedTimeout: 121 // 122 // Duration without network activity before an Agent is considered disconnected. Default is 5 Seconds 123 // 124 // failedTimeout: 125 // 126 // Duration without network activity before an Agent is considered failed after disconnected. Default is 25 Seconds 127 // 128 // keepAliveInterval: 129 // 130 // 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 131 func (e *SettingEngine) SetICETimeouts(disconnectedTimeout, failedTimeout, keepAliveInterval time.Duration) { 132 e.timeout.ICEDisconnectedTimeout = &disconnectedTimeout 133 e.timeout.ICEFailedTimeout = &failedTimeout 134 e.timeout.ICEKeepaliveInterval = &keepAliveInterval 135 } 136 137 // SetHostAcceptanceMinWait sets the ICEHostAcceptanceMinWait 138 func (e *SettingEngine) SetHostAcceptanceMinWait(t time.Duration) { 139 e.timeout.ICEHostAcceptanceMinWait = &t 140 } 141 142 // SetSrflxAcceptanceMinWait sets the ICESrflxAcceptanceMinWait 143 func (e *SettingEngine) SetSrflxAcceptanceMinWait(t time.Duration) { 144 e.timeout.ICESrflxAcceptanceMinWait = &t 145 } 146 147 // SetPrflxAcceptanceMinWait sets the ICEPrflxAcceptanceMinWait 148 func (e *SettingEngine) SetPrflxAcceptanceMinWait(t time.Duration) { 149 e.timeout.ICEPrflxAcceptanceMinWait = &t 150 } 151 152 // SetRelayAcceptanceMinWait sets the ICERelayAcceptanceMinWait 153 func (e *SettingEngine) SetRelayAcceptanceMinWait(t time.Duration) { 154 e.timeout.ICERelayAcceptanceMinWait = &t 155 } 156 157 // SetEphemeralUDPPortRange limits the pool of ephemeral ports that 158 // ICE UDP connections can allocate from. This affects both host candidates, 159 // and the local address of server reflexive candidates. 160 // 161 // When portMin and portMax are left to the 0 default value, pion/ice candidate 162 // gatherer replaces them and uses 1 for portMin and 65535 for portMax. 163 func (e *SettingEngine) SetEphemeralUDPPortRange(portMin, portMax uint16) error { 164 if portMax < portMin { 165 return ice.ErrPort 166 } 167 168 e.ephemeralUDP.PortMin = portMin 169 e.ephemeralUDP.PortMax = portMax 170 return nil 171 } 172 173 // SetLite configures whether or not the ice agent should be a lite agent 174 func (e *SettingEngine) SetLite(lite bool) { 175 e.candidates.ICELite = lite 176 } 177 178 // SetNetworkTypes configures what types of candidate networks are supported 179 // during local and server reflexive gathering. 180 func (e *SettingEngine) SetNetworkTypes(candidateTypes []NetworkType) { 181 e.candidates.ICENetworkTypes = candidateTypes 182 } 183 184 // SetInterfaceFilter sets the filtering functions when gathering ICE candidates 185 // This can be used to exclude certain network interfaces from ICE. Which may be 186 // useful if you know a certain interface will never succeed, or if you wish to reduce 187 // the amount of information you wish to expose to the remote peer 188 func (e *SettingEngine) SetInterfaceFilter(filter func(string) bool) { 189 e.candidates.InterfaceFilter = filter 190 } 191 192 // SetIPFilter sets the filtering functions when gathering ICE candidates 193 // This can be used to exclude certain ip from ICE. Which may be 194 // useful if you know a certain ip will never succeed, or if you wish to reduce 195 // the amount of information you wish to expose to the remote peer 196 func (e *SettingEngine) SetIPFilter(filter func(net.IP) bool) { 197 e.candidates.IPFilter = filter 198 } 199 200 // SetNAT1To1IPs sets a list of external IP addresses of 1:1 (D)NAT 201 // and a candidate type for which the external IP address is used. 202 // This is useful when you host a server using Pion on an AWS EC2 instance 203 // which has a private address, behind a 1:1 DNAT with a public IP (e.g. 204 // Elastic IP). In this case, you can give the public IP address so that 205 // Pion will use the public IP address in its candidate instead of the private 206 // IP address. The second argument, candidateType, is used to tell Pion which 207 // type of candidate should use the given public IP address. 208 // Two types of candidates are supported: 209 // 210 // ICECandidateTypeHost: 211 // 212 // The public IP address will be used for the host candidate in the SDP. 213 // 214 // ICECandidateTypeSrflx: 215 // 216 // A server reflexive candidate with the given public IP address will be added to the SDP. 217 // 218 // Please note that if you choose ICECandidateTypeHost, then the private IP address 219 // won't be advertised with the peer. Also, this option cannot be used along with mDNS. 220 // 221 // If you choose ICECandidateTypeSrflx, it simply adds a server reflexive candidate 222 // with the public IP. The host candidate is still available along with mDNS 223 // capabilities unaffected. Also, you cannot give STUN server URL at the same time. 224 // It will result in an error otherwise. 225 func (e *SettingEngine) SetNAT1To1IPs(ips []string, candidateType ICECandidateType) { 226 e.candidates.NAT1To1IPs = ips 227 e.candidates.NAT1To1IPCandidateType = candidateType 228 } 229 230 // SetIncludeLoopbackCandidate enable pion to gather loopback candidates, it is useful 231 // for some VM have public IP mapped to loopback interface 232 func (e *SettingEngine) SetIncludeLoopbackCandidate(include bool) { 233 e.candidates.IncludeLoopbackCandidate = include 234 } 235 236 // SetAnsweringDTLSRole sets the DTLS role that is selected when offering 237 // The DTLS role controls if the WebRTC Client as a client or server. This 238 // may be useful when interacting with non-compliant clients or debugging issues. 239 // 240 // DTLSRoleActive: 241 // 242 // Act as DTLS Client, send the ClientHello and starts the handshake 243 // 244 // DTLSRolePassive: 245 // 246 // Act as DTLS Server, wait for ClientHello 247 func (e *SettingEngine) SetAnsweringDTLSRole(role DTLSRole) error { 248 if role != DTLSRoleClient && role != DTLSRoleServer { 249 return errSettingEngineSetAnsweringDTLSRole 250 } 251 252 e.answeringDTLSRole = role 253 return nil 254 } 255 256 // SetVNet sets the VNet instance that is passed to pion/ice 257 // 258 // VNet is a virtual network layer for Pion, allowing users to simulate 259 // different topologies, latency, loss and jitter. This can be useful for 260 // learning WebRTC concepts or testing your application in a lab environment 261 // Deprecated: Please use SetNet() 262 func (e *SettingEngine) SetVNet(vnet *vnet.Net) { 263 e.SetNet(vnet) 264 } 265 266 // SetNet sets the Net instance that is passed to pion/ice 267 // 268 // Net is an network interface layer for Pion, allowing users to replace 269 // Pions network stack with a custom implementation. 270 func (e *SettingEngine) SetNet(net transport.Net) { 271 e.net = net 272 } 273 274 // SetICEMulticastDNSMode controls if pion/ice queries and generates mDNS ICE Candidates 275 func (e *SettingEngine) SetICEMulticastDNSMode(multicastDNSMode ice.MulticastDNSMode) { 276 e.candidates.MulticastDNSMode = multicastDNSMode 277 } 278 279 // SetMulticastDNSHostName sets a static HostName to be used by pion/ice instead of generating one on startup 280 // 281 // This should only be used for a single PeerConnection. Having multiple PeerConnections with the same HostName will cause 282 // undefined behavior 283 func (e *SettingEngine) SetMulticastDNSHostName(hostName string) { 284 e.candidates.MulticastDNSHostName = hostName 285 } 286 287 // SetICECredentials sets a staic uFrag/uPwd to be used by pion/ice 288 // 289 // This is useful if you want to do signalless WebRTC session, or having a reproducible environment with static credentials 290 func (e *SettingEngine) SetICECredentials(usernameFragment, password string) { 291 e.candidates.UsernameFragment = usernameFragment 292 e.candidates.Password = password 293 } 294 295 // DisableCertificateFingerprintVerification disables fingerprint verification after DTLS Handshake has finished 296 func (e *SettingEngine) DisableCertificateFingerprintVerification(isDisabled bool) { 297 e.disableCertificateFingerprintVerification = isDisabled 298 } 299 300 // SetDTLSReplayProtectionWindow sets a replay attack protection window size of DTLS connection. 301 func (e *SettingEngine) SetDTLSReplayProtectionWindow(n uint) { 302 e.replayProtection.DTLS = &n 303 } 304 305 // SetSRTPReplayProtectionWindow sets a replay attack protection window size of SRTP session. 306 func (e *SettingEngine) SetSRTPReplayProtectionWindow(n uint) { 307 e.disableSRTPReplayProtection = false 308 e.replayProtection.SRTP = &n 309 } 310 311 // SetSRTCPReplayProtectionWindow sets a replay attack protection window size of SRTCP session. 312 func (e *SettingEngine) SetSRTCPReplayProtectionWindow(n uint) { 313 e.disableSRTCPReplayProtection = false 314 e.replayProtection.SRTCP = &n 315 } 316 317 // DisableSRTPReplayProtection disables SRTP replay protection. 318 func (e *SettingEngine) DisableSRTPReplayProtection(isDisabled bool) { 319 e.disableSRTPReplayProtection = isDisabled 320 } 321 322 // DisableSRTCPReplayProtection disables SRTCP replay protection. 323 func (e *SettingEngine) DisableSRTCPReplayProtection(isDisabled bool) { 324 e.disableSRTCPReplayProtection = isDisabled 325 } 326 327 // SetSDPMediaLevelFingerprints configures the logic for DTLS Fingerprint insertion 328 // If true, fingerprints will be inserted in the sdp at the fingerprint 329 // level, instead of the session level. This helps with compatibility with 330 // some webrtc implementations. 331 func (e *SettingEngine) SetSDPMediaLevelFingerprints(sdpMediaLevelFingerprints bool) { 332 e.sdpMediaLevelFingerprints = sdpMediaLevelFingerprints 333 } 334 335 // SetICETCPMux enables ICE-TCP when set to a non-nil value. Make sure that 336 // NetworkTypeTCP4 or NetworkTypeTCP6 is enabled as well. 337 func (e *SettingEngine) SetICETCPMux(tcpMux ice.TCPMux) { 338 e.iceTCPMux = tcpMux 339 } 340 341 // SetICEUDPMux allows ICE traffic to come through a single UDP port, drastically 342 // simplifying deployments where ports will need to be opened/forwarded. 343 // UDPMux should be started prior to creating PeerConnections. 344 func (e *SettingEngine) SetICEUDPMux(udpMux ice.UDPMux) { 345 e.iceUDPMux = udpMux 346 } 347 348 // SetICEProxyDialer sets the proxy dialer interface based on golang.org/x/net/proxy. 349 func (e *SettingEngine) SetICEProxyDialer(d proxy.Dialer) { 350 e.iceProxyDialer = d 351 } 352 353 // DisableActiveTCP disables using active TCP for ICE. Active TCP is enabled by default 354 func (e *SettingEngine) DisableActiveTCP(isDisabled bool) { 355 e.iceDisableActiveTCP = isDisabled 356 } 357 358 // DisableMediaEngineCopy stops the MediaEngine from being copied. This allows a user to modify 359 // the MediaEngine after the PeerConnection has been constructed. This is useful if you wish to 360 // modify codecs after signaling. Make sure not to share MediaEngines between PeerConnections. 361 func (e *SettingEngine) DisableMediaEngineCopy(isDisabled bool) { 362 e.disableMediaEngineCopy = isDisabled 363 } 364 365 // SetReceiveMTU sets the size of read buffer that copies incoming packets. This is optional. 366 // Leave this 0 for the default receiveMTU 367 func (e *SettingEngine) SetReceiveMTU(receiveMTU uint) { 368 e.receiveMTU = receiveMTU 369 } 370 371 // SetDTLSRetransmissionInterval sets the retranmission interval for DTLS. 372 func (e *SettingEngine) SetDTLSRetransmissionInterval(interval time.Duration) { 373 e.dtls.retransmissionInterval = interval 374 } 375 376 // SetDTLSInsecureSkipHelloVerify sets the skip HelloVerify flag for DTLS. 377 // If true and when acting as DTLS server, will allow client to skip hello verify phase and 378 // receive ServerHello after initial ClientHello. This will mean faster connect times, 379 // but will have lower DoS attack resistance. 380 func (e *SettingEngine) SetDTLSInsecureSkipHelloVerify(skip bool) { 381 e.dtls.insecureSkipHelloVerify = skip 382 } 383 384 // SetDTLSDisableInsecureSkipVerify sets the disable skip insecure verify flag for DTLS. 385 // This controls whether a client verifies the server's certificate chain and host name. 386 func (e *SettingEngine) SetDTLSDisableInsecureSkipVerify(disable bool) { 387 e.dtls.disableInsecureSkipVerify = disable 388 } 389 390 // SetDTLSEllipticCurves sets the elliptic curves for DTLS. 391 func (e *SettingEngine) SetDTLSEllipticCurves(ellipticCurves ...dtlsElliptic.Curve) { 392 e.dtls.ellipticCurves = ellipticCurves 393 } 394 395 // SetDTLSConnectContextMaker sets the context used during the DTLS Handshake. 396 // It can be used to extend or reduce the timeout on the DTLS Handshake. 397 // If nil, the default dtls.ConnectContextMaker is used. It can be implemented as following. 398 // 399 // func ConnectContextMaker() (context.Context, func()) { 400 // return context.WithTimeout(context.Background(), 30*time.Second) 401 // } 402 func (e *SettingEngine) SetDTLSConnectContextMaker(connectContextMaker func() (context.Context, func())) { 403 e.dtls.connectContextMaker = connectContextMaker 404 } 405 406 // SetDTLSExtendedMasterSecret sets the extended master secret type for DTLS. 407 func (e *SettingEngine) SetDTLSExtendedMasterSecret(extendedMasterSecret dtls.ExtendedMasterSecretType) { 408 e.dtls.extendedMasterSecret = extendedMasterSecret 409 } 410 411 // SetDTLSClientAuth sets the client auth type for DTLS. 412 func (e *SettingEngine) SetDTLSClientAuth(clientAuth dtls.ClientAuthType) { 413 e.dtls.clientAuth = &clientAuth 414 } 415 416 // SetDTLSClientCAs sets the client CA certificate pool for DTLS certificate verification. 417 func (e *SettingEngine) SetDTLSClientCAs(clientCAs *x509.CertPool) { 418 e.dtls.clientCAs = clientCAs 419 } 420 421 // SetDTLSRootCAs sets the root CA certificate pool for DTLS certificate verification. 422 func (e *SettingEngine) SetDTLSRootCAs(rootCAs *x509.CertPool) { 423 e.dtls.rootCAs = rootCAs 424 } 425 426 // SetDTLSKeyLogWriter sets the destination of the TLS key material for debugging. 427 // Logging key material compromises security and should only be use for debugging. 428 func (e *SettingEngine) SetDTLSKeyLogWriter(writer io.Writer) { 429 e.dtls.keyLogWriter = writer 430 } 431 432 // SetSCTPMaxReceiveBufferSize sets the maximum receive buffer size. 433 // Leave this 0 for the default maxReceiveBufferSize. 434 func (e *SettingEngine) SetSCTPMaxReceiveBufferSize(maxReceiveBufferSize uint32) { 435 e.sctp.maxReceiveBufferSize = maxReceiveBufferSize 436 }