agent_config.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. package ice
  2. import (
  3. "time"
  4. "github.com/pion/logging"
  5. "github.com/pion/transport/vnet"
  6. "golang.org/x/net/proxy"
  7. )
  8. const (
  9. // defaultCheckInterval is the interval at which the agent performs candidate checks in the connecting phase
  10. defaultCheckInterval = 200 * time.Millisecond
  11. // keepaliveInterval used to keep candidates alive
  12. defaultKeepaliveInterval = 2 * time.Second
  13. // defaultDisconnectedTimeout is the default time till an Agent transitions disconnected
  14. defaultDisconnectedTimeout = 5 * time.Second
  15. // defaultFailedTimeout is the default time till an Agent transitions to failed after disconnected
  16. defaultFailedTimeout = 25 * time.Second
  17. // wait time before nominating a host candidate
  18. defaultHostAcceptanceMinWait = 0
  19. // wait time before nominating a srflx candidate
  20. defaultSrflxAcceptanceMinWait = 500 * time.Millisecond
  21. // wait time before nominating a prflx candidate
  22. defaultPrflxAcceptanceMinWait = 1000 * time.Millisecond
  23. // wait time before nominating a relay candidate
  24. defaultRelayAcceptanceMinWait = 2000 * time.Millisecond
  25. // max binding request before considering a pair failed
  26. defaultMaxBindingRequests = 7
  27. // the number of bytes that can be buffered before we start to error
  28. maxBufferSize = 1000 * 1000 // 1MB
  29. // wait time before binding requests can be deleted
  30. maxBindingRequestTimeout = 4000 * time.Millisecond
  31. )
  32. func defaultCandidateTypes() []CandidateType {
  33. return []CandidateType{CandidateTypeHost, CandidateTypeServerReflexive, CandidateTypeRelay}
  34. }
  35. // AgentConfig collects the arguments to ice.Agent construction into
  36. // a single structure, for future-proofness of the interface
  37. type AgentConfig struct {
  38. Urls []*URL
  39. // PortMin and PortMax are optional. Leave them 0 for the default UDP port allocation strategy.
  40. PortMin uint16
  41. PortMax uint16
  42. // LocalUfrag and LocalPwd values used to perform connectivity
  43. // checks. The values MUST be unguessable, with at least 128 bits of
  44. // random number generator output used to generate the password, and
  45. // at least 24 bits of output to generate the username fragment.
  46. LocalUfrag string
  47. LocalPwd string
  48. // MulticastDNSMode controls mDNS behavior for the ICE agent
  49. MulticastDNSMode MulticastDNSMode
  50. // MulticastDNSHostName controls the hostname for this agent. If none is specified a random one will be generated
  51. MulticastDNSHostName string
  52. // DisconnectedTimeout defaults to 5 seconds when this property is nil.
  53. // If the duration is 0, the ICE Agent will never go to disconnected
  54. DisconnectedTimeout *time.Duration
  55. // FailedTimeout defaults to 25 seconds when this property is nil.
  56. // If the duration is 0, we will never go to failed.
  57. FailedTimeout *time.Duration
  58. // KeepaliveInterval determines how often should we send ICE
  59. // keepalives (should be less then connectiontimeout above)
  60. // when this is nil, it defaults to 10 seconds.
  61. // A keepalive interval of 0 means we never send keepalive packets
  62. KeepaliveInterval *time.Duration
  63. // CheckInterval controls how often our task loop runs when in the
  64. // connecting state.
  65. CheckInterval *time.Duration
  66. // NetworkTypes is an optional configuration for disabling or enabling
  67. // support for specific network types.
  68. NetworkTypes []NetworkType
  69. // CandidateTypes is an optional configuration for disabling or enabling
  70. // support for specific candidate types.
  71. CandidateTypes []CandidateType
  72. LoggerFactory logging.LoggerFactory
  73. // MaxBindingRequests is the max amount of binding requests the agent will send
  74. // over a candidate pair for validation or nomination, if after MaxBindingRequests
  75. // the candidate is yet to answer a binding request or a nomination we set the pair as failed
  76. MaxBindingRequests *uint16
  77. // Lite agents do not perform connectivity check and only provide host candidates.
  78. Lite bool
  79. // NAT1To1IPCandidateType is used along with NAT1To1IPs to specify which candidate type
  80. // the 1:1 NAT IP addresses should be mapped to.
  81. // If unspecified or CandidateTypeHost, NAT1To1IPs are used to replace host candidate IPs.
  82. // If CandidateTypeServerReflexive, it will insert a srflx candidate (as if it was dervied
  83. // from a STUN server) with its port number being the one for the actual host candidate.
  84. // Other values will result in an error.
  85. NAT1To1IPCandidateType CandidateType
  86. // NAT1To1IPs contains a list of public IP addresses that are to be used as a host
  87. // candidate or srflx candidate. This is used typically for servers that are behind
  88. // 1:1 D-NAT (e.g. AWS EC2 instances) and to eliminate the need of server reflexisive
  89. // candidate gathering.
  90. NAT1To1IPs []string
  91. // HostAcceptanceMinWait specify a minimum wait time before selecting host candidates
  92. HostAcceptanceMinWait *time.Duration
  93. // HostAcceptanceMinWait specify a minimum wait time before selecting srflx candidates
  94. SrflxAcceptanceMinWait *time.Duration
  95. // HostAcceptanceMinWait specify a minimum wait time before selecting prflx candidates
  96. PrflxAcceptanceMinWait *time.Duration
  97. // HostAcceptanceMinWait specify a minimum wait time before selecting relay candidates
  98. RelayAcceptanceMinWait *time.Duration
  99. // Net is the our abstracted network interface for internal development purpose only
  100. // (see github.com/pion/transport/vnet)
  101. Net *vnet.Net
  102. // InterfaceFilter is a function that you can use in order to whitelist or blacklist
  103. // the interfaces which are used to gather ICE candidates.
  104. InterfaceFilter func(string) bool
  105. // InsecureSkipVerify controls if self-signed certificates are accepted when connecting
  106. // to TURN servers via TLS or DTLS
  107. InsecureSkipVerify bool
  108. // TCPMux will be used for multiplexing incoming TCP connections for ICE TCP.
  109. // Currently only passive candidates are supported. This functionality is
  110. // experimental and the API might change in the future.
  111. TCPMux TCPMux
  112. // UDPMux is used for multiplexing multiple incoming UDP connections on a single port
  113. // when this is set, the agent ignores PortMin and PortMax configurations and will
  114. // defer to UDPMux for incoming connections
  115. UDPMux UDPMux
  116. // UDPMuxSrflx is used for multiplexing multiple incoming UDP connections of server reflexive candidates
  117. // on a single port when this is set, the agent ignores PortMin and PortMax configurations and will
  118. // defer to UDPMuxSrflx for incoming connections
  119. // It embeds UDPMux to do the actual connection multiplexing
  120. UDPMuxSrflx UniversalUDPMux
  121. // Proxy Dialer is a dialer that should be implemented by the user based on golang.org/x/net/proxy
  122. // dial interface in order to support corporate proxies
  123. ProxyDialer proxy.Dialer
  124. // Accept aggressive nomination in RFC 5245 for compatible with chrome and other browsers
  125. AcceptAggressiveNomination bool
  126. }
  127. // initWithDefaults populates an agent and falls back to defaults if fields are unset
  128. func (config *AgentConfig) initWithDefaults(a *Agent) {
  129. if config.MaxBindingRequests == nil {
  130. a.maxBindingRequests = defaultMaxBindingRequests
  131. } else {
  132. a.maxBindingRequests = *config.MaxBindingRequests
  133. }
  134. if config.HostAcceptanceMinWait == nil {
  135. a.hostAcceptanceMinWait = defaultHostAcceptanceMinWait
  136. } else {
  137. a.hostAcceptanceMinWait = *config.HostAcceptanceMinWait
  138. }
  139. if config.SrflxAcceptanceMinWait == nil {
  140. a.srflxAcceptanceMinWait = defaultSrflxAcceptanceMinWait
  141. } else {
  142. a.srflxAcceptanceMinWait = *config.SrflxAcceptanceMinWait
  143. }
  144. if config.PrflxAcceptanceMinWait == nil {
  145. a.prflxAcceptanceMinWait = defaultPrflxAcceptanceMinWait
  146. } else {
  147. a.prflxAcceptanceMinWait = *config.PrflxAcceptanceMinWait
  148. }
  149. if config.RelayAcceptanceMinWait == nil {
  150. a.relayAcceptanceMinWait = defaultRelayAcceptanceMinWait
  151. } else {
  152. a.relayAcceptanceMinWait = *config.RelayAcceptanceMinWait
  153. }
  154. if config.DisconnectedTimeout == nil {
  155. a.disconnectedTimeout = defaultDisconnectedTimeout
  156. } else {
  157. a.disconnectedTimeout = *config.DisconnectedTimeout
  158. }
  159. if config.FailedTimeout == nil {
  160. a.failedTimeout = defaultFailedTimeout
  161. } else {
  162. a.failedTimeout = *config.FailedTimeout
  163. }
  164. if config.KeepaliveInterval == nil {
  165. a.keepaliveInterval = defaultKeepaliveInterval
  166. } else {
  167. a.keepaliveInterval = *config.KeepaliveInterval
  168. }
  169. if config.CheckInterval == nil {
  170. a.checkInterval = defaultCheckInterval
  171. } else {
  172. a.checkInterval = *config.CheckInterval
  173. }
  174. if config.CandidateTypes == nil || len(config.CandidateTypes) == 0 {
  175. a.candidateTypes = defaultCandidateTypes()
  176. } else {
  177. a.candidateTypes = config.CandidateTypes
  178. }
  179. }
  180. func (config *AgentConfig) initExtIPMapping(a *Agent) error {
  181. var err error
  182. a.extIPMapper, err = newExternalIPMapper(config.NAT1To1IPCandidateType, config.NAT1To1IPs)
  183. if err != nil {
  184. return err
  185. }
  186. if a.extIPMapper == nil {
  187. return nil // this may happen when config.NAT1To1IPs is an empty array
  188. }
  189. if a.extIPMapper.candidateType == CandidateTypeHost {
  190. if a.mDNSMode == MulticastDNSModeQueryAndGather {
  191. return ErrMulticastDNSWithNAT1To1IPMapping
  192. }
  193. candiHostEnabled := false
  194. for _, candiType := range a.candidateTypes {
  195. if candiType == CandidateTypeHost {
  196. candiHostEnabled = true
  197. break
  198. }
  199. }
  200. if !candiHostEnabled {
  201. return ErrIneffectiveNAT1To1IPMappingHost
  202. }
  203. } else if a.extIPMapper.candidateType == CandidateTypeServerReflexive {
  204. candiSrflxEnabled := false
  205. for _, candiType := range a.candidateTypes {
  206. if candiType == CandidateTypeServerReflexive {
  207. candiSrflxEnabled = true
  208. break
  209. }
  210. }
  211. if !candiSrflxEnabled {
  212. return ErrIneffectiveNAT1To1IPMappingSrflx
  213. }
  214. }
  215. return nil
  216. }