github.com/zxy12/golang151_with_comment@v0.0.0-20190507085033-721809559d3c/net/hosts.go (about)

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