1package ice 2 3import ( 4 "net" 5 "strings" 6) 7 8// CandidateHost is a candidate of type host 9type CandidateHost struct { 10 candidateBase 11 12 network string 13} 14 15// CandidateHostConfig is the config required to create a new CandidateHost 16type CandidateHostConfig struct { 17 CandidateID string 18 Network string 19 Address string 20 Port int 21 Component uint16 22 Priority uint32 23 Foundation string 24 TCPType TCPType 25} 26 27// NewCandidateHost creates a new host candidate 28func NewCandidateHost(config *CandidateHostConfig) (*CandidateHost, error) { 29 candidateID := config.CandidateID 30 31 if candidateID == "" { 32 candidateID = globalCandidateIDGenerator.Generate() 33 } 34 35 c := &CandidateHost{ 36 candidateBase: candidateBase{ 37 id: candidateID, 38 address: config.Address, 39 candidateType: CandidateTypeHost, 40 component: config.Component, 41 port: config.Port, 42 tcpType: config.TCPType, 43 foundationOverride: config.Foundation, 44 priorityOverride: config.Priority, 45 }, 46 network: config.Network, 47 } 48 49 if !strings.HasSuffix(config.Address, ".local") { 50 ip := net.ParseIP(config.Address) 51 if ip == nil { 52 return nil, ErrAddressParseFailed 53 } 54 55 if err := c.setIP(ip); err != nil { 56 return nil, err 57 } 58 } else { 59 // Until mDNS candidate is resolved assume it is UDPv4 60 c.candidateBase.networkType = NetworkTypeUDP4 61 } 62 63 return c, nil 64} 65 66func (c *CandidateHost) setIP(ip net.IP) error { 67 networkType, err := determineNetworkType(c.network, ip) 68 if err != nil { 69 return err 70 } 71 72 c.candidateBase.networkType = networkType 73 c.candidateBase.resolvedAddr = createAddr(networkType, ip, c.port) 74 75 return nil 76} 77