From: Russ Cox Date: Wed, 24 Jun 2015 12:39:44 +0000 (-0400) Subject: net: make LookupIP("1.2.3.4") behavior consistent X-Git-Tag: go1.5beta1~136 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=222b23aae9213e0ccd442fc4be51b0a27b5621be;p=gostls13.git net: make LookupIP("1.2.3.4") behavior consistent To date, the behavior has depended on whether we're using cgo and in turn what the host resolver does. Most host resolvers will "resolve" IP addresses, but the non-cgo pure Go path has not. This CL makes resolution of IP addresses always work, even if we're not using cgo and even if the host resolver does not "resolve" IP addresses. Fixes #11335. Change-Id: I19e82be968154d94904bb2f72e9c17893019a909 Reviewed-on: https://go-review.googlesource.com/11420 Reviewed-by: Brad Fitzpatrick --- diff --git a/src/net/ip_test.go b/src/net/ip_test.go index b1939cd08f..9c831d74b3 100644 --- a/src/net/ip_test.go +++ b/src/net/ip_test.go @@ -52,6 +52,47 @@ func TestParseIP(t *testing.T) { } } +func TestLookupWithIP(t *testing.T) { + _, err := LookupIP("") + if err == nil { + t.Errorf(`LookupIP("") succeeded, should fail`) + } + _, err = LookupHost("") + if err == nil { + t.Errorf(`LookupIP("") succeeded, should fail`) + } + + // Test that LookupHost and LookupIP, which normally + // expect host names, work with IP addresses. + for _, tt := range parseIPTests { + addrs, err := LookupHost(tt.in) + if tt.out != nil { + if len(addrs) != 1 || addrs[0] != tt.in || err != nil { + t.Errorf("LookupHost(%q) = %v, %v, want %v, nil", tt.in, addrs, err, []string{tt.in}) + } + } else { + // We can't control what the host resolver does; if it can resolve, say, + // 127.0.0.256 or fe80::1%911 or a host named 'abc', who are we to judge? + // Warn about these discrepancies but don't fail the test. + if err == nil { + t.Logf("warning: LookupHost(%q) = %v, want error", tt.in, addrs) + } + } + + ips, err := LookupIP(tt.in) + if tt.out != nil { + if len(ips) != 1 || !reflect.DeepEqual(ips[0], tt.out) || err != nil { + t.Errorf("LookupIP(%q) = %v, %v, want %v, nil", tt.in, ips, err, []IP{tt.out}) + } + } else { + // We can't control what the host resolver does. See above. + if err == nil { + t.Logf("warning: LookupIP(%q) = %v, want error", tt.in, ips) + } + } + } +} + func BenchmarkParseIP(b *testing.B) { testHookUninstaller.Do(uninstallTestHooks) diff --git a/src/net/lookup.go b/src/net/lookup.go index e2becc5a90..a7ceee823f 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -25,12 +25,28 @@ var protocols = map[string]int{ // LookupHost looks up the given host using the local resolver. // It returns an array of that host's addresses. func LookupHost(host string) (addrs []string, err error) { + // Make sure that no matter what we do later, host=="" is rejected. + // ParseIP, for example, does accept empty strings. + if host == "" { + return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host} + } + if ip := ParseIP(host); ip != nil { + return []string{host}, nil + } return lookupHost(host) } // LookupIP looks up host using the local resolver. // It returns an array of that host's IPv4 and IPv6 addresses. func LookupIP(host string) (ips []IP, err error) { + // Make sure that no matter what we do later, host=="" is rejected. + // ParseIP, for example, does accept empty strings. + if host == "" { + return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host} + } + if ip := ParseIP(host); ip != nil { + return []IP{ip}, nil + } addrs, err := lookupIPMerge(host) if err != nil { return