settingengine.go 14 KB

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