コード例 #1
2
ファイル: generic.go プロジェクト: tomsteele/blacksheepwall
// LookupIP returns hostname from PTR record or error.
func LookupIP(ip, serverAddr string) ([]string, error) {
	names := []string{}
	m := &dns.Msg{}
	ipArpa, err := dns.ReverseAddr(ip)
	if err != nil {
		return names, err
	}
	m.SetQuestion(ipArpa, dns.TypePTR)
	in, err := dns.Exchange(m, serverAddr+":53")
	if err != nil {
		return names, err
	}
	if len(in.Answer) < 1 {
		return names, errors.New("no Answer")
	}

	for _, a := range in.Answer {
		if ptr, ok := a.(*dns.PTR); ok {
			if strings.Contains(ptr.Ptr, strings.Join(strings.Split(ip, "."), "-")) {
				continue
			}
			names = append(names, strings.TrimRight(ptr.Ptr, "."))
		}
	}

	if len(names) < 1 {
		return names, errors.New("no PTR")
	}

	return names, nil
}
コード例 #2
0
ファイル: remote.go プロジェクト: vsayer/gokeyless
func (c *Client) lookupIPs(host string) (ips []net.IP, err error) {
	m := new(dns.Msg)
	for _, resolver := range c.Resolvers {
		m.SetQuestion(dns.Fqdn(host), dns.TypeA)
		if in, err := dns.Exchange(m, resolver); err == nil {
			for _, rr := range in.Answer {
				if a, ok := rr.(*dns.A); ok {
					ips = append(ips, a.A)
				}
			}
		} else {
			log.Debug(err)
		}

		m.SetQuestion(dns.Fqdn(host), dns.TypeAAAA)
		if in, err := dns.Exchange(m, resolver); err == nil {
			for _, rr := range in.Answer {
				if aaaa, ok := rr.(*dns.AAAA); ok {
					ips = append(ips, aaaa.AAAA)
				}
			}
		} else {
			log.Debug(err)
		}
	}
	if len(ips) != 0 {
		return ips, nil
	}

	return net.LookupIP(host)
}
コード例 #3
0
ファイル: dns.go プロジェクト: cdshann/minimega
func dnsClient() {
	rand.Seed(time.Now().UnixNano())
	t := NewEventTicker(*f_mean, *f_stddev, *f_min, *f_max)
	m := new(dns.Msg)

	for {
		t.Tick()
		h, _ := randomHost()
		d := randomDomain()
		var t uint16

		if *f_dnsv4 {
			t = dns.TypeA
		} else if *f_dnsv6 {
			t = dns.TypeAAAA
		} else {
			t = randomQuestionType()
		}

		m.SetQuestion(dns.Fqdn(d), t)
		log.Debug("dns client: question=%v", m.Question)
		in, err := dns.Exchange(m, h+addr)
		if err != nil {
			log.Debug(err.Error())
		} else {
			log.Debug("dns client: answer=%v", in)
			dnsReportChan <- 1
		}
	}
}
コード例 #4
0
ファイル: resolver.go プロジェクト: mohoff/DNS-Resolver
// Uses github.com/miekg/dns package, in order to invoke one query.
func (r *Resolver) queryDNSServer(dnsServer, domainname, rrType string, edns bool) (*dns.Msg, error) {
	fqdn := dns.Fqdn(domainname)
	r.dnsQueryMsg.Id = dns.Id()
	r.dnsQueryMsg.SetQuestion(fqdn, dns.StringToType[rrType])
	dnsServerSocket := dnsServer + ":" + DNSPORT
	dnsResponseMsg, err := dns.Exchange(r.dnsQueryMsg, dnsServerSocket)

	if err != nil {
		return nil, errors.New("dns.Exchange() failed")
	}

	if r.dnsQueryMsg.Id != dnsResponseMsg.Id {
		log.Printf("DNS msgID mismatch: Request-ID(%d), Response-ID(%d)", r.dnsQueryMsg.Id, dnsResponseMsg.Id)
		return nil, errors.New("DNS Msg-ID mismatch")
	}

	if dnsResponseMsg.MsgHdr.Truncated {
		if r.dnsClient.Net == "tcp" {
			return nil, errors.New("Received invalid truncated Msg over TCP") //fmt.Errorf("Got truncated message on tcp")
		}
		if edns {
			r.dnsClient.Net = "tcp"
		}
		return r.queryDNSServer(dnsServer, domainname, rrType, !edns)
	}

	return dnsResponseMsg, nil
}
コード例 #5
0
ファイル: dns_challenge.go プロジェクト: aebruno/lego
// dnsQuery will query a nameserver, iterating through the supplied servers as it retries
// The nameserver should include a port, to facilitate testing where we talk to a mock dns server.
func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive bool) (in *dns.Msg, err error) {
	m := new(dns.Msg)
	m.SetQuestion(fqdn, rtype)
	m.SetEdns0(4096, false)

	if !recursive {
		m.RecursionDesired = false
	}

	// Will retry the request based on the number of servers (n+1)
	for i := 1; i <= len(nameservers)+1; i++ {
		ns := nameservers[i%len(nameservers)]
		in, err = dns.Exchange(m, ns)

		if err == dns.ErrTruncated {
			tcp := &dns.Client{Net: "tcp"}
			// If the TCP request suceeds, the err will reset to nil
			in, _, err = tcp.Exchange(m, ns)
		}

		if err == nil {
			break
		}
	}
	return
}
コード例 #6
0
ファイル: main.go プロジェクト: saljam/dnsproxy
// resolver responds to all DNS A record requests with an address from addrpool,
// maintaining  a mapping to the domain's actual IP address.
func resolver(w dns.ResponseWriter, req *dns.Msg) {
	msg, err := dns.Exchange(req, dnsserver)
	if err != nil {
		log.Printf("Couldn't query: %v", err)
		// TODO return error Msg
		return
	}

	for _, rr := range msg.Answer {
		// TODO do this for only one record, delete the others.
		if rr.Header().Rrtype == dns.TypeA {
			a := rr.(*dns.A)

			addrpool.Lock()
			addr, ok := addrpool.domains[a.Hdr.Name]
			// Maybe we should also Get it on ok to push it up the LRU cache.
			if !ok {
				addrpool.pool.RemoveOldest()
				addrpool.pool.Add(ip4touint32(addrpool.freeaddr), a.Hdr.Name)
				log.Printf("Adding %v -> %s", addrpool.freeaddr, a.Hdr.Name)
				addr = addrpool.freeaddr
				addrpool.domains[a.Hdr.Name] = addr
			}
			addrpool.Unlock()

			log.Println("Type A:", a.A)
			a.A = addr
			a.Hdr.Ttl = 1
		}
	}

	w.WriteMsg(msg)
}
コード例 #7
0
ファイル: main_test.go プロジェクト: levenlabs/struggledns
func Test(t *T) {
	m1 := new(dns.Msg)
	m1.SetQuestion(testDomain, dns.TypeA)
	w1 := getWriter()
	go func() {
		handleRequest(w1, m1)
	}()
	r1 := <-w1.ReplyCh
	require.Len(t, r1.Answer, 1)

	m2 := new(dns.Msg)
	m2.SetQuestion(testDomain, dns.TypeA)
	r2, err := dns.Exchange(m2, "8.8.8.8:53")
	require.Nil(t, err)
	require.Len(t, r2.Answer, 1)

	assert.Equal(t, r2.Rcode, r1.Rcode)
	a1 := strings.Split(r1.Answer[0].String(), "\t")
	//example: a-test.mysuperfancyapi.com., 245, IN, A, 192.95.20.208
	//we want to overwrite the TTL since that will be different
	a2 := strings.Split(r2.Answer[0].String(), "\t")
	a1[1] = ""
	a2[1] = ""
	assert.Equal(t, a2, a1)
}
コード例 #8
0
func (self *DnsResolver) lookupHost(host string, triesLeft int) ([]net.IP, error) {
	m1 := new(dns.Msg)
	m1.Id = dns.Id()
	m1.RecursionDesired = true
	m1.Question = make([]dns.Question, 1)
	m1.Question[0] = dns.Question{dns.Fqdn(host), dns.TypeA, dns.ClassINET}
	in, err := dns.Exchange(m1, self.Servers[self.r.Intn(len(self.Servers))])

	result := []net.IP{}

	if err != nil {
		if strings.HasSuffix(err.Error(), "i/o timeout") && triesLeft > 0 {
			triesLeft -= 1
			return self.lookupHost(host, triesLeft)
		} else {
			return result, err
		}
	}

	if in != nil && in.Rcode != dns.RcodeSuccess {
		return result, errors.New(dns.RcodeToString[in.Rcode])
	}

	for _, record := range in.Answer {
		if t, ok := record.(*dns.A); ok {
			result = append(result, t.A)
		}
	}
	return result, err
}
コード例 #9
0
ファイル: dns_discover.go プロジェクト: anthonyikeda/fargo
func findTXT(fqdn string) ([]string, time.Duration, error) {
	defaultTTL := 120 * time.Second
	query := new(dns.Msg)
	query.SetQuestion(fqdn, dns.TypeTXT)
	dnsServerAddr, err := findDnsServerAddr()
	if err != nil {
		log.Error("Failure finding DNS server, err=%s", err.Error())
		return nil, defaultTTL, err
	}

	response, err := dns.Exchange(query, dnsServerAddr)
	if err != nil {
		log.Error("Failure resolving name %s err=%s", fqdn, err.Error())
		return nil, defaultTTL, err
	}
	if len(response.Answer) < 1 {
		err := fmt.Errorf("no Eureka discovery TXT record returned for name=%s", fqdn)
		log.Error("no answer for name=%s err=%s", fqdn, err.Error())
		return nil, defaultTTL, err
	}
	if response.Answer[0].Header().Rrtype != dns.TypeTXT {
		err := fmt.Errorf("did not receive TXT record back from query specifying TXT record. This should never happen.")
		log.Error("Failure resolving name %s err=%s", fqdn, err.Error())
		return nil, defaultTTL, err
	}
	txt := response.Answer[0].(*dns.TXT)
	ttl := response.Answer[0].Header().Ttl
	if ttl < 60 {
		ttl = 60
	}

	return txt.Txt, time.Duration(ttl) * time.Second, nil
}
コード例 #10
0
ファイル: resolver.go プロジェクト: turbobytes/recursive
func (r *Resolver) exchange(m *dns.Msg, a string, original []string) (res *dns.Msg, err error) {
	question := m.Question[0]
	sort.Strings(original)
	key := cachekey{question, fmt.Sprintf("%v", original)}
	if r.Debug {
		log.Println("KEY: ", key)
	}
	rt, ok := r.cache.Get(key)
	if ok {
		if r.Debug {
			log.Println("Cache HIT")
		}
		r1 := rt.(*dns.Msg)
		res = r1.Copy()
		return
	}
	if r.Debug {
		log.Println("Cache MISS")
		log.Println("QUERY: ", question.Name, "via", a)
	}
	res, err = dns.Exchange(m, a)
	if err != nil {
		if r.Debug {
			log.Println(err)
		}
		return
	}
	//Retry in case it was truncated
	if res.Truncated {
		if r.Debug {
			log.Println("truncated, retrying with tcp")
		}

		cl := new(dns.Client)
		cl.Net = "tcp"
		res, _, err = cl.Exchange(m, a)
		if err != nil {
			if r.Debug {
				log.Println(err)
			}
			return
		}

	}

	if r.Debug {
		log.Println(res)
	}
	if res.Rcode != dns.RcodeSuccess {
		return
	}
	if r.Debug {
		log.Println("Inserting into cache")
	}
	r.cache.Add(key, res)
	return
}
コード例 #11
0
ファイル: server_test.go プロジェクト: zeus911/skydns
func TestCacheTruncated(t *testing.T) {
	s := newTestServer(t, true)
	m := &dns.Msg{}
	m.SetQuestion("skydns.test.", dns.TypeSRV)
	m.Truncated = true
	s.rcache.InsertMessage(cache.QuestionKey(m.Question[0], false), m)

	// Now asking for this should result in a non-truncated answer.
	resp, _ := dns.Exchange(m, "127.0.0.1:"+StrPort)
	if resp.Truncated {
		t.Fatal("truncated bit should be false")
	}
}
コード例 #12
0
ファイル: https_test.go プロジェクト: albertito/dnss
//
// === Tests ===
//
func dnsQuery(addr string, qtype uint16) (*dns.Msg, dns.RR, error) {
	m := new(dns.Msg)
	m.SetQuestion(addr, qtype)
	in, err := dns.Exchange(m, DNSAddr)

	if err != nil {
		return nil, nil, err
	} else if len(in.Answer) > 0 {
		return in, in.Answer[0], nil
	} else {
		return in, nil, nil
	}
}
コード例 #13
0
ファイル: util.go プロジェクト: RomainVabre/origin
// dnsQueryWithTimeout makes a DNS query that times out quickly.
// The timeout is in seconds.
// The boolean response indicates whether the request completed before the timeout.
func dnsQueryWithTimeout(msg *dns.Msg, server string, timeout int) (dnsResponse, bool) {
	rchan := make(chan dnsResponse, 1)
	go func() {
		in, err := dns.Exchange(msg, server+":53")
		rchan <- dnsResponse{in, err}
	}()
	select {
	case <-time.After(time.Second * time.Duration(timeout)):
		return dnsResponse{}, false
	case result := <-rchan:
		return result, true
	}
}
コード例 #14
0
ファイル: main.go プロジェクト: khassib/garden-windows
func udp(address string) {
	m := new(dns.Msg)
	m.SetQuestion("google.com.", dns.TypeA)
	ret, err := dns.Exchange(m, address)
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	if t, ok := ret.Answer[0].(*dns.A); ok {
		fmt.Println(t)
		fmt.Printf("Connected successfully to %s", address)
	}
}
コード例 #15
0
ファイル: mail.go プロジェクト: nymsio/nyms-verifier
func lookupDKIM(selector, domain string) (string, error) {
	// We do this the hard way with a low level library because:
	//  https://code.google.com/p/go/issues/detail?id=8540
	serv, err := getDNSServerAddress()
	if err != nil {
		return "", err
	}
	m := createDKIMQuery(selector, domain)
	r, err := dns.Exchange(m, serv)
	if err != nil {
		return "", fmt.Errorf("failed TXT lookup s=%s d=%s: %v", selector, domain, err)
	}
	return processDKIMResponse(selector, domain, r)
}
コード例 #16
0
ファイル: generic.go プロジェクト: tomsteele/blacksheepwall
// LookupSRV returns a hostname from SRV record or error.
func LookupSRV(fqdn, dnsServer string) (string, error) {
	m := &dns.Msg{}
	m.SetQuestion(dns.Fqdn(fqdn), dns.TypeSRV)
	in, err := dns.Exchange(m, dnsServer+":53")
	if err != nil {
		return "", err
	}
	if len(in.Answer) < 1 {
		return "", errors.New("no Answer")
	}
	if a, ok := in.Answer[0].(*dns.SRV); ok {
		return strings.TrimRight(a.Target, "."), nil
	}
	return "", errors.New("no SRV record returned")
}
コード例 #17
0
ファイル: domain.go プロジェクト: hanjianwei/nx
func domainIPs(domain string) []net.IP {
	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn(domain), dns.TypeA)

	in, err := dns.Exchange(m, "8.8.8.8:53")
	if err != nil {
		log.Fatal(err)
	}

	ips := make([]net.IP, len(in.Answer))
	for i, a := range in.Answer {
		ips[i] = a.(*dns.A).A
	}

	return ips
}
コード例 #18
0
ファイル: generic.go プロジェクト: tomsteele/blacksheepwall
// LookupName returns IPv4 address from A record or error.
func LookupName(fqdn, serverAddr string) (string, error) {
	m := &dns.Msg{}
	m.SetQuestion(dns.Fqdn(fqdn), dns.TypeA)
	in, err := dns.Exchange(m, serverAddr+":53")
	if err != nil {
		return "", err
	}
	if len(in.Answer) < 1 {
		return "", errors.New("no Answer")
	}
	if a, ok := in.Answer[0].(*dns.A); ok {
		ip := a.A.String()
		return ip, nil
	}
	return "", errors.New("no A record returned")
}
コード例 #19
0
ファイル: generic.go プロジェクト: tomsteele/blacksheepwall
// LookupCname returns a fqdn address from CNAME record or error.
func LookupCname(fqdn, serverAddr string) (string, error) {
	m := &dns.Msg{}
	m.SetQuestion(dns.Fqdn(fqdn), dns.TypeCNAME)
	in, err := dns.Exchange(m, serverAddr+":53")
	if err != nil {
		return "", err
	}
	if len(in.Answer) < 1 {
		return "", errors.New("no Answer")
	}
	if a, ok := in.Answer[0].(*dns.CNAME); ok {
		name := a.Target
		return strings.TrimRight(name, "."), nil
	}
	return "", errors.New("no CNAME record returned")
}
コード例 #20
0
func findSoaNs(domain string) (string, string, string) {

	var cname string
	var soa string
	var ns string

	add := func(c, s, n string) {
		cname += c
		soa += s
		ns += n
		return
	}

	cname += domain + ","
	m1 := new(dns.Msg)
	m1.Id = dns.Id()
	m1.RecursionDesired = true
	m1.Question = make([]dns.Question, 1)
	m1.Question[0] = dns.Question{domain, dns.TypeSOA, dns.ClassINET}
	in, _ := dns.Exchange(m1, (cf.Servers[1] + ":53"))
	rrList := [...][]dns.RR{in.Answer, in.Ns, in.Extra}

	for _, rr := range rrList {
		for i := len(rr) - 1; i >= 0; i-- {
			switch rr[i].Header().Rrtype {
			case dns.TypeCNAME:
				temp_cname := rr[i].(*dns.CNAME)
				add(findSoaNs(temp_cname.Target))
				//				fmt.Println(  "temp_cname:" , temp_cname )
				return cname, soa, ns
				break
			case dns.TypeNS:
				temp_ns := rr[i].(*dns.NS)
				ns += temp_ns.Ns + "," // + "|" +  fmt.Sprint( temp_ns.Hdr.Ttl ) + ","
				//				fmt.Println(  "temp_ns:" , temp_ns )
				break
			case dns.TypeSOA:
				temp_soa := rr[i].(*dns.SOA)
				soa += temp_soa.Ns + "," // + "|" + fmt.Sprint( temp_soa.Hdr.Ttl ) + ","
				//				fmt.Println( "temp_soa:" , temp_soa )
				break
			}
		}
	}

	return cname, soa, ns
}
コード例 #21
0
ファイル: multidialer.go プロジェクト: ChoyesYan/goproxy
func (d *MultiDialer) lookupHost2(name string, dnsserver net.IP) (addrs []string, err error) {
	m := &dns.Msg{}

	switch {
	case d.ForceIPv6:
		m.SetQuestion(dns.Fqdn(name), dns.TypeAAAA)
	case d.DisableIPv6:
		m.SetQuestion(dns.Fqdn(name), dns.TypeA)
	default:
		m.SetQuestion(dns.Fqdn(name), dns.TypeANY)
	}

	r, err := dns.Exchange(m, net.JoinHostPort(dnsserver.String(), "53"))
	if err != nil {
		return nil, err
	}

	if len(r.Answer) < 1 {
		return nil, errors.New("no Answer")
	}

	addrs = []string{}

	for _, rr := range r.Answer {
		var addr string

		if aaaa, ok := rr.(*dns.AAAA); ok {
			addr = aaaa.AAAA.String()
		}
		if a, ok := rr.(*dns.A); ok {
			addr = a.A.String()
		}

		if addr == "" {
			continue
		}

		if _, ok := d.IPBlackList.GetQuiet(addr); ok {
			continue
		}

		addrs = append(addrs, addr)
	}

	return addrs, nil
}
コード例 #22
0
ファイル: grpctodns.go プロジェクト: albertito/dnss
func (s *Server) Query(ctx context.Context, in *pb.RawMsg) (*pb.RawMsg, error) {
	tr := trace.New("grpctodns", "Query")
	defer tr.Finish()

	r := &dns.Msg{}
	err := r.Unpack(in.Data)
	if err != nil {
		return nil, err
	}

	if glog.V(3) {
		tr.LazyPrintf(util.QuestionsToString(r.Question))
	}

	// TODO: we should create our own IDs, in case different users pick the
	// same id and we pass that upstream.
	from_up, err := dns.Exchange(r, s.Upstream)
	if err != nil {
		msg := fmt.Sprintf("dns exchange error: %v", err)
		glog.Info(msg)
		tr.LazyPrintf(msg)
		tr.SetError()
		return nil, err
	}

	if from_up == nil {
		err = fmt.Errorf("no response from upstream")
		tr.LazyPrintf(err.Error())
		tr.SetError()
		return nil, err
	}

	if glog.V(3) {
		util.TraceAnswer(tr, from_up)
	}

	buf, err := from_up.Pack()
	if err != nil {
		glog.Infof("   error packing: %v", err)
		tr.LazyPrintf("error packing: %v", err)
		tr.SetError()
		return nil, err
	}

	return &pb.RawMsg{Data: buf}, nil
}
コード例 #23
0
// dnsQuery sends a DNS query to the given nameserver.
// The nameserver should include a port, to facilitate testing where we talk to a mock dns server.
func dnsQuery(fqdn string, rtype uint16, nameserver string, recursive bool) (in *dns.Msg, err error) {
	m := new(dns.Msg)
	m.SetQuestion(fqdn, rtype)
	m.SetEdns0(4096, false)

	if !recursive {
		m.RecursionDesired = false
	}

	in, err = dns.Exchange(m, nameserver)
	if err == dns.ErrTruncated {
		tcp := &dns.Client{Net: "tcp"}
		in, _, err = tcp.Exchange(m, nameserver)
	}

	return
}
コード例 #24
0
ファイル: client.go プロジェクト: AndrewBurian/CovertDNS
/* ----------------------------------------------------------------------------
FUNCTION

Name:		DNSSend

Prototype:	func dnssend(msg, remote string)

Developer:	Andrew Burian

Created On:	2015-09-24

Parameters:
	msg string
		the message to send
	remote string
		the remote address of the DNS server

Return Values:
	(none)

Description:
	Handles the DNS sending of the encoded message

Revisions:
	(none)
---------------------------------------------------------------------------- */
func dnssend(msg, remote string) {

	// create a new dns query message
	dnsMessage := new(dns.Msg)

	// embedd message in url
	msg += ".dl.cloudfront.com"

	// set the question (auto creates a RR)
	dnsMessage.SetQuestion(dns.Fqdn(msg), dns.TypeA)

	// send and wait on response (syncronous)
	_, err := dns.Exchange(dnsMessage, remote+":53")

	if err != nil {
		panic(err)
	}
}
コード例 #25
0
ファイル: generic.go プロジェクト: tomsteele/blacksheepwall
// LookupNS returns the names servers for a domain.
func LookupNS(domain, serverAddr string) ([]string, error) {
	servers := []string{}
	m := &dns.Msg{}
	m.SetQuestion(dns.Fqdn(domain), dns.TypeNS)
	in, err := dns.Exchange(m, serverAddr+":53")
	if err != nil {
		return servers, err
	}
	if len(in.Answer) < 1 {
		return servers, errors.New("no Answer")
	}
	for _, a := range in.Answer {
		if ns, ok := a.(*dns.NS); ok {
			servers = append(servers, ns.Ns)
		}
	}
	return servers, nil
}
コード例 #26
0
ファイル: dns_test.go プロジェクト: nanopack/shaman
func ResolveIt(domain string, rType uint16, badop ...bool) (*dns.Msg, error) {
	// root domain if not already
	root(&domain)
	m := new(dns.Msg)
	m.SetQuestion(domain, rType)

	if len(badop) > 0 {
		m.Opcode = dns.OpcodeStatus
	}

	// ask the dns server
	r, err := dns.Exchange(m, config.DnsListen)
	if err != nil {
		return nil, fmt.Errorf("Failed to exchange - %v", err)
	}

	return r, nil
}
コード例 #27
0
ファイル: dns.go プロジェクト: fangdingjun/gpp
/*
ResolveAAAA return all the ipv6 address for the domain name.

If domain name resolve failed or get an emppty ip list will return an error.

Instead of system dns utils, we use the pure go dns library from https://github.com/miekg/dns

*/
func ResolveAAAA(d string) ([]net.IP, error) {
	m := new(dns.Msg)
	m.SetQuestion(dns.Fqdn(d), dns.TypeAAAA)
	m1, err := dns.Exchange(m, getDNSServer())
	if err != nil {
		return nil, err
	}
	if m1.Rcode != dns.RcodeSuccess {
		return nil, errors.New("dns resolve failed")
	}

	var res []net.IP
	for _, rr := range m1.Answer {
		if a, ok := rr.(*dns.AAAA); ok {
			res = append(res, a.AAAA)
		}
	}
	return res, nil
}
コード例 #28
0
ファイル: multidialer.go プロジェクト: taiping-z/goproxy
func (d *MultiDialer) LookupHost2(name string, dnsserver net.IP) (addrs []string, err error) {
	m := &dns.Msg{}

	if d.ForceIPv6 {
		m.SetQuestion(dns.Fqdn(name), dns.TypeAAAA)
	} else {
		m.SetQuestion(dns.Fqdn(name), dns.TypeANY)
	}

	r, err := dns.Exchange(m, net.JoinHostPort(dnsserver.String(), "53"))
	if err != nil {
		return nil, err
	}

	if len(r.Answer) < 1 {
		return nil, errors.New("no Answer")
	}

	addrs = []string{}

	for _, rr := range r.Answer {
		if d.ForceIPv6 {
			if aaaa, ok := rr.(*dns.AAAA); ok {
				ip := aaaa.AAAA.String()
				if _, ok := d.IPBlackList.GetQuiet(ip); ok {
					continue
				}
				addrs = append(addrs, ip)
			}
		} else {
			if a, ok := rr.(*dns.A); ok {
				ip := a.A.String()
				if _, ok := d.IPBlackList.GetQuiet(ip); ok {
					continue
				}
				addrs = append(addrs, ip)
			}
		}
	}

	return addrs, nil
}
コード例 #29
0
// DereferenceService returns a random target and a node associated with given
// service name.
func DereferenceService(
	service string) (target string, node string, err error) {
	// Perform DNS lookup.
	msg := new(dns.Msg)
	msg.SetQuestion(service+".service.consul.", dns.TypeSRV)
	r, err := dns.Exchange(msg, DNSServerFlag.Get())
	if err != nil {
		return "", "", err
	}
	if r.Rcode == dns.RcodeNameError {
		return "", "", ErrServiceNotFound
	}
	if r.Rcode != dns.RcodeSuccess {
		return "", "", fmt.Errorf("DNS lookup failed with code %v", r.Rcode)
	}
	if len(r.Answer) == 0 {
		return "", "", ErrServiceNotFound
	}

	// Pick the first entry.
	answer := r.Answer[0]
	srvRecord, ok := answer.(*dns.SRV)
	if !ok {
		return "", "", fmt.Errorf("Found non-SRV answer")
	}

	node = strings.SplitN(srvRecord.Target, ".", 2)[0]

	// Look for the IP address of that entry.
	for _, extra := range r.Extra {
		aRecord, ok := extra.(*dns.A)
		if !ok {
			continue
		}
		if extra.Header().Name == srvRecord.Target {
			addr := aRecord.A.String() + ":" + strconv.Itoa(int(srvRecord.Port))
			return addr, node, nil
		}
	}
	return "", "", fmt.Errorf("Service node has no IP associated")
}
コード例 #30
0
ファイル: generic.go プロジェクト: tomsteele/blacksheepwall
// LookupMX returns all the mx servers for a domain.
func LookupMX(domain, serverAddr string) ([]string, error) {
	servers := []string{}
	m := &dns.Msg{}
	m.SetQuestion(dns.Fqdn(domain), dns.TypeMX)
	in, err := dns.Exchange(m, serverAddr+":53")
	if err != nil {
		return servers, err
	}
	if len(in.Answer) < 1 {
		return servers, errors.New("no Answer")
	}
	for _, a := range in.Answer {
		if mx, ok := a.(*dns.MX); ok {
			parts := strings.Split(mx.Mx, " ")
			if len(parts) < 1 {
				continue
			}
			servers = append(servers, parts[len(parts)-1])
		}
	}
	return servers, nil
}