type Msg struct { MsgHdr Compress bool`json:"-"`// If true, the message will be compressed when converted to wire format. Question []Question // Holds the RR(s) of the question section. Answer []RR // Holds the RR(s) of the answer section. Ns []RR // Holds the RR(s) of the authority section. Extra []RR // Holds the RR(s) of the additional section. }
funcmain() { var msg dns.Msg fqdn := dns.Fqdn("baidu.com") msg.SetQuestion(fqdn,dns.TypeA) in ,err := dns.Exchange(&msg,"8.8.8.8:53") if err != nil { panic(err) } iflen(in.Answer) < 1{ fmt.Println("No records") return } for _,answer := range in.Answer{ if a, ok := answer.(*dns.A); ok { fmt.Println(a.A) } } }
funclookup(fqdn, serverAddr string) []result { var results []result var cfqdn = fqdn // Don't modify the original. for { cnames, err := lookupCNAME(cfqdn, serverAddr) if err == nil && len(cnames) > 0 { cfqdn = cnames[0] continue// We have to process the next CNAME. } ips, err := lookupA(cfqdn, serverAddr) if err != nil { break// There are no A records for this hostname. } for _, ip := range ips { results = append(results, result{IPAddress: ip, Hostname: fqdn}) } break// We have processed all the results. } return results }
for i := 0; i < *flWorkerCount; i++ { go worker(tracker, fqdns, gather, *flServerAddr) } for scanner.Scan() { fqdns <- fmt.Sprintf("%s.%s", scanner.Text(), *flDomain) }
7. 收集和显示结果
首先启动一个匿名的gorountine,它将收集工人的结果
1 2 3 4 5 6 7 8
gofunc() { for r := range gather { results = append(results, r...) } var e empty tracker <- e }()
funclookupA(fqdn, serverAddr string) ([]string, error) { var m dns.Msg var ips []string m.SetQuestion(dns.Fqdn(fqdn), dns.TypeA) in, err := dns.Exchange(&m, serverAddr) if err != nil { return ips, err } iflen(in.Answer) < 1 { return ips, errors.New("no answer") } for _, answer := range in.Answer { if a, ok := answer.(*dns.A); ok { ips = append(ips, a.A.String()) } } return ips, nil }
funclookupCNAME(fqdn, serverAddr string) ([]string, error) { var m dns.Msg var fqdns []string m.SetQuestion(dns.Fqdn(fqdn), dns.TypeCNAME) in, err := dns.Exchange(&m, serverAddr) if err != nil { return fqdns, err } iflen(in.Answer) < 1 { return fqdns, errors.New("no answer") } for _, answer := range in.Answer { if c, ok := answer.(*dns.CNAME); ok { fqdns = append(fqdns, c.Target) } } return fqdns, nil }
funclookup(fqdn, serverAddr string) []result { var results []result var cfqdn = fqdn // Don't modify the original. for { cnames, err := lookupCNAME(cfqdn, serverAddr) if err == nil && len(cnames) > 0 { cfqdn = cnames[0] continue// We have to process the next CNAME. } ips, err := lookupA(cfqdn, serverAddr) if err != nil { break// There are no A records for this hostname. } for _, ip := range ips { results = append(results, result{IPAddress: ip, Hostname: fqdn}) } break// We have processed all the results. } return results }
funcworker(tracker chan empty, fqdns chanstring, gather chan []result, serverAddr string) { for fqdn := range fqdns { results := lookup(fqdn, serverAddr) iflen(results) > 0 { gather <- results } } var e empty tracker <- e }
type empty struct{}
type result struct { IPAddress string Hostname string }