Skip to content
File

Blob: acme/dns_test.go

go143 lines
1package acme
2 
3import (
4 "bytes"
5 "fmt"
6 "net"
7 "testing"
8 
9 "go.miragespace.co/specter/spec/mocks"
10 
11 "github.com/miekg/dns"
12 "github.com/stretchr/testify/mock"
13 "github.com/stretchr/testify/require"
14 "go.uber.org/zap/zaptest"
15)
16 
17const (
18 testEmail = "test@test.com"
19 testDomain = "acme.example.com"
20 testNSName = "ns.acme.example.com"
21 testNSContentA = "192.168.1.1"
22 testNSContentAAAA = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
23 testTXTSubdomain = "subdomain"
24 testTXTResponse = "hello"
25)
26 
27func getUDPListener(as *require.Assertions) (net.PacketConn, int) {
28 l, err := net.ListenPacket("udp", "127.0.0.1:0")
29 as.NoError(err)
30 
31 return l, l.LocalAddr().(*net.UDPAddr).Port
32}
33 
34func TestStaticQuery(t *testing.T) {
35 as := require.New(t)
36 logger := zaptest.NewLogger(t)
37 
38 kv := new(mocks.VNode)
39 defer kv.AssertExpectations(t)
40 
41 ctx := t.Context()
42 
43 h := NewDNS(ctx, logger, kv, testEmail, testDomain, map[string][]string{
44 testNSName: {testNSContentA, testNSContentAAAA},
45 })
46 
47 listener, port := getUDPListener(as)
48 defer listener.Close()
49 
50 mux := dns.NewServeMux()
51 mux.Handle(testDomain, h)
52 srv := &dns.Server{
53 PacketConn: listener,
54 Handler: mux,
55 }
56 go srv.ActivateAndServe()
57 
58 var (
59 client = &dns.Client{}
60 resp, m *dns.Msg
61 err error
62 )
63 
64 // SOA
65 m = new(dns.Msg)
66 m.SetQuestion(dns.CanonicalName(testDomain), dns.TypeSOA)
67 resp, _, err = client.Exchange(m, fmt.Sprintf("127.0.0.1:%d", port))
68 as.NoError(err)
69 
70 as.Len(resp.Answer, 1)
71 soa, ok := resp.Answer[0].(*dns.SOA)
72 as.True(ok)
73 as.Equal(dns.CanonicalName(testNSName), soa.Ns)
74 
75 // NS A record
76 m = new(dns.Msg)
77 m.SetQuestion(dns.CanonicalName(testNSName), dns.TypeA)
78 resp, _, err = client.Exchange(m, fmt.Sprintf("127.0.0.1:%d", port))
79 as.NoError(err)
80 
81 as.Len(resp.Answer, 1)
82 nsA, ok := resp.Answer[0].(*dns.A)
83 as.True(ok)
84 as.EqualValues(net.ParseIP(testNSContentA).To4(), nsA.A)
85 
86 // NS AAAA record
87 m = new(dns.Msg)
88 m.SetQuestion(dns.CanonicalName(testNSName), dns.TypeAAAA)
89 resp, _, err = client.Exchange(m, fmt.Sprintf("127.0.0.1:%d", port))
90 as.NoError(err)
91 
92 as.Len(resp.Answer, 1)
93 nsAAAA, ok := resp.Answer[0].(*dns.AAAA)
94 as.True(ok)
95 as.EqualValues(net.ParseIP(testNSContentAAAA), nsAAAA.AAAA)
96}
97 
98func TestDynamicQuery(t *testing.T) {
99 as := require.New(t)
100 logger := zaptest.NewLogger(t)
101 
102 kv := new(mocks.VNode)
103 defer kv.AssertExpectations(t)
104 
105 ctx := t.Context()
106 
107 h := NewDNS(ctx, logger, kv, testEmail, testDomain, map[string][]string{
108 testNSName: {testNSContentA, testNSContentAAAA},
109 })
110 
111 listener, port := getUDPListener(as)
112 defer listener.Close()
113 
114 mux := dns.NewServeMux()
115 mux.Handle(testDomain, h)
116 srv := &dns.Server{
117 PacketConn: listener,
118 Handler: mux,
119 }
120 go srv.ActivateAndServe()
121 
122 var (
123 client = &dns.Client{}
124 resp, m *dns.Msg
125 err error
126 )
127 
128 kv.On("PrefixList", mock.Anything, mock.MatchedBy(func(prefix []byte) bool {
129 return bytes.Equal(prefix, []byte(dnsKeyName(testTXTSubdomain)))
130 })).Return([][]byte{[]byte(testTXTResponse)}, nil)
131 
132 m = new(dns.Msg)
133 m.SetQuestion(dns.CanonicalName(fmt.Sprintf("%s.%s", testTXTSubdomain, testDomain)), dns.TypeTXT)
134 resp, _, err = client.Exchange(m, fmt.Sprintf("127.0.0.1:%d", port))
135 as.NoError(err)
136 
137 as.Len(resp.Answer, 1)
138 txt, ok := resp.Answer[0].(*dns.TXT)
139 as.True(ok)
140 as.Len(txt.Txt, 1)
141 as.Equal(testTXTResponse, txt.Txt[0])
142}