From a5b0c67d5f7d7957ee5fae8a2980f621d95ab719 Mon Sep 17 00:00:00 2001 From: Stephen McQuay Date: Thu, 18 Oct 2012 15:39:04 +0900 Subject: [PATCH] net: add LookupNS(domain string) Fixes #4224. R=golang-dev, dave, minux.ma, mikioh.mikioh, alex.brainman, rsc, herbert.fischer CC=golang-dev https://golang.org/cl/6675043 --- src/pkg/net/dnsclient.go | 5 +++++ src/pkg/net/lookup.go | 5 +++++ src/pkg/net/lookup_plan9.go | 15 +++++++++++++++ src/pkg/net/lookup_test.go | 14 ++++++++++++++ src/pkg/net/lookup_unix.go | 13 +++++++++++++ src/pkg/net/lookup_windows.go | 15 +++++++++++++++ 6 files changed, 67 insertions(+) diff --git a/src/pkg/net/dnsclient.go b/src/pkg/net/dnsclient.go index e69cb3188b..a7089d04a5 100644 --- a/src/pkg/net/dnsclient.go +++ b/src/pkg/net/dnsclient.go @@ -244,3 +244,8 @@ func (s byPref) sort() { } sort.Sort(s) } + +// An NS represents a single DNS NS record. +type NS struct { + Host string +} diff --git a/src/pkg/net/lookup.go b/src/pkg/net/lookup.go index 3a44e528eb..533b3511a2 100644 --- a/src/pkg/net/lookup.go +++ b/src/pkg/net/lookup.go @@ -47,6 +47,11 @@ func LookupMX(name string) (mx []*MX, err error) { return lookupMX(name) } +// LookupNS returns the DNS NS records for the given domain name. +func LookupNS(name string) (ns []*NS, err error) { + return lookupNS(name) +} + // LookupTXT returns the DNS TXT records for the given domain name. func LookupTXT(name string) (txt []string, err error) { return lookupTXT(name) diff --git a/src/pkg/net/lookup_plan9.go b/src/pkg/net/lookup_plan9.go index 2c698304b2..ae7cf79421 100644 --- a/src/pkg/net/lookup_plan9.go +++ b/src/pkg/net/lookup_plan9.go @@ -201,6 +201,21 @@ func lookupMX(name string) (mx []*MX, err error) { return } +func lookupNS(name string) (ns []*NS, err error) { + lines, err := queryDNS(name, "ns") + if err != nil { + return + } + for _, line := range lines { + f := getFields(line) + if len(f) < 4 { + continue + } + ns = append(ns, &NS{f[3]}) + } + return +} + func lookupTXT(name string) (txt []string, err error) { lines, err := queryDNS(name, "txt") if err != nil { diff --git a/src/pkg/net/lookup_test.go b/src/pkg/net/lookup_test.go index 84f089e869..990ade9e21 100644 --- a/src/pkg/net/lookup_test.go +++ b/src/pkg/net/lookup_test.go @@ -52,6 +52,20 @@ func TestGmailMX(t *testing.T) { } } +func TestGmailNS(t *testing.T) { + if testing.Short() || !*testExternal { + t.Logf("skipping test to avoid external network") + return + } + ns, err := LookupNS("gmail.com") + if err != nil { + t.Errorf("failed: %s", err) + } + if len(ns) == 0 { + t.Errorf("no results") + } +} + func TestGmailTXT(t *testing.T) { if testing.Short() || !*testExternal { t.Logf("skipping test to avoid external network") diff --git a/src/pkg/net/lookup_unix.go b/src/pkg/net/lookup_unix.go index d500a1240d..fa98eed5f2 100644 --- a/src/pkg/net/lookup_unix.go +++ b/src/pkg/net/lookup_unix.go @@ -119,6 +119,19 @@ func lookupMX(name string) (mx []*MX, err error) { return } +func lookupNS(name string) (ns []*NS, err error) { + _, records, err := lookup(name, dnsTypeNS) + if err != nil { + return + } + ns = make([]*NS, len(records)) + for i, r := range records { + r := r.(*dnsRR_NS) + ns[i] = &NS{r.Ns} + } + return +} + func lookupTXT(name string) (txt []string, err error) { _, records, err := lookup(name, dnsTypeTXT) if err != nil { diff --git a/src/pkg/net/lookup_windows.go b/src/pkg/net/lookup_windows.go index 99783e9756..2a8d01ff40 100644 --- a/src/pkg/net/lookup_windows.go +++ b/src/pkg/net/lookup_windows.go @@ -129,6 +129,21 @@ func lookupMX(name string) (mx []*MX, err error) { return mx, nil } +func lookupNS(name string) (ns []*NS, err error) { + var r *syscall.DNSRecord + e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil) + if e != nil { + return nil, os.NewSyscallError("LookupNS", e) + } + defer syscall.DnsRecordListFree(r, 1) + ns = make([]*NS, 0, 10) + for p := r; p != nil && p.Type == syscall.DNS_TYPE_NS; p = p.Next { + v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0])) + ns = append(ns, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."}) + } + return ns, nil +} + func lookupTXT(name string) (txt []string, err error) { var r *syscall.DNSRecord e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)