package net
import (
"internal/bytealg"
"sync"
"time"
)
const cacheMaxAge = 5 * time .Second
func parseLiteralIP (addr string ) string {
var ip IP
var zone string
ip = parseIPv4 (addr )
if ip == nil {
ip , zone = parseIPv6Zone (addr )
}
if ip == nil {
return ""
}
if zone == "" {
return ip .String ()
}
return ip .String () + "%" + zone
}
var hosts struct {
sync .Mutex
byName map [string ][]string
byAddr map [string ][]string
expire time .Time
path string
mtime time .Time
size int64
}
func readHosts () {
now := time .Now ()
hp := testHookHostsPath
if now .Before (hosts .expire ) && hosts .path == hp && len (hosts .byName ) > 0 {
return
}
mtime , size , err := stat (hp )
if err == nil && hosts .path == hp && hosts .mtime .Equal (mtime ) && hosts .size == size {
hosts .expire = now .Add (cacheMaxAge )
return
}
hs := make (map [string ][]string )
is := make (map [string ][]string )
var file *file
if file , _ = open (hp ); file == nil {
return
}
for line , ok := file .readLine (); ok ; line , ok = file .readLine () {
if i := bytealg .IndexByteString (line , '#' ); i >= 0 {
line = line [0 :i ]
}
f := getFields (line )
if len (f ) < 2 {
continue
}
addr := parseLiteralIP (f [0 ])
if addr == "" {
continue
}
for i := 1 ; i < len (f ); i ++ {
name := absDomainName ([]byte (f [i ]))
h := []byte (f [i ])
lowerASCIIBytes (h )
key := absDomainName (h )
hs [key ] = append (hs [key ], addr )
is [addr ] = append (is [addr ], name )
}
}
hosts .expire = now .Add (cacheMaxAge )
hosts .path = hp
hosts .byName = hs
hosts .byAddr = is
hosts .mtime = mtime
hosts .size = size
file .close ()
}
func lookupStaticHost (host string ) []string {
hosts .Lock ()
defer hosts .Unlock ()
readHosts ()
if len (hosts .byName ) != 0 {
lowerHost := []byte (host )
lowerASCIIBytes (lowerHost )
if ips , ok := hosts .byName [absDomainName (lowerHost )]; ok {
ipsCp := make ([]string , len (ips ))
copy (ipsCp , ips )
return ipsCp
}
}
return nil
}
func lookupStaticAddr (addr string ) []string {
hosts .Lock ()
defer hosts .Unlock ()
readHosts ()
addr = parseLiteralIP (addr )
if addr == "" {
return nil
}
if len (hosts .byAddr ) != 0 {
if hosts , ok := hosts .byAddr [addr ]; ok {
hostsCp := make ([]string , len (hosts ))
copy (hostsCp , hosts )
return hostsCp
}
}
return nil
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .