...

Source file src/net/hosts.go

Documentation: net

		 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.
		 4  
		 5  package net
		 6  
		 7  import (
		 8  	"internal/bytealg"
		 9  	"sync"
		10  	"time"
		11  )
		12  
		13  const cacheMaxAge = 5 * time.Second
		14  
		15  func parseLiteralIP(addr string) string {
		16  	var ip IP
		17  	var zone string
		18  	ip = parseIPv4(addr)
		19  	if ip == nil {
		20  		ip, zone = parseIPv6Zone(addr)
		21  	}
		22  	if ip == nil {
		23  		return ""
		24  	}
		25  	if zone == "" {
		26  		return ip.String()
		27  	}
		28  	return ip.String() + "%" + zone
		29  }
		30  
		31  // hosts contains known host entries.
		32  var hosts struct {
		33  	sync.Mutex
		34  
		35  	// Key for the list of literal IP addresses must be a host
		36  	// name. It would be part of DNS labels, a FQDN or an absolute
		37  	// FQDN.
		38  	// For now the key is converted to lower case for convenience.
		39  	byName map[string][]string
		40  
		41  	// Key for the list of host names must be a literal IP address
		42  	// including IPv6 address with zone identifier.
		43  	// We don't support old-classful IP address notation.
		44  	byAddr map[string][]string
		45  
		46  	expire time.Time
		47  	path	 string
		48  	mtime	time.Time
		49  	size	 int64
		50  }
		51  
		52  func readHosts() {
		53  	now := time.Now()
		54  	hp := testHookHostsPath
		55  
		56  	if now.Before(hosts.expire) && hosts.path == hp && len(hosts.byName) > 0 {
		57  		return
		58  	}
		59  	mtime, size, err := stat(hp)
		60  	if err == nil && hosts.path == hp && hosts.mtime.Equal(mtime) && hosts.size == size {
		61  		hosts.expire = now.Add(cacheMaxAge)
		62  		return
		63  	}
		64  
		65  	hs := make(map[string][]string)
		66  	is := make(map[string][]string)
		67  	var file *file
		68  	if file, _ = open(hp); file == nil {
		69  		return
		70  	}
		71  	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
		72  		if i := bytealg.IndexByteString(line, '#'); i >= 0 {
		73  			// Discard comments.
		74  			line = line[0:i]
		75  		}
		76  		f := getFields(line)
		77  		if len(f) < 2 {
		78  			continue
		79  		}
		80  		addr := parseLiteralIP(f[0])
		81  		if addr == "" {
		82  			continue
		83  		}
		84  		for i := 1; i < len(f); i++ {
		85  			name := absDomainName([]byte(f[i]))
		86  			h := []byte(f[i])
		87  			lowerASCIIBytes(h)
		88  			key := absDomainName(h)
		89  			hs[key] = append(hs[key], addr)
		90  			is[addr] = append(is[addr], name)
		91  		}
		92  	}
		93  	// Update the data cache.
		94  	hosts.expire = now.Add(cacheMaxAge)
		95  	hosts.path = hp
		96  	hosts.byName = hs
		97  	hosts.byAddr = is
		98  	hosts.mtime = mtime
		99  	hosts.size = size
	 100  	file.close()
	 101  }
	 102  
	 103  // lookupStaticHost looks up the addresses for the given host from /etc/hosts.
	 104  func lookupStaticHost(host string) []string {
	 105  	hosts.Lock()
	 106  	defer hosts.Unlock()
	 107  	readHosts()
	 108  	if len(hosts.byName) != 0 {
	 109  		// TODO(jbd,bradfitz): avoid this alloc if host is already all lowercase?
	 110  		// or linear scan the byName map if it's small enough?
	 111  		lowerHost := []byte(host)
	 112  		lowerASCIIBytes(lowerHost)
	 113  		if ips, ok := hosts.byName[absDomainName(lowerHost)]; ok {
	 114  			ipsCp := make([]string, len(ips))
	 115  			copy(ipsCp, ips)
	 116  			return ipsCp
	 117  		}
	 118  	}
	 119  	return nil
	 120  }
	 121  
	 122  // lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
	 123  func lookupStaticAddr(addr string) []string {
	 124  	hosts.Lock()
	 125  	defer hosts.Unlock()
	 126  	readHosts()
	 127  	addr = parseLiteralIP(addr)
	 128  	if addr == "" {
	 129  		return nil
	 130  	}
	 131  	if len(hosts.byAddr) != 0 {
	 132  		if hosts, ok := hosts.byAddr[addr]; ok {
	 133  			hostsCp := make([]string, len(hosts))
	 134  			copy(hostsCp, hosts)
	 135  			return hostsCp
	 136  		}
	 137  	}
	 138  	return nil
	 139  }
	 140  

View as plain text