package hosts import ( "net" "time" ) const ( notIPQuery = 0 _IP4Query = 4 _IP6Query = 6 ) var ( zeroDuration = time.Duration(0) ) type Hosts interface { Get(domain string, family int) ([]net.IP, time.Duration, bool) } type ProviderList struct { providers []Provider } type Provider interface { Get(domain string) ([]string, time.Duration, bool) } func NewHosts(providers []Provider) Hosts { return &ProviderList{providers} } /* Match local /etc/hosts file first, remote redis records second */ func (h *ProviderList) Get(domain string, family int) ([]net.IP, time.Duration, bool) { var sips []string var ok bool var ip net.IP var ips []net.IP var ttl time.Duration for _, provider := range h.providers { sips, ttl, ok = provider.Get(domain) if ok { break } } if sips == nil { return nil, zeroDuration, false } for _, sip := range sips { switch family { case _IP4Query: ip = net.ParseIP(sip).To4() case _IP6Query: ip = net.ParseIP(sip).To16() default: continue } if ip != nil { ips = append(ips, ip) } } return ips, ttl, ips != nil }