hosts.go 1.8 KB

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