]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.recursor-dnssec/test_DNS64.py
Merge pull request #13904 from jsoref/issue-menu
[thirdparty/pdns.git] / regression-tests.recursor-dnssec / test_DNS64.py
1 import dns
2 import os
3
4 from recursortests import RecursorTest
5
6 class DNS64RecursorTest(RecursorTest):
7
8 _confdir = 'DNS64'
9 _config_template = """
10 auth-zones=example.dns64=configs/%s/example.dns64.zone
11 auth-zones+=in-addr.arpa=configs/%s/in-addr.arpa.zone
12 auth-zones+=ip6.arpa=configs/%s/ip6.arpa.zone
13
14 dns64-prefix=64:ff9b::/96
15 """ % (_confdir, _confdir, _confdir)
16
17 _lua_dns_script_file = """
18 function nodata(dq)
19 if dq.qtype == pdns.AAAA and dq.qname:equal("formerr.example.dns64") then
20 dq.rcode = pdns.FORMERR
21 return true
22 end
23 return false
24 end
25 """
26
27 @classmethod
28 def generateRecursorConfig(cls, confdir):
29 authzonepath = os.path.join(confdir, 'example.dns64.zone')
30 with open(authzonepath, 'w') as authzone:
31 authzone.write("""$ORIGIN example.dns64
32 @ 3600 IN SOA {soa}
33 www 3600 IN A 192.0.2.42
34 www 3600 IN TXT "does exist"
35 aaaa 3600 IN AAAA 2001:db8::1
36 cname 3600 IN CNAME cname2.example.dns64.
37 cname2 3600 IN CNAME www.example.dns64.
38 formerr 3600 IN A 192.0.2.43
39 """.format(soa=cls._SOA))
40
41 authzonepath = os.path.join(confdir, 'in-addr.arpa.zone')
42 with open(authzonepath, 'w') as authzone:
43 authzone.write("""$ORIGIN in-addr.arpa
44 @ 3600 IN SOA {soa}
45 42.2.0.192 IN PTR www.example.dns64.
46 """.format(soa=cls._SOA))
47
48 authzonepath = os.path.join(confdir, 'ip6.arpa.zone')
49 with open(authzonepath, 'w') as authzone:
50 authzone.write("""$ORIGIN ip6.arpa
51 @ 3600 IN SOA {soa}
52 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2 IN PTR aaaa.example.dns64.
53 """.format(soa=cls._SOA))
54
55 super(DNS64RecursorTest, cls).generateRecursorConfig(confdir)
56
57 # this type (A) exists for this name
58 def testExistingA(self):
59 qname = 'www.example.dns64.'
60 expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'A', '192.0.2.42')
61
62 query = dns.message.make_query(qname, 'A', want_dnssec=True)
63 for method in ("sendUDPQuery", "sendTCPQuery"):
64 sender = getattr(self, method)
65 res = sender(query)
66 self.assertRcodeEqual(res, dns.rcode.NOERROR)
67 self.assertRRsetInAnswer(res, expected)
68
69 # there is no A record, we should get a NODATA
70 def testNonExistingA(self):
71 qname = 'aaaa.example.dns64.'
72
73 query = dns.message.make_query(qname, 'A', want_dnssec=True)
74 for method in ("sendUDPQuery", "sendTCPQuery"):
75 sender = getattr(self, method)
76 res = sender(query)
77 self.assertRcodeEqual(res, dns.rcode.NOERROR)
78 self.assertEqual(len(res.answer), 0)
79
80 # this type (AAAA) does not exist for this name but there is an A record, we should get a DNS64-wrapped AAAA
81 def testNonExistingAAAA(self):
82 qname = 'www.example.dns64.'
83 expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'AAAA', '64:ff9b::c000:22a')
84
85 query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
86 for method in ("sendUDPQuery", "sendTCPQuery"):
87 sender = getattr(self, method)
88 res = sender(query)
89 self.assertRcodeEqual(res, dns.rcode.NOERROR)
90 self.assertRRsetInAnswer(res, expected)
91
92 # there is a CNAME from that name to a second one, then to a name for which this type (AAAA)
93 # does not exist, but an A record does, so we should get a DNS64-wrapped AAAA
94 def testCNAMEToA(self):
95 qname = 'cname.example.dns64.'
96 expectedResults = [
97 dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'CNAME', 'cname2.example.dns64.'),
98 dns.rrset.from_text('cname2.example.dns64.', 0, dns.rdataclass.IN, 'CNAME', 'www.example.dns64.'),
99 dns.rrset.from_text('www.example.dns64.', 0, dns.rdataclass.IN, 'AAAA', '64:ff9b::c000:22a')
100 ]
101
102 query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
103 for method in ("sendUDPQuery", "sendTCPQuery"):
104 sender = getattr(self, method)
105 res = sender(query)
106 self.assertRcodeEqual(res, dns.rcode.NOERROR)
107 for expected in expectedResults:
108 self.assertRRsetInAnswer(res, expected)
109
110 # this type (AAAA) does not exist for this name and there is no A record either, we should get a NXDomain
111 def testNXD(self):
112 qname = 'nxd.example.dns64.'
113
114 query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
115 for method in ("sendUDPQuery", "sendTCPQuery"):
116 sender = getattr(self, method)
117 res = sender(query)
118 self.assertRcodeEqual(res, dns.rcode.NXDOMAIN)
119
120 # there is an AAAA record, we should get it
121 def testExistingAAAA(self):
122 qname = 'aaaa.example.dns64.'
123 expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'AAAA', '2001:db8::1')
124
125 query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
126 for method in ("sendUDPQuery", "sendTCPQuery"):
127 sender = getattr(self, method)
128 res = sender(query)
129 self.assertRcodeEqual(res, dns.rcode.NOERROR)
130 self.assertRRsetInAnswer(res, expected)
131
132 # If the AAAA is handled by Lua code, we should not get a dns64 result
133 def testFormerr(self):
134 qname = 'formerr.example.dns64'
135
136 query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
137 for method in ("sendUDPQuery", "sendTCPQuery"):
138 sender = getattr(self, method)
139 res = sender(query)
140 self.assertRcodeEqual(res, dns.rcode.FORMERR)
141
142 # If the AAAA times out, we still should get a dns64 result
143 def testTimeout(self):
144 qname = '8.delay1.example.'
145 expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'AAAA', '64:ff9b::c000:264')
146
147 query = dns.message.make_query(qname, 'AAAA', want_dnssec=True)
148 for method in ("sendUDPQuery", "sendTCPQuery"):
149 sender = getattr(self, method)
150 res = sender(query)
151 self.assertRcodeEqual(res, dns.rcode.NOERROR)
152 self.assertRRsetInAnswer(res, expected)
153
154 # there is a TXT record, we should get it
155 def testExistingTXT(self):
156 qname = 'www.example.dns64.'
157 expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'TXT', '"does exist"')
158
159 query = dns.message.make_query(qname, 'TXT', want_dnssec=True)
160 for method in ("sendUDPQuery", "sendTCPQuery"):
161 sender = getattr(self, method)
162 res = sender(query)
163 self.assertRcodeEqual(res, dns.rcode.NOERROR)
164 self.assertRRsetInAnswer(res, expected)
165
166 # the PTR records for the DNS64 prefix should be generated
167 def testNonExistingPTR(self):
168 qname = 'a.2.2.0.0.0.0.c.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa.'
169 expectedCNAME = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'CNAME', '42.2.0.192.in-addr.arpa.')
170 expected = dns.rrset.from_text('42.2.0.192.in-addr.arpa.', 0, dns.rdataclass.IN, 'PTR', 'www.example.dns64.')
171
172 query = dns.message.make_query(qname, 'PTR', want_dnssec=True)
173 for method in ("sendUDPQuery", "sendTCPQuery"):
174 sender = getattr(self, method)
175 res = sender(query)
176 print(res)
177 self.assertRcodeEqual(res, dns.rcode.NOERROR)
178 self.assertRRsetInAnswer(res, expectedCNAME)
179 self.assertRRsetInAnswer(res, expected)
180
181 # but not for other prefixes
182 def testExistingPTR(self):
183 qname = '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.'
184 expected = dns.rrset.from_text(qname, 0, dns.rdataclass.IN, 'PTR', 'aaaa.example.dns64.')
185
186 query = dns.message.make_query(qname, 'PTR', want_dnssec=True)
187 for method in ("sendUDPQuery", "sendTCPQuery"):
188 sender = getattr(self, method)
189 res = sender(query)
190 self.assertRcodeEqual(res, dns.rcode.NOERROR)
191 self.assertRRsetInAnswer(res, expected)