-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresolver.go
96 lines (79 loc) · 2.63 KB
/
resolver.go
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
88
89
90
91
92
93
94
95
96
package resolver
import (
"context"
"github.com/miekg/dns"
"strings"
)
type Resolver struct {
zones zoneStore
funcs resolverFunctions
}
// The core, top level, resolving functions. They're defined as variables to aid overriding them for testing.
type resolverFunctions struct {
resolveLabel func(ctx context.Context, d *domain, z zone, qmsg *dns.Msg, auth *authenticator) (zone, *Response)
checkForMissingZones func(ctx context.Context, d *domain, z zone, rmsg *dns.Msg, auth *authenticator) zone
createZone func(ctx context.Context, name, parent string, nameservers []*dns.NS, extra []dns.RR, exchanger exchanger) (zone, error)
finaliseResponse func(ctx context.Context, auth *authenticator, qmsg *dns.Msg, response *Response) *Response
processDelegation func(ctx context.Context, z zone, rmsg *dns.Msg) (zone, *Response)
cname func(ctx context.Context, qmsg *dns.Msg, r *Response, exchanger exchanger) error
getExchanger func() exchanger
}
func NewResolver() *Resolver {
pool, err := buildRootServerPool()
if err != nil {
// Everything is technically static at this point.
panic(err)
}
z := new(zones)
z.add(&zoneImpl{
zoneName: ".",
pool: pool,
})
resolver := &Resolver{
zones: z,
}
// When not testing, we point to the concrete instances of the functions.
resolver.funcs = resolverFunctions{
resolveLabel: resolver.resolveLabel,
checkForMissingZones: resolver.checkForMissingZones,
createZone: createZone,
finaliseResponse: resolver.finaliseResponse,
processDelegation: resolver.processDelegation,
cname: cname,
getExchanger: resolver.getExchanger,
}
return resolver
}
func (resolver *Resolver) getExchanger() exchanger {
return resolver
}
// CountZones metrics gathering.
func (resolver *Resolver) CountZones() int {
return resolver.zones.count()
}
//-----------------------------------------------------------------------------
func buildRootServerPool() (*nameserverPool, error) {
zp := dns.NewZoneParser(strings.NewReader(rootZone), ".", "local")
pool := &nameserverPool{hostsWithoutAddresses: make([]string, 0)}
for rr, ok := zp.Next(); ok; rr, ok = zp.Next() {
switch rr := rr.(type) {
case *dns.A:
pool.ipv4 = append(pool.ipv4, &nameserver{
hostname: canonicalName(rr.Header().Name),
addr: rr.A.String(),
})
case *dns.AAAA:
pool.ipv6 = append(pool.ipv6, &nameserver{
hostname: canonicalName(rr.Header().Name),
addr: rr.AAAA.String(),
})
default:
// Continue
}
}
if err := zp.Err(); err != nil {
return nil, err
}
pool.updateIPCount()
return pool, nil
}