File: dnscache.go

package info (click to toggle)
golang-github-viki-org-dnscache 0.0~git20130720.0.c70c1f2-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 60 kB
  • ctags: 19
  • sloc: makefile: 3
file content (77 lines) | stat: -rw-r--r-- 1,525 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package dnscache
// Package dnscache caches DNS lookups

import (
  "net"
  "sync"
  "time"
)

type Resolver struct {
  lock sync.RWMutex
  cache map[string][]net.IP
}

func New(refreshRate time.Duration) *Resolver {
  resolver := &Resolver {
    cache: make(map[string][]net.IP, 64),
  }
  if refreshRate > 0 {
    go resolver.autoRefresh(refreshRate)
  }
  return resolver
}

func (r *Resolver) Fetch(address string) ([]net.IP, error) {
  r.lock.RLock()
  ips, exists := r.cache[address]
  r.lock.RUnlock()
  if exists { return ips, nil }

  return r.Lookup(address)
}

func (r *Resolver) FetchOne(address string) (net.IP, error) {
  ips, err := r.Fetch(address)
  if err != nil || len(ips) == 0 { return nil, err}
  return ips[0], nil
}

func (r *Resolver) FetchOneString(address string) (string, error) {
  ip, err := r.FetchOne(address)
  if err != nil || ip == nil { return "", err }
  return ip.String(), nil
}

func (r *Resolver) Refresh() {
  i := 0
  r.lock.RLock()
  addresses := make([]string, len(r.cache))
  for key, _ := range r.cache {
    addresses[i] = key
    i++
  }
  r.lock.RUnlock()

  for _, address := range addresses {
    r.Lookup(address)
    time.Sleep(time.Second * 2)
  }
}

func (r *Resolver) Lookup(address string) ([]net.IP, error) {
  ips, err := net.LookupIP(address)
  if err != nil { return nil, err }

  r.lock.Lock()
  r.cache[address] = ips
  r.lock.Unlock()
  return ips, nil
}

func (r *Resolver) autoRefresh(rate time.Duration) {
  for {
    time.Sleep(rate)
    r.Refresh()
  }
}