1// +build !js 2 3package webrtc 4 5import ( 6 "github.com/pion/ice/v2" 7 "github.com/pion/webrtc/v3/pkg/rtcerr" 8) 9 10// ICEServer describes a single STUN and TURN server that can be used by 11// the ICEAgent to establish a connection with a peer. 12type ICEServer struct { 13 URLs []string `json:"urls"` 14 Username string `json:"username,omitempty"` 15 Credential interface{} `json:"credential,omitempty"` 16 CredentialType ICECredentialType `json:"credentialType,omitempty"` 17} 18 19func (s ICEServer) parseURL(i int) (*ice.URL, error) { 20 return ice.ParseURL(s.URLs[i]) 21} 22 23func (s ICEServer) validate() error { 24 _, err := s.urls() 25 return err 26} 27 28func (s ICEServer) urls() ([]*ice.URL, error) { 29 urls := []*ice.URL{} 30 31 for i := range s.URLs { 32 url, err := s.parseURL(i) 33 if err != nil { 34 return nil, &rtcerr.InvalidAccessError{Err: err} 35 } 36 37 if url.Scheme == ice.SchemeTypeTURN || url.Scheme == ice.SchemeTypeTURNS { 38 // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.2) 39 if s.Username == "" || s.Credential == nil { 40 return nil, &rtcerr.InvalidAccessError{Err: ErrNoTurnCredentials} 41 } 42 url.Username = s.Username 43 44 switch s.CredentialType { 45 case ICECredentialTypePassword: 46 // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.3) 47 password, ok := s.Credential.(string) 48 if !ok { 49 return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredentials} 50 } 51 url.Password = password 52 53 case ICECredentialTypeOauth: 54 // https://www.w3.org/TR/webrtc/#set-the-configuration (step #11.3.4) 55 if _, ok := s.Credential.(OAuthCredential); !ok { 56 return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredentials} 57 } 58 59 default: 60 return nil, &rtcerr.InvalidAccessError{Err: ErrTurnCredentials} 61 } 62 } 63 64 urls = append(urls, url) 65 } 66 67 return urls, nil 68} 69