src/pkg/net/hosts.go - The Go Programming Language

Golang

Source file src/pkg/net/hosts.go

     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	// Read static host/IP entries from /etc/hosts.
     6	
     7	package net
     8	
     9	import (
    10		"sync"
    11		"time"
    12	)
    13	
    14	const cacheMaxAge = 5 * time.Minute
    15	
    16	// hostsPath points to the file with static IP/address entries.
    17	var hostsPath = "/etc/hosts"
    18	
    19	// Simple cache.
    20	var hosts struct {
    21		sync.Mutex
    22		byName map[string][]string
    23		byAddr map[string][]string
    24		expire time.Time
    25		path   string
    26	}
    27	
    28	func readHosts() {
    29		now := time.Now()
    30		hp := hostsPath
    31		if len(hosts.byName) == 0 || now.After(hosts.expire) || hosts.path != hp {
    32			hs := make(map[string][]string)
    33			is := make(map[string][]string)
    34			var file *file
    35			if file, _ = open(hp); file == nil {
    36				return
    37			}
    38			for line, ok := file.readLine(); ok; line, ok = file.readLine() {
    39				if i := byteIndex(line, '#'); i >= 0 {
    40					// Discard comments.
    41					line = line[0:i]
    42				}
    43				f := getFields(line)
    44				if len(f) < 2 || ParseIP(f[0]) == nil {
    45					continue
    46				}
    47				for i := 1; i < len(f); i++ {
    48					h := f[i]
    49					hs[h] = append(hs[h], f[0])
    50					is[f[0]] = append(is[f[0]], h)
    51				}
    52			}
    53			// Update the data cache.
    54			hosts.expire = time.Now().Add(cacheMaxAge)
    55			hosts.path = hp
    56			hosts.byName = hs
    57			hosts.byAddr = is
    58			file.close()
    59		}
    60	}
    61	
    62	// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
    63	func lookupStaticHost(host string) []string {
    64		hosts.Lock()
    65		defer hosts.Unlock()
    66		readHosts()
    67		if len(hosts.byName) != 0 {
    68			if ips, ok := hosts.byName[host]; ok {
    69				return ips
    70			}
    71		}
    72		return nil
    73	}
    74	
    75	// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
    76	func lookupStaticAddr(addr string) []string {
    77		hosts.Lock()
    78		defer hosts.Unlock()
    79		readHosts()
    80		if len(hosts.byAddr) != 0 {
    81			if hosts, ok := hosts.byAddr[addr]; ok {
    82				return hosts
    83			}
    84		}
    85		return nil
    86	}