Gerrit Bot has uploaded this change for review.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/p6PaMVPM
Fixes: #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: c9c2946104fce6b96f3aa59a2103712f53e68e94
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 170 insertions(+), 20 deletions(-)
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 21aa91f..d441620 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -526,7 +526,7 @@
func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []string, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
// Use entries from /etc/hosts if they match.
- addrs = lookupStaticHost(name)
+ addrs, _ = lookupStaticHost(name)
if len(addrs) > 0 || order == hostLookupFiles {
return
}
@@ -543,8 +543,9 @@
}
// lookup entries from /etc/hosts
-func goLookupIPFiles(name string) (addrs []IPAddr) {
- for _, haddr := range lookupStaticHost(name) {
+func goLookupIPFiles(name string) (addrs []IPAddr, cname string) {
+ addr, cname := lookupStaticHost(name)
+ for _, haddr := range addr {
haddr, zone := splitHostZone(haddr)
if ip := ParseIP(haddr); ip != nil {
addr := IPAddr{IP: ip, Zone: zone}
@@ -565,9 +566,20 @@
func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
- addrs = goLookupIPFiles(name)
- if len(addrs) > 0 || order == hostLookupFiles {
- return addrs, dnsmessage.Name{}, nil
+ var canonical string
+ addrs, canonical = goLookupIPFiles(name)
+
+ if len(addrs) > 0 {
+ var err error
+ cname, err = dnsmessage.NewName(canonical)
+ if err != nil {
+ return nil, dnsmessage.Name{}, err
+ }
+ return addrs, cname, nil
+ }
+
+ if order == hostLookupFiles {
+ return nil, dnsmessage.Name{}, errors.New("no entry in /etc/hosts file")
}
}
if !isDomainName(name) {
@@ -723,9 +735,18 @@
sortByRFC6724(addrs)
if len(addrs) == 0 {
if order == hostLookupDNSFiles {
- addrs = goLookupIPFiles(name)
+ var canonical string
+ addrs, canonical = goLookupIPFiles(name)
+ if len(addrs) > 0 {
+ var err error
+ cname, err = dnsmessage.NewName(canonical)
+ if err != nil {
+ return nil, dnsmessage.Name{}, err
+ }
+ return addrs, cname, nil
+ }
}
- if len(addrs) == 0 && lastErr != nil {
+ if lastErr != nil {
return nil, dnsmessage.Name{}, lastErr
}
}
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 14366ec..07e0866 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -2161,3 +2161,53 @@
t.Errorf("records = [%v]; want [%v]", strings.Join(records, " "), want[0])
}
}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesFilesOnlyMode(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/aliases"
+ mode := hostLookupFiles
+
+ for _, v := range lookupStaticHostAliasesTest {
+ testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+ }
+}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesFilesDNSMode(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/aliases"
+ mode := hostLookupFilesDNS
+
+ for _, v := range lookupStaticHostAliasesTest {
+ testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+ }
+}
+
+var goLookupIPCNAMEOrderDNSFilesModeTests = []struct {
+ lookup, res string
+}{
+ //127.0.1.1
+ {"8438random7333name2", "8438random7333name2.example.test"},
+}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesDNSFilesMode(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/aliases"
+ mode := hostLookupDNSFiles
+
+ for _, v := range goLookupIPCNAMEOrderDNSFilesModeTests {
+ testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+ }
+}
+
+func testGoLookupIPCNAMEOrderHostsAliases(t *testing.T, mode hostLookupOrder, lookup, lookupRes string) {
+ ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)}
+ for _, in := range ins {
+ _, res, err := goResolver.goLookupIPCNAMEOrder(context.Background(), "ip", in, mode)
+ if err != nil {
+ t.Errorf("expected err == nil, but got error: %v", err)
+ }
+ if res.String() != lookupRes {
+ t.Errorf("goLookupIPCNAMEOrder(%v): should be: '%v', but: '%v'", in, lookupRes, res)
+ }
+ }
+}
diff --git a/src/net/hosts.go b/src/net/hosts.go
index e604031..e74643b 100644
--- a/src/net/hosts.go
+++ b/src/net/hosts.go
@@ -28,6 +28,11 @@
return ip.String() + "%" + zone
}
+type byName struct {
+ addrs []string
+ canonicalName string
+}
+
// hosts contains known host entries.
var hosts struct {
sync.Mutex
@@ -36,7 +41,7 @@
// name. It would be part of DNS labels, a FQDN or an absolute
// FQDN.
// For now the key is converted to lower case for convenience.
- byName map[string][]string
+ byName map[string]byName
// Key for the list of host names must be a literal IP address
// including IPv6 address with zone identifier.
@@ -62,8 +67,9 @@
return
}
- hs := make(map[string][]string)
+ hs := make(map[string]byName)
is := make(map[string][]string)
+
var file *file
if file, _ = open(hp); file == nil {
return
@@ -81,12 +87,22 @@
if addr == "" {
continue
}
+
+ var canonical string
for i := 1; i < len(f); i++ {
name := absDomainName(f[i])
h := []byte(f[i])
lowerASCIIBytes(h)
key := absDomainName(string(h))
- hs[key] = append(hs[key], addr)
+
+ if i == 1 {
+ canonical = key
+ }
+
+ hs[key] = byName{
+ addrs: append(hs[key].addrs, addr),
+ canonicalName: canonical,
+ }
is[addr] = append(is[addr], name)
}
}
@@ -100,8 +116,8 @@
file.close()
}
-// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
-func lookupStaticHost(host string) []string {
+// lookupStaticHost looks up the addresses and the cannonical name for the given host from /etc/hosts.
+func lookupStaticHost(host string) ([]string, string) {
hosts.Lock()
defer hosts.Unlock()
readHosts()
@@ -111,13 +127,13 @@
lowerASCIIBytes(lowerHost)
host = string(lowerHost)
}
- if ips, ok := hosts.byName[absDomainName(host)]; ok {
- ipsCp := make([]string, len(ips))
- copy(ipsCp, ips)
- return ipsCp
+ if byName, ok := hosts.byName[absDomainName(host)]; ok {
+ ipsCp := make([]string, len(byName.addrs))
+ copy(ipsCp, byName.addrs)
+ return ipsCp, byName.canonicalName
}
}
- return nil
+ return nil, ""
}
// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
diff --git a/src/net/hosts_test.go b/src/net/hosts_test.go
index 7291914..013ea78 100644
--- a/src/net/hosts_test.go
+++ b/src/net/hosts_test.go
@@ -72,7 +72,7 @@
func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) {
ins := []string{ent.in, absDomainName(ent.in), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
for _, in := range ins {
- addrs := lookupStaticHost(in)
+ addrs, _ := lookupStaticHost(in)
if !reflect.DeepEqual(addrs, ent.out) {
t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", hostsPath, in, addrs, ent.out)
}
@@ -157,7 +157,7 @@
ent := staticHostEntry{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}}
testStaticHost(t, testHookHostsPath, ent)
// Modify the addresses return by lookupStaticHost.
- addrs := lookupStaticHost(ent.in)
+ addrs, _ := lookupStaticHost(ent.in)
for i := range addrs {
addrs[i] += "junk"
}
@@ -173,3 +173,42 @@
}
testStaticAddr(t, testHookHostsPath, ent)
}
+
+var lookupStaticHostAliasesTest = []struct {
+ lookup, res string
+}{
+ //127.0.0.1
+ {"test", "test"},
+ //127.0.0.2
+ {"test2.example.com", "test2.example.com"},
+ {"test2", "test2.example.com."},
+ //127.0.0.3
+ {"test3.example.com", "test3"},
+ {"test3", "test3"},
+ //127.0.0.4
+ {"example.com", "example.com"},
+ //127.0.0.5
+ {"test5.example.com", "test4.example.com"},
+ {"test5", "test4.example.com"},
+ {"test4", "test4.example.com"},
+ {"test4.example.com", "test4.example.com"},
+}
+
+func TestLookupStaticHostAliases(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+ testHookHostsPath = "testdata/aliases"
+ for _, ent := range lookupStaticHostAliasesTest {
+ testLookupStaticHostAliases(t, ent.lookup, absDomainName(ent.res))
+ }
+}
+
+func testLookupStaticHostAliases(t *testing.T, lookup, lookupRes string) {
+ ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)}
+ for _, in := range ins {
+ _, res := lookupStaticHost(in)
+ if res != lookupRes {
+ t.Errorf("lookupStaticHost(%v): should be: '%v', but: '%v'", in, lookupRes, res)
+ }
+ }
+}
diff --git a/src/net/testdata/aliases b/src/net/testdata/aliases
new file mode 100644
index 0000000..e723523
--- /dev/null
+++ b/src/net/testdata/aliases
@@ -0,0 +1,8 @@
+127.0.0.1 test
+127.0.0.2 test2.example.com test2
+127.0.0.3 test3 test3.example.com
+127.0.0.4 example.com
+127.0.0.5 test4.example.com test4 test5 test5.example.com
+
+#must be a non resolvable domain on the internet
+127.0.1.1 8438random7333name2.example.test 8438random7333name2
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Congratulations on opening your first change. Thank you for your contribution!
Next steps:
A maintainer will review your change and provide feedback. See
https://golang.org/doc/contribute.html#review for more info and tips to get your
patch through code review.
Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.
During May-July and Nov-Jan the Go project is in a code freeze, during which
little code gets reviewed or merged. If a reviewer responds with a comment like
R=go1.11 or adds a tag like "wait-release", it means that this CL will be
reviewed as part of the next development cycle. See https://golang.org/s/release
for more details.
Attention is currently required from: Damien Neil, Ian Lance Taylor.
Gerrit Bot uploaded patch set #2 to this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes: #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: c9c2946104fce6b96f3aa59a2103712f53e68e94
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 170 insertions(+), 20 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
Patch set 2:Run-TryBot +1Code-Review +1Trust +1
2 comments:
Commit Message:
Patch Set #2, Line 12: Fixes: #44741
Please omit the colon here. See https://go.dev/wiki/CommitMessage for our preferred format. Thanks.
Patchset:
This has picked up a merge conflict. Any interest in fixing that? Thanks.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Damien Neil.
Gerrit Bot uploaded patch set #3 to this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: c9c2946104fce6b96f3aa59a2103712f53e68e94
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 170 insertions(+), 20 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Damien Neil.
Gerrit Bot uploaded patch set #4 to this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: ed5b64498c9050d314af96fa3f8c4d14e4fc58e1
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 171 insertions(+), 20 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Damien Neil.
Gerrit Bot uploaded patch set #5 to this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: 1c5b1a0382a6a78851891d7619690fd449e3e603
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 170 insertions(+), 20 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Damien Neil.
Patch set 5:Run-TryBot +1
Attention is currently required from: Damien Neil.
1 comment:
Patchset:
Done
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Damien Neil.
3 comments:
File src/net/dnsclient_unix.go:
Patch Set #5, Line 576: return
Let's explicitly write "return addrs, cname" here. It's very subtle that the cname declared with := above is the same cname as the result parameter.
File src/net/dnsclient_unix_test.go:
Patch Set #5, Line 2210: t.Errorf("goLookupIPCNAMEOrder(%v): should be: '%v', but: '%v'", in, lookupRes, res)
We usually say "got %v; want %v".
File src/net/hosts.go:
Patch Set #5, Line 102: hs[key] = byName{
This doesn't look right. The use of append in the original code is supporting the case where a host name appears multiple times in the file, mapping to multiple IP addresses. I don't know if that is supposed to work, but it seems that it did work. But if a host name appears multiple times, it is potentially associated with multiple canonical names. This code is going to associate it with a single canonical name, whichever one was seen last. This means that we can return an address along with a canonical name that is not associated with that address. I don't know what we should do here, but this doesn't seem like the right approach.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
1 comment:
File src/net/hosts.go:
Patch Set #5, Line 102: hs[key] = byName{
This doesn't look right. […]
This are the differences that i spotted: https://pastebin.com/XyqT9ZKr
adding something like this (just above the line you marked) fixes them:
+ if v,ok := hs[key]; ok {
+ hs[key] = byName{
+ addrs: append(v.addrs, addr),
+ canonicalName: v.canonicalName,
+ }
+ continue
+ }
"This means that we can return an address along with a canonical name that is not associated with that address"
Can you give me an example of /etc/hosts file that would cause that?
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Mateusz Poliwczak.
1 comment:
File src/net/hosts.go:
Patch Set #5, Line 102: hs[key] = byName{
This are the differences that i spotted: https://pastebin.com/XyqT9ZKr […]
127.0.0.1 myhost.example.com myhost
127.0.0.2 myhost2.example.com myhost
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
1 comment:
File src/net/hosts.go:
Patch Set #5, Line 102: hs[key] = byName{
127.0.0.1 myhost.example.com myhost […]
Now it should work the same way as glibc. The same output (go and cgo):
$ GODEBUG=netdns=go go run test.go myhost
myhost.example.com. [127.0.0.1 127.0.0.2]
$ GODEBUG=netdns=cgo go run test.go myhost
myhost.example.com. [127.0.0.1 127.0.0.2]
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
Gerrit Bot uploaded patch set #6 to this change.
The following approvals got outdated and were removed: Run-TryBot+1 by Ian Lance Taylor, TryBot-Result+1 by Gopher Robot
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: 370428ec00732fc1f237eca439fe0613b8a3e5d8
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 180 insertions(+), 21 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Mateusz Poliwczak.
5 comments:
File src/net/dnsclient_unix.go:
Patch Set #5, Line 576: return
Let's explicitly write "return addrs, cname" here. […]
Done
File src/net/dnsclient_unix_test.go:
Patch Set #5, Line 2210: t.Errorf("goLookupIPCNAMEOrder(%v): should be: '%v', but: '%v'", in, lookupRes, res)
We usually say "got %v; want %v".
Done
File src/net/hosts.go:
Patch Set #5, Line 102: hs[key] = byName{
Now it should work the same way as glibc. The same output (go and cgo): […]
Ack
File src/net/hosts.go:
Patch Set #6, Line 113: addrs: append(hs[key].addrs, addr),
I think that at this point in the code we know that there is no entry at hs[key], so I think the append call here is equivalent to []string{addr}.
File src/net/hosts_test.go:
Patch Set #6, Line 211: t.Errorf("lookupStaticHost(%v): should be: '%v', but: '%v'", in, lookupRes, res)
Use got %v want %v.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Mateusz Poliwczak.
3 comments:
File src/net/testdata/aliases:
Patch Set #6, Line 2: test2
According to [RFC6761](https://www.rfc-editor.org/rfc/rfc6761.html), only `test.` been reserved, maybe `2.test`?
Patch Set #6, Line 3: test3
Same as above and test4, test5
Patch Set #6, Line 8: 8438random7333name2
RFC6761 states that `invalid.` is "as opposed to names that may be invalid for other reasons"
127.0.1.1 invalid.test, invalid
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Zhuo Meng.
5 comments:
File src/net/hosts.go:
Patch Set #6, Line 113: addrs: append(hs[key].addrs, addr),
I think that at this point in the code we know that there is no entry at hs[key], so I think the app […]
Done
File src/net/hosts_test.go:
Patch Set #6, Line 211: t.Errorf("lookupStaticHost(%v): should be: '%v', but: '%v'", in, lookupRes, res)
Use got %v want %v.
Done
File src/net/testdata/aliases:
Patch Set #6, Line 2: test2
According to [RFC6761](https://www.rfc-editor.org/rfc/rfc6761.html), only `test. […]
Done
Patch Set #6, Line 3: test3
Same as above and test4, test5
Done
Patch Set #6, Line 8: 8438random7333name2
RFC6761 states that `invalid.` is "as opposed to names that may be invalid for other reasons" […]
Done
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Zhuo Meng.
Gerrit Bot uploaded patch set #7 to this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: 6cd89deaedc068b792fa78616cf8a84749daef32
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 180 insertions(+), 21 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Zhuo Meng.
Patch set 7:Run-TryBot +1
Attention is currently required from: Ian Lance Taylor, Meng Zhuo.
1 comment:
Commit Message:
Patch Set #2, Line 12: Fixes: #44741
Please omit the colon here. See https://go.dev/wiki/CommitMessage for our preferred format. […]
Done
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
File src/net/dnsclient_unix_test.go:
Patch Set #7, Line 2205: _, res, err := goResolver.goLookupIPCNAMEOrder(context.Background(), "ip", in, mode)
Should we use a fakeDNSServer here? Just in case the "invalid" from TestGoLookupIPCNAMEOrderHostsAliasesDNSFilesMode gets resolved by some weird dns resolver.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
File src/net/dnsclient_unix.go:
Patch Set #7, Line 602: entry
should i change error to errNoSuchHost?
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Mateusz Poliwczak, Meng Zhuo.
2 comments:
File src/net/dnsclient_unix.go:
Patch Set #7, Line 602: entry
should i change error to errNoSuchHost?
Yes, I think so.
File src/net/dnsclient_unix_test.go:
Patch Set #7, Line 2205: _, res, err := goResolver.goLookupIPCNAMEOrder(context.Background(), "ip", in, mode)
Should we use a fakeDNSServer here? Just in case the "invalid" from TestGoLookupIPCNAMEOrderHostsAli […]
Can we look up a name like "invalid.invalid" that DNS will always reject? (At least, that is what lookup_test.go says.)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Mateusz Poliwczak, Meng Zhuo.
Gerrit Bot uploaded patch set #8 to this change.
The following approvals got outdated and were removed: Run-TryBot+1 by Ian Lance Taylor, TryBot-Result+1 by Gopher Robot
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: ac2d24da7aff825248f4f18c4b49d3c65eafbbfa
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 181 insertions(+), 21 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Meng Zhuo.
2 comments:
File src/net/dnsclient_unix.go:
Patch Set #7, Line 602: entry
Yes, I think so.
Done
File src/net/dnsclient_unix_test.go:
Patch Set #7, Line 2205: _, res, err := goResolver.goLookupIPCNAMEOrder(context.Background(), "ip", in, mode)
Can we look up a name like "invalid. […]
Done
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Meng Zhuo.
1 comment:
Patchset:
Can you rebase this up to HEAD? I want to see if there are any side-effects now that CL 446179 has been submitted. Thanks.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Meng Zhuo.
Gerrit Bot uploaded patch set #9 to this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: 41614f16ed9fe8015ee8aa1c48a0ef2650d726eb
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 181 insertions(+), 21 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Meng Zhuo.
1 comment:
Patchset:
Can you rebase this up to HEAD? I want to see if there are any side-effects now that CL 446179 has […]
Done
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor.
Patch set 9:Run-TryBot +1
1 comment:
File src/net/dnsclient_unix.go:
Patch Set #9, Line 579: func goLookupIPFiles(name string) (addrs []IPAddr, cname string) {
The name "cname" is confusing me here, because this is definitely not a CNAME. Can we call is "canonical"? And do that consistently throughout this change? Thanks.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Meng Zhuo.
Gerrit Bot uploaded patch set #10 to this change.
The following approvals got outdated and were removed: Run-TryBot+1 by Meng Zhuo, TryBot-Result+1 by Gopher Robot
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: 3d47e44f11c350df906d0c986e41891dd6e8d929
GitHub-Pull-Request: golang/go#51004
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 181 insertions(+), 21 deletions(-)
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Meng Zhuo.
1 comment:
File src/net/dnsclient_unix.go:
Patch Set #9, Line 579: func goLookupIPFiles(name string) (addrs []IPAddr, cname string) {
The name "cname" is confusing me here, because this is definitely not a CNAME. […]
Done
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Meng Zhuo.
Patch set 10:Run-TryBot +1Auto-Submit +1Code-Review +2
1 comment:
Patchset:
Thanks.
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.
Gopher Robot submitted this change.
net: add support for /etc/hosts aliases using go resolver
It adds support for /etc/hosts aliases and fixes the difference between the glibc cgo and the go DNS resolver.
Examples: https://pastebin.com/Fv6UcAVr
Fixes #44741
Change-Id: I98c484fced900731fbad800278b296028a45f044
GitHub-Last-Rev: 3d47e44f11c350df906d0c986e41891dd6e8d929
GitHub-Pull-Request: golang/go#51004
Reviewed-on: https://go-review.googlesource.com/c/go/+/382996
Run-TryBot: Ian Lance Taylor <ia...@google.com>
Auto-Submit: Ian Lance Taylor <ia...@google.com>
Reviewed-by: Damien Neil <dn...@google.com>
TryBot-Result: Gopher Robot <go...@golang.org>
Reviewed-by: Ian Lance Taylor <ia...@google.com>
---
M src/net/dnsclient_unix.go
M src/net/dnsclient_unix_test.go
M src/net/hosts.go
M src/net/hosts_test.go
A src/net/testdata/aliases
5 files changed, 187 insertions(+), 21 deletions(-)
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index aed6a33..7cb30c0 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -559,7 +559,7 @@
func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder) (addrs []string, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
// Use entries from /etc/hosts if they match.
- addrs = lookupStaticHost(name)
+ addrs, _ = lookupStaticHost(name)
if len(addrs) > 0 || order == hostLookupFiles {
return
}
@@ -576,8 +576,9 @@
}
// lookup entries from /etc/hosts
-func goLookupIPFiles(name string) (addrs []IPAddr) {
- for _, haddr := range lookupStaticHost(name) {
+func goLookupIPFiles(name string) (addrs []IPAddr, canonical string) {
+ addr, canonical := lookupStaticHost(name)
+ for _, haddr := range addr {
haddr, zone := splitHostZone(haddr)
if ip := ParseIP(haddr); ip != nil {
addr := IPAddr{IP: ip, Zone: zone}
@@ -585,7 +586,7 @@
}
}
sortByRFC6724(addrs)
- return
+ return addrs, canonical
}
// goLookupIP is the native Go implementation of LookupIP.
@@ -598,11 +599,23 @@
func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder) (addrs []IPAddr, cname dnsmessage.Name, err error) {
if order == hostLookupFilesDNS || order == hostLookupFiles {
- addrs = goLookupIPFiles(name)
- if len(addrs) > 0 || order == hostLookupFiles {
- return addrs, dnsmessage.Name{}, nil
+ var canonical string
+ addrs, canonical = goLookupIPFiles(name)
+
+ if len(addrs) > 0 {
+ var err error
+ cname, err = dnsmessage.NewName(canonical)
+ if err != nil {
+ return nil, dnsmessage.Name{}, err
+ }
+ return addrs, cname, nil
+ }
+
+ if order == hostLookupFiles {
+ return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
}
}
+
if !isDomainName(name) {
// See comment in func lookup above about use of errNoSuchHost.
return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
@@ -776,9 +789,18 @@
sortByRFC6724(addrs)
if len(addrs) == 0 && !(network == "CNAME" && cname.Length > 0) {
if order == hostLookupDNSFiles {
- addrs = goLookupIPFiles(name)
+ var canonical string
+ addrs, canonical = goLookupIPFiles(name)
+ if len(addrs) > 0 {
+ var err error
+ cname, err = dnsmessage.NewName(canonical)
+ if err != nil {
+ return nil, dnsmessage.Name{}, err
+ }
+ return addrs, cname, nil
+ }
}
- if len(addrs) == 0 && lastErr != nil {
+ if lastErr != nil {
return nil, dnsmessage.Name{}, lastErr
}
}
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
index 63d3c51..a9a5567 100644
--- a/src/net/dnsclient_unix_test.go
+++ b/src/net/dnsclient_unix_test.go
@@ -2170,6 +2170,56 @@
}
}
+func TestGoLookupIPCNAMEOrderHostsAliasesFilesOnlyMode(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/aliases"
+ mode := hostLookupFiles
+
+ for _, v := range lookupStaticHostAliasesTest {
+ testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+ }
+}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesFilesDNSMode(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/aliases"
+ mode := hostLookupFilesDNS
+
+ for _, v := range lookupStaticHostAliasesTest {
+ testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+ }
+}
+
+var goLookupIPCNAMEOrderDNSFilesModeTests = []struct {
+ lookup, res string
+}{
+ // 127.0.1.1
+ {"invalid.invalid", "invalid.test"},
+}
+
+func TestGoLookupIPCNAMEOrderHostsAliasesDNSFilesMode(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+ testHookHostsPath = "testdata/aliases"
+ mode := hostLookupDNSFiles
+
+ for _, v := range goLookupIPCNAMEOrderDNSFilesModeTests {
+ testGoLookupIPCNAMEOrderHostsAliases(t, mode, v.lookup, absDomainName(v.res))
+ }
+}
+
+func testGoLookupIPCNAMEOrderHostsAliases(t *testing.T, mode hostLookupOrder, lookup, lookupRes string) {
+ ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)}
+ for _, in := range ins {
+ _, res, err := goResolver.goLookupIPCNAMEOrder(context.Background(), "ip", in, mode)
+ if err != nil {
+ t.Errorf("expected err == nil, but got error: %v", err)
+ }
+ if res.String() != lookupRes {
+ t.Errorf("goLookupIPCNAMEOrder(%v): got %v, want %v", in, res, lookupRes)
+ }
+ }
+}
+
// Test that we advertise support for a larger DNS packet size.
// This isn't a great test as it just tests the dnsmessage package
// against itself.
diff --git a/src/net/hosts.go b/src/net/hosts.go
index e604031..2ba8536 100644
--- a/src/net/hosts.go
+++ b/src/net/hosts.go
@@ -28,6 +28,11 @@
return ip.String() + "%" + zone
}
+type byName struct {
+ addrs []string
+ canonicalName string
+}
+
// hosts contains known host entries.
var hosts struct {
sync.Mutex
@@ -36,7 +41,7 @@
// name. It would be part of DNS labels, a FQDN or an absolute
// FQDN.
// For now the key is converted to lower case for convenience.
- byName map[string][]string
+ byName map[string]byName
// Key for the list of host names must be a literal IP address
// including IPv6 address with zone identifier.
@@ -62,8 +67,9 @@
return
}
- hs := make(map[string][]string)
+ hs := make(map[string]byName)
is := make(map[string][]string)
+
var file *file
if file, _ = open(hp); file == nil {
return
@@ -81,13 +87,32 @@
if addr == "" {
continue
}
+
+ var canonical string
for i := 1; i < len(f); i++ {
name := absDomainName(f[i])
h := []byte(f[i])
lowerASCIIBytes(h)
key := absDomainName(string(h))
- hs[key] = append(hs[key], addr)
+
+ if i == 1 {
+ canonical = key
+ }
+
is[addr] = append(is[addr], name)
+
+ if v,ok := hs[key]; ok {
+ hs[key] = byName{
+ addrs: append(v.addrs, addr),
+ canonicalName: v.canonicalName,
+ }
+ continue
+ }
+
+ hs[key] = byName{
+ addrs: []string{addr},
+ canonicalName: canonical,
+ }
}
}
// Update the data cache.
@@ -100,8 +125,8 @@
file.close()
}
-// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
-func lookupStaticHost(host string) []string {
+// lookupStaticHost looks up the addresses and the cannonical name for the given host from /etc/hosts.
+func lookupStaticHost(host string) ([]string, string) {
hosts.Lock()
defer hosts.Unlock()
readHosts()
@@ -111,13 +136,13 @@
lowerASCIIBytes(lowerHost)
host = string(lowerHost)
}
- if ips, ok := hosts.byName[absDomainName(host)]; ok {
- ipsCp := make([]string, len(ips))
- copy(ipsCp, ips)
- return ipsCp
+ if byName, ok := hosts.byName[absDomainName(host)]; ok {
+ ipsCp := make([]string, len(byName.addrs))
+ copy(ipsCp, byName.addrs)
+ return ipsCp, byName.canonicalName
}
}
- return nil
+ return nil, ""
}
// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
diff --git a/src/net/hosts_test.go b/src/net/hosts_test.go
index 7291914..b3f189e 100644
--- a/src/net/hosts_test.go
+++ b/src/net/hosts_test.go
@@ -72,7 +72,7 @@
func testStaticHost(t *testing.T, hostsPath string, ent staticHostEntry) {
ins := []string{ent.in, absDomainName(ent.in), strings.ToLower(ent.in), strings.ToUpper(ent.in)}
for _, in := range ins {
- addrs := lookupStaticHost(in)
+ addrs, _ := lookupStaticHost(in)
if !reflect.DeepEqual(addrs, ent.out) {
t.Errorf("%s, lookupStaticHost(%s) = %v; want %v", hostsPath, in, addrs, ent.out)
}
@@ -157,7 +157,7 @@
ent := staticHostEntry{"localhost", []string{"127.0.0.1", "127.0.0.2", "127.0.0.3"}}
testStaticHost(t, testHookHostsPath, ent)
// Modify the addresses return by lookupStaticHost.
- addrs := lookupStaticHost(ent.in)
+ addrs, _ := lookupStaticHost(ent.in)
for i := range addrs {
addrs[i] += "junk"
}
@@ -173,3 +173,42 @@
}
testStaticAddr(t, testHookHostsPath, ent)
}
+
+var lookupStaticHostAliasesTest = []struct {
+ lookup, res string
+}{
+ // 127.0.0.1
+ {"test", "test"},
+ // 127.0.0.2
+ {"test2.example.com", "test2.example.com"},
+ {"2.test", "test2.example.com"},
+ // 127.0.0.3
+ {"test3.example.com", "3.test"},
+ {"3.test", "3.test"},
+ // 127.0.0.4
+ {"example.com", "example.com"},
+ // 127.0.0.5
+ {"test5.example.com", "test4.example.com"},
+ {"5.test", "test4.example.com"},
+ {"4.test", "test4.example.com"},
+ {"test4.example.com", "test4.example.com"},
+}
+
+func TestLookupStaticHostAliases(t *testing.T) {
+ defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath)
+
+ testHookHostsPath = "testdata/aliases"
+ for _, ent := range lookupStaticHostAliasesTest {
+ testLookupStaticHostAliases(t, ent.lookup, absDomainName(ent.res))
+ }
+}
+
+func testLookupStaticHostAliases(t *testing.T, lookup, lookupRes string) {
+ ins := []string{lookup, absDomainName(lookup), strings.ToLower(lookup), strings.ToUpper(lookup)}
+ for _, in := range ins {
+ _, res := lookupStaticHost(in)
+ if res != lookupRes {
+ t.Errorf("lookupStaticHost(%v): got %v, want %v", in, res, lookupRes)
+ }
+ }
+}
diff --git a/src/net/testdata/aliases b/src/net/testdata/aliases
new file mode 100644
index 0000000..9330ba0
--- /dev/null
+++ b/src/net/testdata/aliases
@@ -0,0 +1,8 @@
+127.0.0.1 test
+127.0.0.2 test2.example.com 2.test
+127.0.0.3 3.test test3.example.com
+127.0.0.4 example.com
+127.0.0.5 test4.example.com 4.test 5.test test5.example.com
+
+# must be a non resolvable domain on the internet
+127.0.1.1 invalid.test invalid.invalid
To view, visit change 382996. To unsubscribe, or for help writing mail filters, visit settings.