// Performs the actual query by service name (browse) or service instance name (lookup), // start response listeners goroutines and loops over the entries channel. func (c *client) query(params *LookupParams) error { var serviceName, serviceInstanceName string serviceName = fmt.Sprintf("%s.%s.", trimDot(params.Service), trimDot(params.Domain)) if params.Instance != "" { serviceInstanceName = fmt.Sprintf("%s.%s", params.Instance, serviceName) } // send the query m := new(dns.Msg) if serviceInstanceName != "" { m.Question = []dns.Question{ dns.Question{serviceInstanceName, dns.TypeSRV, dns.ClassINET}, dns.Question{serviceInstanceName, dns.TypeTXT, dns.ClassINET}, } m.RecursionDesired = false } else { m.SetQuestion(serviceName, dns.TypePTR) m.RecursionDesired = false } if err := c.sendQuery(m); err != nil { return err } return nil }
func main() { if len(os.Args) <= 1 { log.Printf("Usage: %s domain", os.Args[0]) os.Exit(1) } config, _ := dns.ClientConfigFromFile("/etc/resolv.conf") c := new(dns.Client) m := new(dns.Msg) m.SetQuestion(dns.Fqdn(os.Args[1]), dns.TypeMX) m.RecursionDesired = true r, _, err := c.Exchange(m, net.JoinHostPort(config.Servers[0], config.Port)) if r == nil { log.Fatalf("*** error: %s\n", err.Error()) } if r.Rcode != dns.RcodeSuccess { log.Fatalf(" *** invalid answer name %s after MX query for %s\n", os.Args[1], os.Args[1]) } // Stuff must be in the answer section for _, a := range r.Answer { fmt.Printf("%v\n", a) } }
// perform a DNS query and assert the reply code, number or answers, etc func assertExchange(t *testing.T, z string, ty uint16, minAnswers int, maxAnswers int, expErr int) *dns.Msg { c := new(dns.Client) c.UDPSize = testUDPBufSize m := new(dns.Msg) m.RecursionDesired = true m.SetQuestion(z, ty) m.SetEdns0(testUDPBufSize, false) // we don't want to play with truncation here... r, _, err := c.Exchange(m, fmt.Sprintf("127.0.0.1:%d", testPort)) t.Logf("Response:\n%+v\n", r) wt.AssertNoErr(t, err) if minAnswers == 0 && maxAnswers == 0 { wt.AssertStatus(t, r.Rcode, expErr, "DNS response code") } else { wt.AssertStatus(t, r.Rcode, dns.RcodeSuccess, "DNS response code") } answers := len(r.Answer) if minAnswers >= 0 && answers < minAnswers { wt.Fatalf(t, "Number of answers >= %d", minAnswers) } if maxAnswers >= 0 && answers > maxAnswers { wt.Fatalf(t, "Number of answers <= %d", maxAnswers) } return r }
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 }
func (c *Client) Discover(domain string, cb func(*dns.Msg)) { m := new(dns.Msg) m.SetQuestion(dns.Fqdn(domain), dns.TypePTR) m.RecursionDesired = true addr := &net.UDPAddr{ IP: net.ParseIP("224.0.0.251"), Port: 5353, } conn, err := net.ListenMulticastUDP("udp4", nil, addr) if err != nil { panic(err) } defer conn.Close() c.conn = conn out, err := m.Pack() if err != nil { panic(err) } _, err = conn.WriteToUDP(out, addr) if err != nil { panic(err) } c.handleReceiveMsg(domain, cb) }
// Perform a DNS query and assert the reply code, number or answers, etc func assertExchange(t *testing.T, z string, ty uint16, port int, minAnswers int, maxAnswers int, expErr int) (*dns.Msg, *dns.Msg) { require.NotEqual(t, 0, port, "invalid DNS server port") c := &dns.Client{ UDPSize: testUDPBufSize, } m := new(dns.Msg) m.RecursionDesired = true m.SetQuestion(z, ty) m.SetEdns0(testUDPBufSize, false) // we don't want to play with truncation here... lstAddr := fmt.Sprintf("127.0.0.1:%d", port) r, _, err := c.Exchange(m, lstAddr) t.Logf("Response from '%s':\n%+v\n", lstAddr, r) if err != nil { t.Errorf("Error when querying DNS server at %s: %s", lstAddr, err) } require.NoError(t, err) if minAnswers == 0 && maxAnswers == 0 { require.Equal(t, expErr, r.Rcode, "DNS response code") } else { require.Equal(t, dns.RcodeSuccess, r.Rcode, "DNS response code") } answers := len(r.Answer) if minAnswers >= 0 && answers < minAnswers { require.FailNow(t, fmt.Sprintf("Number of answers >= %d", minAnswers)) } if maxAnswers >= 0 && answers > maxAnswers { require.FailNow(t, fmt.Sprintf("Number of answers <= %d", maxAnswers)) } return m, r }
// 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)] udp := &dns.Client{Net: "udp", Timeout: DNSTimeout} in, _, err = udp.Exchange(m, ns) if err == dns.ErrTruncated { tcp := &dns.Client{Net: "tcp", Timeout: DNSTimeout} // If the TCP request suceeds, the err will reset to nil in, _, err = tcp.Exchange(m, ns) } if err == nil { break } } return }
// Async func (c *MDNSClient) SendQuery(name string, querytype uint16, insistent bool, responseCh chan<- *Response) { c.actionChan <- func() { query, found := c.inflight[name] if !found { m := new(dns.Msg) m.SetQuestion(name, querytype) m.RecursionDesired = false buf, err := m.Pack() if err != nil { responseCh <- &Response{err: err} close(responseCh) return } query = &inflightQuery{ name: name, id: m.Id, } if _, err = c.conn.WriteTo(buf, c.addr); err != nil { responseCh <- &Response{err: err} close(responseCh) return } c.inflight[name] = query } info := &responseInfo{ ch: responseCh, timeout: time.Now().Add(mDNSTimeout), insistent: insistent, } // Invariant on responseInfos: they are in ascending order of // timeout. Since we use a fixed interval from Now(), this // must be after all existing timeouts. query.responseInfos = append(query.responseInfos, info) } }
func makeDnsTxtRequest(domain string, server string) (string, error) { var err error var conn *dns.Conn if conn, err = dns.Dial("udp", server); err != nil { return "", err } m := new(dns.Msg) m.SetQuestion(dns.Fqdn(domain), dns.TypeTXT) m.RecursionDesired = true if err = conn.WriteMsg(m); err != nil { return "", err } var rm *dns.Msg if rm, err = conn.ReadMsg(); err != nil { return "", err } if txt, ok := rm.Answer[0].(*dns.TXT); !ok { return "", fmt.Errorf("No TXT Answer") } else { return strings.Join(txt.Txt, ""), nil } }
func createDKIMQuery(selector, domain string) *dns.Msg { q := fmt.Sprintf("%s._domainkey.%s", selector, domain) m := new(dns.Msg) m.SetQuestion(dns.Fqdn(q), dns.TypeTXT) m.RecursionDesired = true return m }
// Check that we can prune an answer func TestPrune(t *testing.T) { InitDefaultLogging(testing.Verbose()) Info.Println("TestPrune starting") questionMsg := new(dns.Msg) questionMsg.SetQuestion("name", dns.TypeA) questionMsg.RecursionDesired = true question := &questionMsg.Question[0] records := []ZoneRecord{ Record{"name", net.ParseIP("10.0.1.1"), 0, 0, 0}, Record{"name", net.ParseIP("10.0.1.2"), 0, 0, 0}, Record{"name", net.ParseIP("10.0.1.3"), 0, 0, 0}, Record{"name", net.ParseIP("10.0.1.4"), 0, 0, 0}, } reply := makeAddressReply(questionMsg, question, records, DefaultLocalTTL) reply.Answer[0].Header().Ttl = DefaultLocalTTL pruned := pruneAnswers(reply.Answer, 1) require.Equal(t, 1, len(pruned), "wrong number of answers") pruned = pruneAnswers(reply.Answer, 2) require.Equal(t, 2, len(pruned), "wrong number of answers") pruned = pruneAnswers(reply.Answer, 0) require.Equal(t, len(records), len(pruned), "wrong number of answers") }
func DnsQuery(query string, wg *sync.WaitGroup, config *dns.ClientConfig, cm *chanman.ChanMan) { defer wg.Done() dnsClient := new(dns.Client) message := new(dns.Msg) message.SetQuestion(dns.Fqdn(query), dns.TypeA) message.RecursionDesired = true response, rtt, err := dnsClient.Exchange(message, net.JoinHostPort(config.Servers[0], "53")) if err != nil { log.Println(err) cm.RunChan <- true } if response == nil { } else { if response.Rcode != dns.RcodeSuccess { log.Println(" query fail") } var stat = new(dnsstat.Info) stat.Rtt = rtt cm.StatsChan <- stat cm.RunChan <- true } }
func newMsg(host string, qClass uint16) *dns.Msg { m1 := new(dns.Msg) m1.Id = dns.Id() m1.RecursionDesired = true m1.Question = make([]dns.Question, 1) m1.Question[0] = dns.Question{host, qClass, dns.ClassINET} return m1 }
func localQuery(mychan chan DNSreply, qname string, qtype uint16) { var result DNSreply var trials uint result.qname = qname result.qtype = qtype result.r = nil result.err = errors.New("No name server to answer the question") localm := new(dns.Msg) localm.Id = dns.Id() localm.RecursionDesired = true localm.Question = make([]dns.Question, 1) localm.SetEdns0(EDNSBUFFERSIZE, false) // Even if no EDNS requested, see #9 May be we should retry without it if timeout? localc := new(dns.Client) localc.ReadTimeout = timeout localm.Question[0] = dns.Question{qname, qtype, dns.ClassINET} Tests: for trials = 0; trials < uint(*maxTrials); trials++ { Resolvers: for serverIndex := range conf.Servers { server := conf.Servers[serverIndex] result.nameserver = server // Brackets around the server address are necessary for IPv6 name servers r, rtt, err := localc.Exchange(localm, "["+server+"]:"+conf.Port) // Do not use net.JoinHostPort, see https://github.com/bortzmeyer/check-soa/commit/3e4edb13855d8c4016768796b2892aa83eda1933#commitcomment-2355543 if r == nil { result.r = nil result.err = err if strings.Contains(err.Error(), "timeout") { // Try another resolver break Resolvers } else { // We give in break Tests } } else { result.rtt = rtt if r.Rcode == dns.RcodeSuccess { // TODO: as a result, NODATA (NOERROR/ANSWER=0) are silently ignored (try "foo", for instance, the name exists but no IP address) // TODO: for rcodes like SERVFAIL, trying another resolver could make sense result.r = r result.err = nil break Tests } else { // All the other codes are errors. Yes, it may // happens that one resolver returns REFUSED // and the others work but we do not handle // this case. TODO: delete the resolver from // the list and try another one result.r = r result.err = errors.New(dns.RcodeToString[r.Rcode]) break Tests } } } } if *debug { fmt.Printf("DEBUG: end of DNS request \"%s\" / %d\n", qname, qtype) } mychan <- result }
// Perform probing & announcement //TODO: implement a proper probing & conflict resolution func (s *Server) probe() { q := new(dns.Msg) q.SetQuestion(s.service.ServiceInstanceName(), dns.TypePTR) q.RecursionDesired = false srv := &dns.SRV{ Hdr: dns.RR_Header{ Name: s.service.ServiceInstanceName(), Rrtype: dns.TypeSRV, Class: dns.ClassINET, Ttl: s.ttl, }, Priority: 0, Weight: 0, Port: uint16(s.service.Port), Target: s.service.HostName, } txt := &dns.TXT{ Hdr: dns.RR_Header{ Name: s.service.ServiceInstanceName(), Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: s.ttl, }, Txt: s.service.Text, } q.Ns = []dns.RR{srv, txt} randomizer := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < 3; i++ { if err := s.multicastResponse(q); err != nil { log.Println("[ERR] bonjour: failed to send probe:", err.Error()) } time.Sleep(time.Duration(randomizer.Intn(250)) * time.Millisecond) } resp := new(dns.Msg) resp.MsgHdr.Response = true resp.Answer = []dns.RR{} resp.Extra = []dns.RR{} s.composeLookupAnswers(resp, s.ttl) // From RFC6762 // The Multicast DNS responder MUST send at least two unsolicited // responses, one second apart. To provide increased robustness against // packet loss, a responder MAY send up to eight unsolicited responses, // provided that the interval between unsolicited responses increases by // at least a factor of two with every response sent. timeout := 1 * time.Second for i := 0; i < 3; i++ { if err := s.multicastResponse(resp); err != nil { log.Println("[ERR] bonjour: failed to send announcement:", err.Error()) } time.Sleep(timeout) timeout *= 2 } }
// DNS requests go to this function func dnsHandle(w dns.ResponseWriter, r *dns.Msg) { name := r.Question[0].Name if !namePattern.MatchString(name) { kilog.Debug("%v does not match pattern, forwarding", name) dnsForward(w, r) return } // otherwise kilog.Debug("%v matches pattern, handling", name) dnsLock.Lock() defer dnsLock.Unlock() // check in table first fakeIP, ok := nameToIP[name] if !ok { // place in table var nwIP string for { haha := ipAlloc().String() _, exists := ipToName[haha] if exists { continue } nwIP = haha break } fakeIP = nwIP nameToIP[name] = fakeIP ipToName[fakeIP] = name // remove in 30 minutes go func() { time.Sleep(time.Minute * 30) dnsLock.Lock() defer dnsLock.Unlock() delete(nameToIP, name) delete(ipToName, fakeIP) }() } // return the fake IP to the user resp := new(dns.A) resp.Hdr.Name = name resp.Hdr.Ttl = 1 // very short resp.Hdr.Class = dns.ClassINET resp.Hdr.Rrtype = dns.TypeA resp.A = net.ParseIP(fakeIP) towrite := new(dns.Msg) towrite.Id = r.Id towrite.RecursionAvailable = true towrite.RecursionDesired = true towrite.Response = true towrite.Question = r.Question towrite.Answer = make([]dns.RR, 1) towrite.Answer[0] = resp w.WriteMsg(towrite) kilog.Debug("returning mapping %v -> %v", name, fakeIP) }
func (d PodCheckAuth) authenticateToRegistry(token string, r types.DiagnosticResult) { resolvConf, err := getResolvConf(r) if err != nil { return // any errors have been reported via "r", env is very borked, test cannot proceed } msg := new(dns.Msg) msg.SetQuestion(registryHostname+".", dns.TypeA) msg.RecursionDesired = false result, completed := dnsQueryWithTimeout(msg, resolvConf.Servers[0], 2) switch { case !completed: r.Error("DP1006", nil, fmt.Sprintf("DNS resolution for registry address %s timed out; this could indicate problems with DNS resolution or networking", registryHostname)) return case result.err != nil: r.Error("DP1016", nil, fmt.Sprintf("DNS resolution for registry address %s returned an error; container DNS is likely incorrect. The error was: %v", registryHostname, result.err)) return case result.in == nil, len(result.in.Answer) == 0: r.Warn("DP1007", nil, fmt.Sprintf("DNS resolution for registry address %s returned no results; either the integrated registry is not deployed, or container DNS configuration is incorrect.", registryHostname)) return } // first try the secure connection in case they followed directions to secure the registry // (https://docs.openshift.org/latest/install_config/install/docker_registry.html#securing-the-registry) cacert, err := ioutil.ReadFile(d.MasterCaPath) // TODO: we assume same CA as master - better choice? if err != nil { r.Error("DP1008", err, fmt.Sprintf("Failed to read CA cert file %s:\n%v", d.MasterCaPath, err)) return } pool := x509.NewCertPool() if !pool.AppendCertsFromPEM(cacert) { r.Error("DP1009", err, fmt.Sprintf("Could not use cert from CA cert file %s:\n%v", d.MasterCaPath, err)) return } noSecClient := http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return fmt.Errorf("no redirect expected") }, Timeout: time.Second * 2, } secClient := noSecClient secClient.Transport = knet.SetTransportDefaults(&http.Transport{TLSClientConfig: &tls.Config{RootCAs: pool}}) secError := processRegistryRequest(&secClient, fmt.Sprintf("https://%s:%s/v2/", registryHostname, registryPort), token, r) if secError == nil { return // made the request successfully enough to diagnose } switch { case strings.Contains(secError.Error(), "tls: oversized record received"), strings.Contains(secError.Error(), "server gave HTTP response to HTTPS"): r.Debug("DP1015", "docker-registry not secured; falling back to cleartext connection") if nosecError := processRegistryRequest(&noSecClient, fmt.Sprintf("http://%s:%s/v2/", registryHostname, registryPort), token, r); nosecError != nil { r.Error("DP1013", nosecError, fmt.Sprintf("Unexpected error authenticating to the integrated registry:\n(%T) %[1]v", nosecError)) } default: r.Error("DP1013", secError, fmt.Sprintf("Unexpected error authenticating to the integrated registry:\n(%T) %[1]v", secError)) } }
/* * makeMessage() - construct DNS message structure */ func makeMessage(c *Context, qname, qtype, qclass string, ext Extension) *dns.Msg { m := new(dns.Msg) m.Id = dns.Id() if c.restype == RESOLUTION_STUB { m.RecursionDesired = true } else { m.RecursionDesired = false } if c.adflag { m.AuthenticatedData = true } if c.cdflag { m.CheckingDisabled = true } if ext["dnssec_return_status"] || ext["dnssec_return_only_secure"] || ext["dnssec_return_validation_chain"] { opt := new(dns.OPT) opt.Hdr.Name = "." opt.Hdr.Rrtype = dns.TypeOPT opt.SetDo() m.Extra = append(m.Extra, opt) } m.Question = make([]dns.Question, 1) qtype_int, ok := dns.StringToType[strings.ToUpper(qtype)] if !ok { fmt.Printf("%s: Unrecognized query type.\n", qtype) return nil } qclass_int, ok := dns.StringToClass[strings.ToUpper(qclass)] if !ok { fmt.Printf("%s: Unrecognized query class.\n", qclass) return nil } m.Question[0] = dns.Question{qname, qtype_int, qclass_int} return m }
func (d *DnsDomain) Test() bool { if !(*Domain)(d).Test() { return false } fqdn := d.Name if strings.HasPrefix(fqdn, "*.") { fqdn = "a" + fqdn[1:] } if !strings.HasSuffix(fqdn, ".") { fqdn = fqdn + "." } any_ok := false d.DNS = make([]*DnsRecords, 0, len(DNS_servers)) for name, addr := range DNS_servers { records := new(DnsRecords) records.Server = name records.NS = addr d.DNS = append(d.DNS, records) req := new(dns.Msg) req.Id = dns.Id() req.RecursionDesired = true req.Question = []dns.Question{ dns.Question{fqdn, dns.TypeA, dns.ClassINET}, } resp, err := dns_client.Exchange(req, addr) if err != nil { records.Status = 900 records.Message = err.Error() continue } records.IPs = make([]string, 0, len(resp.Answer)) for _, rr := range resp.Answer { switch a := rr.(type) { case *dns.RR_A: records.IPs = append(records.IPs, a.A.String()) } } if len(records.IPs) > 0 { any_ok = true } else { records.Status = 900 records.Message = "No records" } } return any_ok }
func DnsGetDoaminIP(domain string) (string, error) { m := new(dns.Msg) m.Id = dns.Id() m.SetQuestion(dns.Fqdn(domain), dns.TypeA) m.RecursionDesired = true res, err := dnsQuery(m) if nil != err { return "", err } return pickIP(res), nil }
func pinguer(domain string) (int, int) { // Every N steps, we will tell the stats module how many requests we sent maxRequestID := big.NewInt(65536) errors := 0 totalSent := 0 questionRecord := dns.TypeA message := new(dns.Msg).SetQuestion(domain, questionRecord) if iterative { message.RecursionDesired = false } for reqnumber := 0; count == 0 || reqnumber < count; reqnumber++ { // Try to resolve the domain if randomIds { // Regenerate message Id to avoid servers dropping (seemingly) duplicate messages newid, _ := rand.Int(rand.Reader, maxRequestID) message.Id = uint16(newid.Int64()) } start := time.Now() err := dnsExchange(resolver, message) elapsedMilliSeconds := float64(time.Since(start)) / float64(time.Millisecond) if err != nil { if verbose { fmt.Printf("%s error: % (%s)\n", domain, err, resolver) } errors++ } totalSent++ // Display results of the ping fmt.Printf( "ping %s with %s %s: %.3fms\n", resolver, dns.TypeToString[questionRecord], domain, elapsedMilliSeconds, ) time.Sleep(time.Duration(pingInterval) * time.Millisecond) } return totalSent, errors }
// Returns true if domain has a Name Server associated func queryNS(domain string, dnsServers []string, proto string) (int, error) { c := new(dns.Client) c.ReadTimeout = time.Duration(2 * time.Second) c.WriteTimeout = time.Duration(2 * time.Second) c.Net = proto m := new(dns.Msg) m.RecursionDesired = true dnsServer := dnsServers[rand.Intn(len(dnsServers))] m.SetQuestion(dns.Fqdn(domain), dns.TypeNS) in, _, err := c.Exchange(m, dnsServer+":53") if err == nil { return in.Rcode, err } return dns.RcodeRefused, err }
func (resolver ConsulDnsAddressResolver) Resolve(service string) (string, error) { m1 := new(dns.Msg) m1.Id = dns.Id() m1.RecursionDesired = true m1.SetQuestion(service+".service.consul.", dns.TypeA) c := new(dns.Client) in, _, err := c.Exchange(m1, resolver.ServerAddress) if err != nil { log.Fatal(err) } if len(in.Answer) > 0 { log.Println(in.Answer) return in.Answer[0].(*dns.A).A.String(), nil } return "", errors.New("Could not resolve service address") }
// ExampleRetrieverFunc uses a specific resolver with custom timeouts. func ExampleRetrieverFunc() { discovery := dnsdisco.NewDiscovery("jabber", "tcp", "registro.br") discovery.SetRetriever(dnsdisco.RetrieverFunc(func(service, proto, name string) (servers []*net.SRV, err error) { client := dns.Client{ ReadTimeout: 2 * time.Second, WriteTimeout: 2 * time.Second, } name = strings.TrimRight(name, ".") z := fmt.Sprintf("_%s._%s.%s.", service, proto, name) var request dns.Msg request.SetQuestion(z, dns.TypeSRV) request.RecursionDesired = true response, _, err := client.Exchange(&request, "8.8.8.8:53") if err != nil { return nil, err } for _, rr := range response.Answer { if srv, ok := rr.(*dns.SRV); ok { servers = append(servers, &net.SRV{ Target: srv.Target, Port: srv.Port, Priority: srv.Priority, Weight: srv.Weight, }) } } return })) // Retrieve the servers if err := discovery.Refresh(); err != nil { fmt.Println(err) return } target, port := discovery.Choose() fmt.Printf("Target: %s\nPort: %d\n", target, port) // Output: // Target: jabber.registro.br. // Port: 5269 }
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 }
// 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 }
func (this *UDPNameServer) BuildQueryA(domain string, id uint16) *alloc.Buffer { buffer := alloc.NewBuffer() msg := new(dns.Msg) msg.Id = id msg.RecursionDesired = true msg.Question = []dns.Question{ dns.Question{ Name: dns.Fqdn(domain), Qtype: dns.TypeA, Qclass: dns.ClassINET, }} writtenBuffer, _ := msg.PackBuffer(buffer.Value) buffer.Slice(0, len(writtenBuffer)) return buffer }
func fakeMsg(dom string, rrHeader uint16, proto string, serverPort int) (*dns.Msg, error) { qc := uint16(dns.ClassINET) c := new(dns.Client) c.Net = proto m := new(dns.Msg) m.Question = make([]dns.Question, 1) m.Question[0] = dns.Question{ Name: dns.Fqdn(dom), Qtype: rrHeader, Qclass: qc, } m.RecursionDesired = true in, _, err := c.Exchange(m, "127.0.0.1:"+strconv.Itoa(serverPort)) return in, err }
// Lookup the IP address using HypeDNS func lookupHypeDNS(hostname string) (response string, err error) { c := new(dns.Client) m := new(dns.Msg) m.SetQuestion(dns.Fqdn(hostname), dns.TypeAAAA) m.RecursionDesired = true r, _, err := c.Exchange(m, "[fc5d:baa5:61fc:6ffd:9554:67f0:e290:7535]:53") if r == nil || err != nil { return } // Stuff must be in the answer section for _, a := range r.Answer { columns := strings.Fields(a.String()) //column 4 holds the ip address return padIPv6(net.ParseIP(columns[4])), nil } return }
func linearResolver(threadID int, domain string, sentCounterCh chan<- result) { // Resolve the domain as fast as possible if verbose { fmt.Printf("Starting thread #%d.\n", threadID) } // Every N steps, we will tell the stats module how many requests we sent displayStep := 5 maxRequestID := big.NewInt(65536) errors := 0 message := new(dns.Msg).SetQuestion(domain, dns.TypeA) if iterative { message.RecursionDesired = false } for { for i := 0; i < displayStep; i++ { // Try to resolve the domain if randomIds { // Regenerate message Id to avoid servers dropping (seemingly) duplicate messages newid, _ := rand.Int(rand.Reader, maxRequestID) message.Id = uint16(newid.Int64()) } if flood { go dnsExchange(resolver, message) } else { err := dnsExchange(resolver, message) if err != nil { if verbose { fmt.Printf("%s error: % (%s)\n", domain, err, resolver) } errors++ } } } // Update the counter of sent requests and requests sentCounterCh <- result{displayStep, errors} errors = 0 } }