1// +build !js
2
3package webrtc
4
5import (
6	"io"
7	"time"
8
9	"github.com/pion/ice/v2"
10	"github.com/pion/logging"
11	"github.com/pion/transport/packetio"
12	"github.com/pion/transport/vnet"
13	"golang.org/x/net/proxy"
14)
15
16// SettingEngine allows influencing behavior in ways that are not
17// supported by the WebRTC API. This allows us to support additional
18// use-cases without deviating from the WebRTC API elsewhere.
19type SettingEngine struct {
20	ephemeralUDP struct {
21		PortMin uint16
22		PortMax uint16
23	}
24	detach struct {
25		DataChannels bool
26	}
27	timeout struct {
28		ICEDisconnectedTimeout    *time.Duration
29		ICEFailedTimeout          *time.Duration
30		ICEKeepaliveInterval      *time.Duration
31		ICEHostAcceptanceMinWait  *time.Duration
32		ICESrflxAcceptanceMinWait *time.Duration
33		ICEPrflxAcceptanceMinWait *time.Duration
34		ICERelayAcceptanceMinWait *time.Duration
35	}
36	candidates struct {
37		ICELite                bool
38		ICENetworkTypes        []NetworkType
39		InterfaceFilter        func(string) bool
40		NAT1To1IPs             []string
41		NAT1To1IPCandidateType ICECandidateType
42		MulticastDNSMode       ice.MulticastDNSMode
43		MulticastDNSHostName   string
44		UsernameFragment       string
45		Password               string
46	}
47	replayProtection struct {
48		DTLS  *uint
49		SRTP  *uint
50		SRTCP *uint
51	}
52	sdpMediaLevelFingerprints                 bool
53	answeringDTLSRole                         DTLSRole
54	disableCertificateFingerprintVerification bool
55	disableSRTPReplayProtection               bool
56	disableSRTCPReplayProtection              bool
57	vnet                                      *vnet.Net
58	BufferFactory                             func(packetType packetio.BufferPacketType, ssrc uint32) io.ReadWriteCloser
59	LoggerFactory                             logging.LoggerFactory
60	iceTCPMux                                 ice.TCPMux
61	iceProxyDialer                            proxy.Dialer
62	disableMediaEngineCopy                    bool
63}
64
65// DetachDataChannels enables detaching data channels. When enabled
66// data channels have to be detached in the OnOpen callback using the
67// DataChannel.Detach method.
68func (e *SettingEngine) DetachDataChannels() {
69	e.detach.DataChannels = true
70}
71
72// SetICETimeouts sets the behavior around ICE Timeouts
73// * disconnectedTimeout is the duration without network activity before a Agent is considered disconnected. Default is 5 Seconds
74// * failedTimeout is the duration without network activity before a Agent is considered failed after disconnected. Default is 25 Seconds
75// * keepAliveInterval 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
76func (e *SettingEngine) SetICETimeouts(disconnectedTimeout, failedTimeout, keepAliveInterval time.Duration) {
77	e.timeout.ICEDisconnectedTimeout = &disconnectedTimeout
78	e.timeout.ICEFailedTimeout = &failedTimeout
79	e.timeout.ICEKeepaliveInterval = &keepAliveInterval
80}
81
82// SetHostAcceptanceMinWait sets the ICEHostAcceptanceMinWait
83func (e *SettingEngine) SetHostAcceptanceMinWait(t time.Duration) {
84	e.timeout.ICEHostAcceptanceMinWait = &t
85}
86
87// SetSrflxAcceptanceMinWait sets the ICESrflxAcceptanceMinWait
88func (e *SettingEngine) SetSrflxAcceptanceMinWait(t time.Duration) {
89	e.timeout.ICESrflxAcceptanceMinWait = &t
90}
91
92// SetPrflxAcceptanceMinWait sets the ICEPrflxAcceptanceMinWait
93func (e *SettingEngine) SetPrflxAcceptanceMinWait(t time.Duration) {
94	e.timeout.ICEPrflxAcceptanceMinWait = &t
95}
96
97// SetRelayAcceptanceMinWait sets the ICERelayAcceptanceMinWait
98func (e *SettingEngine) SetRelayAcceptanceMinWait(t time.Duration) {
99	e.timeout.ICERelayAcceptanceMinWait = &t
100}
101
102// SetEphemeralUDPPortRange limits the pool of ephemeral ports that
103// ICE UDP connections can allocate from. This affects both host candidates,
104// and the local address of server reflexive candidates.
105func (e *SettingEngine) SetEphemeralUDPPortRange(portMin, portMax uint16) error {
106	if portMax < portMin {
107		return ice.ErrPort
108	}
109
110	e.ephemeralUDP.PortMin = portMin
111	e.ephemeralUDP.PortMax = portMax
112	return nil
113}
114
115// SetLite configures whether or not the ice agent should be a lite agent
116func (e *SettingEngine) SetLite(lite bool) {
117	e.candidates.ICELite = lite
118}
119
120// SetNetworkTypes configures what types of candidate networks are supported
121// during local and server reflexive gathering.
122func (e *SettingEngine) SetNetworkTypes(candidateTypes []NetworkType) {
123	e.candidates.ICENetworkTypes = candidateTypes
124}
125
126// SetInterfaceFilter sets the filtering functions when gathering ICE candidates
127// This can be used to exclude certain network interfaces from ICE. Which may be
128// useful if you know a certain interface will never succeed, or if you wish to reduce
129// the amount of information you wish to expose to the remote peer
130func (e *SettingEngine) SetInterfaceFilter(filter func(string) bool) {
131	e.candidates.InterfaceFilter = filter
132}
133
134// SetNAT1To1IPs sets a list of external IP addresses of 1:1 (D)NAT
135// and a candidate type for which the external IP address is used.
136// This is useful when you are host a server using Pion on an AWS EC2 instance
137// which has a private address, behind a 1:1 DNAT with a public IP (e.g.
138// Elastic IP). In this case, you can give the public IP address so that
139// Pion will use the public IP address in its candidate instead of the private
140// IP address. The second argument, candidateType, is used to tell Pion which
141// type of candidate should use the given public IP address.
142// Two types of candidates are supported:
143//
144// ICECandidateTypeHost:
145//		The public IP address will be used for the host candidate in the SDP.
146// ICECandidateTypeSrflx:
147//		A server reflexive candidate with the given public IP address will be added
148// to the SDP.
149//
150// Please note that if you choose ICECandidateTypeHost, then the private IP address
151// won't be advertised with the peer. Also, this option cannot be used along with mDNS.
152//
153// If you choose ICECandidateTypeSrflx, it simply adds a server reflexive candidate
154// with the public IP. The host candidate is still available along with mDNS
155// capabilities unaffected. Also, you cannot give STUN server URL at the same time.
156// It will result in an error otherwise.
157func (e *SettingEngine) SetNAT1To1IPs(ips []string, candidateType ICECandidateType) {
158	e.candidates.NAT1To1IPs = ips
159	e.candidates.NAT1To1IPCandidateType = candidateType
160}
161
162// SetAnsweringDTLSRole sets the DTLS role that is selected when offering
163// The DTLS role controls if the WebRTC Client as a client or server. This
164// may be useful when interacting with non-compliant clients or debugging issues.
165//
166// DTLSRoleActive:
167// 		Act as DTLS Client, send the ClientHello and starts the handshake
168// DTLSRolePassive:
169// 		Act as DTLS Server, wait for ClientHello
170func (e *SettingEngine) SetAnsweringDTLSRole(role DTLSRole) error {
171	if role != DTLSRoleClient && role != DTLSRoleServer {
172		return errSettingEngineSetAnsweringDTLSRole
173	}
174
175	e.answeringDTLSRole = role
176	return nil
177}
178
179// SetVNet sets the VNet instance that is passed to pion/ice
180//
181// VNet is a virtual network layer for Pion, allowing users to simulate
182// different topologies, latency, loss and jitter. This can be useful for
183// learning WebRTC concepts or testing your application in a lab environment
184func (e *SettingEngine) SetVNet(vnet *vnet.Net) {
185	e.vnet = vnet
186}
187
188// SetICEMulticastDNSMode controls if pion/ice queries and generates mDNS ICE Candidates
189func (e *SettingEngine) SetICEMulticastDNSMode(multicastDNSMode ice.MulticastDNSMode) {
190	e.candidates.MulticastDNSMode = multicastDNSMode
191}
192
193// SetMulticastDNSHostName sets a static HostName to be used by pion/ice instead of generating one on startup
194//
195// This should only be used for a single PeerConnection. Having multiple PeerConnections with the same HostName will cause
196// undefined behavior
197func (e *SettingEngine) SetMulticastDNSHostName(hostName string) {
198	e.candidates.MulticastDNSHostName = hostName
199}
200
201// SetICECredentials sets a staic uFrag/uPwd to be used by pion/ice
202//
203// This is useful if you want to do signalless WebRTC session, or having a reproducible environment with static credentials
204func (e *SettingEngine) SetICECredentials(usernameFragment, password string) {
205	e.candidates.UsernameFragment = usernameFragment
206	e.candidates.Password = password
207}
208
209// DisableCertificateFingerprintVerification disables fingerprint verification after DTLS Handshake has finished
210func (e *SettingEngine) DisableCertificateFingerprintVerification(isDisabled bool) {
211	e.disableCertificateFingerprintVerification = isDisabled
212}
213
214// SetDTLSReplayProtectionWindow sets a replay attack protection window size of DTLS connection.
215func (e *SettingEngine) SetDTLSReplayProtectionWindow(n uint) {
216	e.replayProtection.DTLS = &n
217}
218
219// SetSRTPReplayProtectionWindow sets a replay attack protection window size of SRTP session.
220func (e *SettingEngine) SetSRTPReplayProtectionWindow(n uint) {
221	e.disableSRTPReplayProtection = false
222	e.replayProtection.SRTP = &n
223}
224
225// SetSRTCPReplayProtectionWindow sets a replay attack protection window size of SRTCP session.
226func (e *SettingEngine) SetSRTCPReplayProtectionWindow(n uint) {
227	e.disableSRTCPReplayProtection = false
228	e.replayProtection.SRTCP = &n
229}
230
231// DisableSRTPReplayProtection disables SRTP replay protection.
232func (e *SettingEngine) DisableSRTPReplayProtection(isDisabled bool) {
233	e.disableSRTPReplayProtection = isDisabled
234}
235
236// DisableSRTCPReplayProtection disables SRTCP replay protection.
237func (e *SettingEngine) DisableSRTCPReplayProtection(isDisabled bool) {
238	e.disableSRTCPReplayProtection = isDisabled
239}
240
241// SetSDPMediaLevelFingerprints configures the logic for DTLS Fingerprint insertion
242// If true, fingerprints will be inserted in the sdp at the fingerprint
243// level, instead of the session level. This helps with compatibility with
244// some webrtc implementations.
245func (e *SettingEngine) SetSDPMediaLevelFingerprints(sdpMediaLevelFingerprints bool) {
246	e.sdpMediaLevelFingerprints = sdpMediaLevelFingerprints
247}
248
249// SetICETCPMux enables ICE-TCP when set to a non-nil value. Make sure that
250// NetworkTypeTCP4 or NetworkTypeTCP6 is enabled as well.
251func (e *SettingEngine) SetICETCPMux(tcpMux ice.TCPMux) {
252	e.iceTCPMux = tcpMux
253}
254
255// SetICEProxyDialer sets the proxy dialer interface based on golang.org/x/net/proxy.
256func (e *SettingEngine) SetICEProxyDialer(d proxy.Dialer) {
257	e.iceProxyDialer = d
258}
259
260// DisableMediaEngineCopy stops the MediaEngine from being copied. This allows a user to modify
261// the MediaEngine after the PeerConnection has been constructed. This is useful if you wish to
262// modify codecs after signaling. Make sure not to share MediaEngines between PeerConnections.
263func (e *SettingEngine) DisableMediaEngineCopy(isDisabled bool) {
264	e.disableMediaEngineCopy = isDisabled
265}
266