mirror of
https://github.com/golang/go
synced 2024-11-22 06:14:39 -07:00
Use /etc/hosts when resolving names.
http://code.google.com/p/go/issues/detail?id=313 This conflics with Chris' patch at: https://golang.org/cl/181063 But I believe this is more complete since it has a simple caching and proper tests. R=cw, rsc CC=golang-dev https://golang.org/cl/183066
This commit is contained in:
parent
01b4f2dd23
commit
d6054fcd88
@ -11,6 +11,7 @@ GOFILES=\
|
|||||||
dnsmsg.go\
|
dnsmsg.go\
|
||||||
fd.go\
|
fd.go\
|
||||||
fd_$(GOOS).go\
|
fd_$(GOOS).go\
|
||||||
|
hosts.go\
|
||||||
ip.go\
|
ip.go\
|
||||||
ipsock.go\
|
ipsock.go\
|
||||||
net.go\
|
net.go\
|
||||||
|
@ -224,7 +224,7 @@ func isDomainName(s string) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupHost looks up the host name using the local DNS resolver.
|
// LookupHost looks for name using the local hosts file and DNS resolver.
|
||||||
// It returns the canonical name for the host and an array of that
|
// It returns the canonical name for the host and an array of that
|
||||||
// host's addresses.
|
// host's addresses.
|
||||||
func LookupHost(name string) (cname string, addrs []string, err os.Error) {
|
func LookupHost(name string) (cname string, addrs []string, err os.Error) {
|
||||||
@ -236,7 +236,12 @@ func LookupHost(name string) (cname string, addrs []string, err os.Error) {
|
|||||||
err = dnserr
|
err = dnserr
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Use entries from /etc/hosts if they match.
|
||||||
|
addrs = lookupStaticHost(name)
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
cname = name
|
||||||
|
return
|
||||||
|
}
|
||||||
// If name is rooted (trailing dot) or has enough dots,
|
// If name is rooted (trailing dot) or has enough dots,
|
||||||
// try it by itself first.
|
// try it by itself first.
|
||||||
rooted := len(name) > 0 && name[len(name)-1] == '.'
|
rooted := len(name) > 0 && name[len(name)-1] == '.'
|
||||||
|
78
src/pkg/net/hosts.go
Normal file
78
src/pkg/net/hosts.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Read static host/IP entries from /etc/hosts.
|
||||||
|
|
||||||
|
package net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const cacheMaxAge = int64(300) // 5 minutes.
|
||||||
|
|
||||||
|
// hostsPath points to the file with static IP/address entries.
|
||||||
|
var hostsPath = "/etc/hosts"
|
||||||
|
|
||||||
|
// Simple cache.
|
||||||
|
var hosts struct {
|
||||||
|
sync.Mutex
|
||||||
|
data map[string][]string
|
||||||
|
time int64
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func readHosts() {
|
||||||
|
now, _, _ := os.Time()
|
||||||
|
hp := hostsPath
|
||||||
|
if len(hosts.data) == 0 || hosts.time+cacheMaxAge <= now || hosts.path != hp {
|
||||||
|
hs := make(map[string][]string)
|
||||||
|
var file *file
|
||||||
|
file, _ = open(hp)
|
||||||
|
for line, ok := file.readLine(); ok; line, ok = file.readLine() {
|
||||||
|
if i := byteIndex(line, '#'); i >= 0 {
|
||||||
|
// Discard comments.
|
||||||
|
line = line[0:i]
|
||||||
|
}
|
||||||
|
f := getFields(line)
|
||||||
|
if len(f) < 2 || ParseIP(f[0]) == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
h := f[1]
|
||||||
|
old, _ := hs[h]
|
||||||
|
hs[h] = appendHost(old, f[0])
|
||||||
|
}
|
||||||
|
// Update the data cache.
|
||||||
|
hosts.time, _, _ = os.Time()
|
||||||
|
hosts.path = hp
|
||||||
|
hosts.data = hs
|
||||||
|
file.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendHost(hosts []string, address string) []string {
|
||||||
|
n := len(hosts)
|
||||||
|
if n+1 > cap(hosts) { // reallocate
|
||||||
|
a := make([]string, n, 2*n+1)
|
||||||
|
copy(a, hosts)
|
||||||
|
hosts = a
|
||||||
|
}
|
||||||
|
hosts = hosts[0 : n+1]
|
||||||
|
hosts[n] = address
|
||||||
|
return hosts
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookupStaticHosts looks up the addresses for the given host from /etc/hosts.
|
||||||
|
func lookupStaticHost(host string) []string {
|
||||||
|
hosts.Lock()
|
||||||
|
defer hosts.Unlock()
|
||||||
|
readHosts()
|
||||||
|
if len(hosts.data) != 0 {
|
||||||
|
if ips, ok := hosts.data[host]; ok {
|
||||||
|
return ips
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
48
src/pkg/net/hosts_test.go
Normal file
48
src/pkg/net/hosts_test.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package net
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type hostTest struct {
|
||||||
|
host string
|
||||||
|
ips []IP
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var hosttests = []hostTest{
|
||||||
|
hostTest{"odin", []IP{
|
||||||
|
IPv4(127, 0, 0, 2),
|
||||||
|
IPv4(127, 0, 0, 3),
|
||||||
|
ParseIP("::2"),
|
||||||
|
}},
|
||||||
|
hostTest{"thor", []IP{
|
||||||
|
IPv4(127, 1, 1, 1),
|
||||||
|
}},
|
||||||
|
hostTest{"loki", []IP{}},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLookupStaticHost(t *testing.T) {
|
||||||
|
p := hostsPath
|
||||||
|
hostsPath = "hosts_testdata"
|
||||||
|
for i := 0; i < len(hosttests); i++ {
|
||||||
|
tt := hosttests[i]
|
||||||
|
ips := lookupStaticHost(tt.host)
|
||||||
|
if len(ips) != len(tt.ips) {
|
||||||
|
t.Errorf("# of hosts = %v; want %v",
|
||||||
|
len(ips), len(tt.ips))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for k, v := range ips {
|
||||||
|
if tt.ips[k].String() != v {
|
||||||
|
t.Errorf("lookupStaticHost(%q) = %v; want %v",
|
||||||
|
tt.host, v, tt.ips[k])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hostsPath = p
|
||||||
|
}
|
10
src/pkg/net/hosts_testdata
Normal file
10
src/pkg/net/hosts_testdata
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
255.255.255.255 broadcasthost
|
||||||
|
127.0.0.2 odin
|
||||||
|
127.0.0.3 odin # inline comment
|
||||||
|
::2 odin
|
||||||
|
127.1.1.1 thor
|
||||||
|
# Bogus entries that must be ignored.
|
||||||
|
123.123.123 loki
|
||||||
|
321.321.321.321
|
||||||
|
# TODO(yvesj): Should we be able to parse this? From a Darwin system.
|
||||||
|
fe80::1%lo0 localhost
|
@ -278,6 +278,10 @@ func parseIPv4(s string) IP {
|
|||||||
var p [IPv4len]byte
|
var p [IPv4len]byte
|
||||||
i := 0
|
i := 0
|
||||||
for j := 0; j < IPv4len; j++ {
|
for j := 0; j < IPv4len; j++ {
|
||||||
|
if i >= len(s) {
|
||||||
|
// Missing octets.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if j > 0 {
|
if j > 0 {
|
||||||
if s[i] != '.' {
|
if s[i] != '.' {
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user