Skip to content

net: fix resolving local windows machine ptr #32214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/net/lookup_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
85 changes: 85 additions & 0 deletions src/net/lookup_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"errors"
"fmt"
"internal/testenv"
"os/exec"
"reflect"
Expand All @@ -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)
Expand Down Expand Up @@ -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) }
Expand Down Expand Up @@ -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
}