diff --git a/src/net/lookup_windows.go b/src/net/lookup_windows.go index d7b28f5e18571f..adf1e368e1eb5a 100644 --- a/src/net/lookup_windows.go +++ b/src/net/lookup_windows.go @@ -358,7 +358,8 @@ func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNS } rec := make([]*syscall.DNSRecord, 0, 10) for p := r; p != nil; p = p.Next { - if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer { + // in case of a local machine, DNS records are returned with DNSREC_QUESTION flag instead of DNS_ANSWER + if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer && p.Dw&dnsSectionMask != syscall.DnsSectionQuestion { continue } if p.Type != dnstype { diff --git a/src/net/lookup_windows_test.go b/src/net/lookup_windows_test.go index d3748f28c3f98b..62b61ed6c2f3ce 100644 --- a/src/net/lookup_windows_test.go +++ b/src/net/lookup_windows_test.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "internal/testenv" "os/exec" "reflect" @@ -18,6 +19,7 @@ import ( ) var nslookupTestServers = []string{"mail.golang.com", "gmail.com"} +var lookupTestIPs = []string{"8.8.8.8", "1.1.1.1"} func toJson(v interface{}) string { data, _ := json.Marshal(v) @@ -124,6 +126,54 @@ func TestNSLookupTXT(t *testing.T) { } } +func TestLookupLocalPTR(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + addr, err := localIP() + if err != nil { + t.Errorf("failed to get local ip: %s", err) + } + names, err := LookupAddr(addr.String()) + if err != nil { + t.Errorf("failed %s: %s", addr, err) + } + if len(names) == 0 { + t.Errorf("no results") + } + expected, err := lookupPTR(addr.String()) + if err != nil { + t.Logf("skipping failed lookup %s test: %s", addr.String(), err) + } + sort.Strings(expected) + sort.Strings(names) + if !reflect.DeepEqual(expected, names) { + t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names)) + } +} + +func TestLookupPTR(t *testing.T) { + testenv.MustHaveExternalNetwork(t) + + for _, addr := range lookupTestIPs { + names, err := LookupAddr(addr) + if err != nil { + t.Errorf("failed %s: %s", addr, err) + } + if len(names) == 0 { + t.Errorf("no results") + } + expected, err := lookupPTR(addr) + if err != nil { + t.Logf("skipping failed lookup %s test: %s", addr, err) + } + sort.Strings(expected) + sort.Strings(names) + if !reflect.DeepEqual(expected, names) { + t.Errorf("different results %s:\texp:%v\tgot:%v", addr, toJson(expected), toJson(names)) + } + } +} + type byPrefAndHost []*MX func (s byPrefAndHost) Len() int { return len(s) } @@ -230,3 +280,38 @@ func nslookupTXT(name string) (txt []string, err error) { } return } + +func ping(name string) (string, error) { + cmd := exec.Command("ping", "-n", "1", "-a", name) + stdoutStderr, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("%v: %v", err, string(stdoutStderr)) + } + r := strings.ReplaceAll(string(stdoutStderr), "\r\n", "\n") + return r, nil +} + +func lookupPTR(name string) (ptr []string, err error) { + var r string + if r, err = ping(name); err != nil { + return + } + ptr = make([]string, 0, 10) + rx := regexp.MustCompile(`(?m)^Pinging\s+([a-zA-Z0-9.\-]+)\s+\[.*$`) + for _, ans := range rx.FindAllStringSubmatch(r, -1) { + ptr = append(ptr, ans[1]+".") + } + return +} + +func localIP() (ip IP, err error) { + conn, err := Dial("udp", "golang.org:80") + if err != nil { + return nil, err + } + defer conn.Close() + + localAddr := conn.LocalAddr().(*UDPAddr) + + return localAddr.IP, nil +}