1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 const cacheMaxAge
= 5 * time
.Second
14 func parseLiteralIP(addr
string) string {
19 ip
, zone
= parseIPv6Zone(addr
)
27 return ip
.String() + "%" + zone
30 // hosts contains known host entries.
34 // Key for the list of literal IP addresses must be a host
35 // name. It would be part of DNS labels, a FQDN or an absolute
37 // For now the key is converted to lower case for convenience.
38 byName
map[string][]string
40 // Key for the list of host names must be a literal IP address
41 // including IPv6 address with zone identifier.
42 // We don't support old-classful IP address notation.
43 byAddr
map[string][]string
53 hp
:= testHookHostsPath
55 if now
.Before(hosts
.expire
) && hosts
.path
== hp
&& len(hosts
.byName
) > 0 {
58 mtime
, size
, err
:= stat(hp
)
59 if err
== nil && hosts
.path
== hp
&& hosts
.mtime
.Equal(mtime
) && hosts
.size
== size
{
60 hosts
.expire
= now
.Add(cacheMaxAge
)
64 hs
:= make(map[string][]string)
65 is
:= make(map[string][]string)
67 if file
, _
= open(hp
); file
== nil {
70 for line
, ok
:= file
.readLine(); ok
; line
, ok
= file
.readLine() {
71 if i
:= byteIndex(line
, '#'); i
>= 0 {
79 addr
:= parseLiteralIP(f
[0])
83 for i
:= 1; i
< len(f
); i
++ {
84 name
:= absDomainName([]byte(f
[i
]))
87 key
:= absDomainName(h
)
88 hs
[key
] = append(hs
[key
], addr
)
89 is
[addr
] = append(is
[addr
], name
)
92 // Update the data cache.
93 hosts
.expire
= now
.Add(cacheMaxAge
)
102 // lookupStaticHost looks up the addresses for the given host from /etc/hosts.
103 func lookupStaticHost(host
string) []string {
107 if len(hosts
.byName
) != 0 {
108 // TODO(jbd,bradfitz): avoid this alloc if host is already all lowercase?
109 // or linear scan the byName map if it's small enough?
110 lowerHost
:= []byte(host
)
111 lowerASCIIBytes(lowerHost
)
112 if ips
, ok
:= hosts
.byName
[absDomainName(lowerHost
)]; ok
{
113 ipsCp
:= make([]string, len(ips
))
121 // lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
122 func lookupStaticAddr(addr
string) []string {
126 addr
= parseLiteralIP(addr
)
130 if len(hosts
.byAddr
) != 0 {
131 if hosts
, ok
:= hosts
.byAddr
[addr
]; ok
{
132 hostsCp
:= make([]string, len(hosts
))