1 package bdns
2
3 import (
4 "context"
5 "errors"
6 "fmt"
7 "net"
8 "os"
9
10 "github.com/miekg/dns"
11
12 blog "github.com/letsencrypt/boulder/log"
13 )
14
15
16 type MockClient struct {
17 Log blog.Logger
18 }
19
20
21 func (mock *MockClient) LookupTXT(_ context.Context, hostname string) ([]string, error) {
22 if hostname == "_acme-challenge.servfail.com" {
23 return nil, fmt.Errorf("SERVFAIL")
24 }
25 if hostname == "_acme-challenge.good-dns01.com" {
26
27
28
29 return []string{"LPsIwTo7o8BoG0-vjCyGQGBWSVIPxI-i_X336eUOQZo"}, nil
30 }
31 if hostname == "_acme-challenge.wrong-dns01.com" {
32 return []string{"a"}, nil
33 }
34 if hostname == "_acme-challenge.wrong-many-dns01.com" {
35 return []string{"a", "b", "c", "d", "e"}, nil
36 }
37 if hostname == "_acme-challenge.long-dns01.com" {
38 return []string{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, nil
39 }
40 if hostname == "_acme-challenge.no-authority-dns01.com" {
41
42
43
44 return []string{"LPsIwTo7o8BoG0-vjCyGQGBWSVIPxI-i_X336eUOQZo"}, nil
45 }
46
47 if hostname == "_acme-challenge.empty-txts.com" {
48 return []string{}, nil
49 }
50 return []string{"hostname"}, nil
51 }
52
53
54 func makeTimeoutError() *net.OpError {
55 return &net.OpError{
56 Err: os.NewSyscallError("ugh timeout", timeoutError{}),
57 }
58 }
59
60 type timeoutError struct{}
61
62 func (t timeoutError) Error() string {
63 return "so sloooow"
64 }
65 func (t timeoutError) Timeout() bool {
66 return true
67 }
68
69
70 func (mock *MockClient) LookupHost(_ context.Context, hostname string) ([]net.IP, error) {
71 if hostname == "always.invalid" ||
72 hostname == "invalid.invalid" {
73 return []net.IP{}, nil
74 }
75 if hostname == "always.timeout" {
76 return []net.IP{}, &Error{dns.TypeA, "always.timeout", makeTimeoutError(), -1, nil}
77 }
78 if hostname == "always.error" {
79 err := &net.OpError{
80 Op: "read",
81 Net: "udp",
82 Err: errors.New("some net error"),
83 }
84 m := new(dns.Msg)
85 m.SetQuestion(dns.Fqdn(hostname), dns.TypeA)
86 m.AuthenticatedData = true
87 m.SetEdns0(4096, false)
88 logDNSError(mock.Log, "mock.server", hostname, m, nil, err)
89 return []net.IP{}, &Error{dns.TypeA, hostname, err, -1, nil}
90 }
91 if hostname == "id.mismatch" {
92 err := dns.ErrId
93 m := new(dns.Msg)
94 m.SetQuestion(dns.Fqdn(hostname), dns.TypeA)
95 m.AuthenticatedData = true
96 m.SetEdns0(4096, false)
97 r := new(dns.Msg)
98 record := new(dns.A)
99 record.Hdr = dns.RR_Header{Name: dns.Fqdn(hostname), Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
100 record.A = net.ParseIP("127.0.0.1")
101 r.Answer = append(r.Answer, record)
102 logDNSError(mock.Log, "mock.server", hostname, m, r, err)
103 return []net.IP{}, &Error{dns.TypeA, hostname, err, -1, nil}
104 }
105
106 if hostname == "ipv4.and.ipv6.localhost" {
107 return []net.IP{
108 net.ParseIP("::1"),
109 net.ParseIP("127.0.0.1"),
110 }, nil
111 }
112 if hostname == "ipv6.localhost" {
113 return []net.IP{
114 net.ParseIP("::1"),
115 }, nil
116 }
117 ip := net.ParseIP("127.0.0.1")
118 return []net.IP{ip}, nil
119 }
120
121
122 func (mock *MockClient) LookupCAA(_ context.Context, domain string) ([]*dns.CAA, string, error) {
123 return nil, "", nil
124 }
125
View as plain text