func LookupIP(domain string, timeout int) ([]string, error) { var c dns.Client var err error ips := []string{} domain = strings.TrimRight(domain, ".") + "." c.DialTimeout = time.Duration(timeout) * time.Millisecond c.ReadTimeout = time.Duration(timeout) * time.Millisecond c.WriteTimeout = time.Duration(timeout) * time.Millisecond m := new(dns.Msg) m.SetQuestion(domain, dns.TypeA) ret, _, err := c.Exchange(m, "114.114.114.114:53") if err != nil { domain = strings.TrimRight(domain, ".") e := fmt.Sprintf("lookup error: %s, %s", domain, err.Error()) return ips, errors.New(e) } for _, i := range ret.Answer { result := strings.Split(i.String(), "\t") if result[3] == "A" && IsIP(result[4]) { ips = append(ips, result[4]) } } return ips, err }
func lookupHost(host string, config *dns.ClientConfig) (addrs []string, err error) { if utilNet.IsValidIpv4(host) || utilNet.IsValidIpv6(host) { return []string{host}, nil } if host == "localhost" { return []string{"127.0.0.1", "::1"}, nil } c := new(dns.Client) c.DialTimeout = DialTimeout c.ReadTimeout = ReadTimeout c.WriteTimeout = WriteTimeout m := new(dns.Msg) m.SetQuestion(dns.Fqdn(host), dns.TypeA) var r *dns.Msg for i := 0; i < len(config.Servers); i++ { r, _, err = c.Exchange(m, config.Servers[i]+":"+config.Port) if err != nil { continue } err = nil } if err != nil { return nil, e.Forward(err) } if r.Rcode != dns.RcodeSuccess { return nil, e.New("can't resolve %v", host) } addrs = make([]string, 0, 10) for _, a := range r.Answer { if addr, ok := a.(*dns.A); ok { addrs = append(addrs, addr.A.String()) } } m.SetQuestion(dns.Fqdn(host), dns.TypeAAAA) for i := 0; i < len(config.Servers); i++ { r, _, err = c.Exchange(m, config.Servers[0]+":"+config.Port) if err != nil { continue } err = nil } if err != nil { return nil, e.Forward(err) } if r.Rcode != dns.RcodeSuccess { return nil, e.New("no success") } for _, a := range r.Answer { if addr, ok := a.(*dns.AAAA); ok { addrs = append(addrs, addr.AAAA.String()) } } return }
func LookupIp(ip string) (host string, err error) { if !utilNet.IsValidIpv4(ip) && !utilNet.IsValidIpv6(ip) { return "", e.New("not a valid ip address") } if ip == "127.0.0.1" || ip == "::1" { return "localhost", nil } config, err := dns.ClientConfigFromFile(ConfigurationFile) if err != nil { return "", e.Forward(err) } config.Timeout = Timeout c := new(dns.Client) c.DialTimeout = DialTimeout c.ReadTimeout = ReadTimeout c.WriteTimeout = WriteTimeout m := new(dns.Msg) rev, err := dns.ReverseAddr(ip) if err != nil { return "", e.Forward(err) } m.SetQuestion(rev, dns.TypePTR) var r *dns.Msg for i := 0; i < len(config.Servers); i++ { r, _, err = c.Exchange(m, config.Servers[i]+":"+config.Port) if err != nil { continue } err = nil } if err != nil { return "", e.Forward(err) } if r.Rcode != dns.RcodeSuccess { return "", e.New("can't resolve %v", ip) } for _, a := range r.Answer { if ptr, ok := a.(*dns.PTR); ok { return strings.TrimSuffix(ptr.Ptr, "."), nil } } return "", e.New("no ptr available") }
// defaultExtResolver queries other nameserver, potentially recurses; callers should probably be invoking extResolver // instead since that's the pluggable entrypoint into external resolution. func (res *Resolver) defaultExtResolver(r *dns.Msg, nameserver string, proto string, cnt int) (*dns.Msg, error) { var in *dns.Msg var err error c := new(dns.Client) c.Net = proto var t time.Duration = 5 * 1e9 if res.config.Timeout != 0 { t = time.Duration(int64(res.config.Timeout * 1e9)) } c.DialTimeout = t c.ReadTimeout = t c.WriteTimeout = t in, _, err = c.Exchange(r, nameserver) if err != nil { return in, err } // recurse if (in != nil) && (len(in.Answer) == 0) && (!in.MsgHdr.Authoritative) && (len(in.Ns) > 0) && (err != nil) { if cnt == recurseCnt { logging.CurLog.NonMesosRecursed.Inc() } if cnt > 0 { if soa, ok := (in.Ns[0]).(*dns.SOA); ok { return res.defaultExtResolver(r, net.JoinHostPort(soa.Ns, "53"), proto, cnt-1) } } } return in, err }