-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpool_exchange.go
65 lines (54 loc) · 1.61 KB
/
pool_exchange.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
package resolver
import (
"context"
"fmt"
"github.com/miekg/dns"
)
func (pool *nameserverPool) exchange(ctx context.Context, m *dns.Msg) *Response {
hasIPv4 := pool.hasIPv4()
hasIPv6 := pool.hasIPv6()
if !hasIPv4 && !hasIPv6 {
if z, ok := ctx.Value(ctxZoneName).(string); ok {
return ResponseError(fmt.Errorf("%w [%s]", ErrNoPoolConfiguredForZone, z))
}
return ResponseError(ErrNoPoolConfiguredForZone)
}
//---
var response *Response
if hasIPv6 && IPv6Available() {
if server := pool.getIPv6(); server != nil {
response = server.exchange(ctx, m)
}
} else {
if server := pool.getIPv4(); server != nil {
response = server.exchange(ctx, m)
}
}
if response.IsEmpty() || response.HasError() || response.truncated() {
// If there was an issue, we give it one more try.
// If we have more than one nameserver, this will try a different one.
if hasIPv4 {
if server := pool.getIPv4(); server != nil {
response = server.exchange(ctx, m)
}
} else {
if server := pool.getIPv6(); server != nil {
response = server.exchange(ctx, m)
}
}
}
if response.IsEmpty() || response.HasError() {
errMsg := fmt.Sprintf("all nameservers tried returned an unsucessful response for qname [%s]", m.Question[0].Name)
if z, ok := ctx.Value(ctxZoneName).(string); ok {
errMsg = errMsg + fmt.Sprintf(" in zone [%s]", z)
}
err := fmt.Errorf("%w: %s", ErrUnableToResolveAnswer, errMsg)
if response.HasError() {
// If we already had an error, we'll wrap it with this one.
response.Err = fmt.Errorf("%w: %w", response.Err, err)
} else {
response.Err = err
}
}
return response
}