-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathresolver.go
More file actions
87 lines (70 loc) · 1.77 KB
/
Copy pathresolver.go
File metadata and controls
87 lines (70 loc) · 1.77 KB
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
78
79
80
81
82
83
84
85
86
87
package main
import (
"bufio"
"errors"
"github.com/miekg/dns"
"math/rand"
"net"
"os"
"time"
)
var errEmptyResults = errors.New("empty results returned from domain lookup")
// DNSResolver defines interface to able to use
// different DNS resolver implementations
type DNSResolver interface {
Resolve(host string) ([]net.IP, error)
}
// NewDNSResolver returns MyDNSResolver instance
func NewDNSResolver() *MyDNSResolver {
return &MyDNSResolver{
random: rand.New(rand.NewSource(time.Now().UnixNano())),
ips: make([]string, 0),
dnsClient: &dns.Client{},
}
}
// MyDNSResolver loads DNS servers from the file
// and return resolved IP by randomly selecting DNS server from the list
type MyDNSResolver struct {
ips []string
random *rand.Rand
dnsClient *dns.Client
}
// Load loads ips from the file
func (r *MyDNSResolver) Load(file string) error {
f, err := os.Open(file)
if err != nil {
return err
}
defer f.Close()
sc := bufio.NewScanner(f)
for sc.Scan() {
r.ips = append(r.ips, net.JoinHostPort(sc.Text(), "53"))
}
return sc.Err()
}
// Resolve returns resolved IP for specific host
func (r *MyDNSResolver) Resolve(host string) ([]net.IP, error) {
var result []net.IP
m1 := &dns.Msg{}
m1.SetQuestion(dns.Fqdn(host), dns.TypeA)
msg, _, err := r.dnsClient.Exchange(m1, r.getServer())
if err != nil {
return result, err
}
if msg != nil && msg.Rcode != dns.RcodeSuccess {
return result, errors.New(dns.RcodeToString[msg.Rcode])
}
for _, record := range msg.Answer {
if t, ok := record.(*dns.A); ok {
result = append(result, t.A)
}
}
if len(result) == 0 {
return result, errEmptyResults
}
return result, nil
}
// return random DNS server
func (r *MyDNSResolver) getServer() string {
return r.ips[r.random.Intn(len(r.ips))]
}