settingengine.go 17 KB

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