2 * testcode/unitauth.c - unit test for authzone authoritative zone code.
4 * Copyright (c) 2017, NLnet Labs. All rights reserved.
6 * This software is open source.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Unit test for auth zone code.
41 #include "services/authzone.h"
42 #include "testcode/unitmain.h"
43 #include "util/regional.h"
44 #include "util/net_help.h"
45 #include "util/config_file.h"
46 #include "util/data/msgreply.h"
47 #include "services/cache/dns.h"
48 #include "sldns/str2wire.h"
49 #include "sldns/wire2str.h"
50 #include "sldns/sbuffer.h"
52 /** verbosity for this test */
55 /** struct for query and answer checks */
57 /** zone to query (delegpt) */
59 /** query name, class, type */
61 /** additional flags or "" */
63 /** expected answer to check against, multi-line string */
67 /** auth zone for test */
68 static const char* zone_example_com =
69 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
70 "example.com. 3600 IN A 10.0.0.1\n"
71 "example.com. 3600 IN NS ns.example.com.\n"
72 "example.com. 3600 IN MX 50 mail.example.com.\n"
73 "deep.ent.example.com. 3600 IN A 10.0.0.9\n"
74 "mail.example.com. 3600 IN A 10.0.0.4\n"
75 "ns.example.com. 3600 IN A 10.0.0.5\n"
76 "out.example.com. 3600 IN CNAME www.example.com.\n"
77 "plan.example.com. 3600 IN CNAME nonexist.example.com.\n"
78 "redir.example.com. 3600 IN DNAME redir.example.org.\n"
79 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
80 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
81 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
82 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
83 "*.wild.example.com. 3600 IN A 10.0.0.8\n"
84 "*.wild2.example.com. 3600 IN CNAME www.example.com.\n"
85 "*.wild3.example.com. 3600 IN A 10.0.0.8\n"
86 "*.wild3.example.com. 3600 IN MX 50 mail.example.com.\n"
87 "www.example.com. 3600 IN A 10.0.0.2\n"
88 "www.example.com. 3600 IN A 10.0.0.3\n"
89 "yy.example.com. 3600 IN TXT \"a\"\n"
90 "yy.example.com. 3600 IN TXT \"b\"\n"
91 "yy.example.com. 3600 IN TXT \"c\"\n"
92 "yy.example.com. 3600 IN TXT \"d\"\n"
93 "yy.example.com. 3600 IN TXT \"e\"\n"
94 "yy.example.com. 3600 IN TXT \"f\"\n"
96 /* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */
97 /* normal: domain and 1 rrsig */
98 "z1.example.com. 3600 IN A 10.0.0.10\n"
99 "z1.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
100 /* normal: domain and 2 rrsigs */
101 "z2.example.com. 3600 IN A 10.0.0.10\n"
102 "z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
103 "z2.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
104 /* normal: domain and 3 rrsigs */
105 "z3.example.com. 3600 IN A 10.0.0.10\n"
106 "z3.example.com. 3600 IN A 10.0.0.11\n"
107 "z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
108 "z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
109 "z3.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12356 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
110 /* just an RRSIG rrset with nothing else */
111 "z4.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
112 /* just an RRSIG rrset with nothing else, 2 rrsigs */
113 "z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
114 "z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
115 #if 1 /* comparison of file does not work on this part because duplicates */
116 /* are removed and the rrsets are reordered */
117 "end_of_check.z6.example.com. 3600 IN A 10.0.0.10\n"
118 /* first rrsig, then A record */
119 "z6.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
120 "z6.example.com. 3600 IN A 10.0.0.10\n"
121 /* first two rrsigs, then A record */
122 "z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
123 "z7.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
124 "z7.example.com. 3600 IN A 10.0.0.10\n"
125 /* first two rrsigs, then two A records */
126 "z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
127 "z8.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
128 "z8.example.com. 3600 IN A 10.0.0.10\n"
129 "z8.example.com. 3600 IN A 10.0.0.11\n"
130 /* duplicate RR, duplicate RRsig */
131 "z9.example.com. 3600 IN A 10.0.0.10\n"
132 "z9.example.com. 3600 IN A 10.0.0.11\n"
133 "z9.example.com. 3600 IN A 10.0.0.10\n"
134 "z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
135 "z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
136 /* different covered types, first RRSIGs then, RRs, then another RRSIG */
137 "zz10.example.com. 3600 IN RRSIG AAAA 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
138 "zz10.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
139 "zz10.example.com. 3600 IN A 10.0.0.10\n"
140 "zz10.example.com. 3600 IN RRSIG CNAME 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
141 "zz10.example.com. 3600 IN AAAA ::11\n"
142 #endif /* if0 for duplicates and reordering */
145 /** queries for example.com: zone, query, flags, answer. end with NULL */
146 static struct q_ans example_com_queries[] = {
147 { "example.com", "www.example.com. A", "",
148 ";flags QR AA rcode NOERROR\n"
150 "www.example.com. 3600 IN A 10.0.0.2\n"
151 "www.example.com. 3600 IN A 10.0.0.3\n"
154 { "example.com", "example.com. SOA", "",
155 ";flags QR AA rcode NOERROR\n"
157 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
160 { "example.com", "example.com. A", "",
161 ";flags QR AA rcode NOERROR\n"
163 "example.com. 3600 IN A 10.0.0.1\n"
166 { "example.com", "example.com. AAAA", "",
167 ";flags QR AA rcode NOERROR\n"
168 ";authority section\n"
169 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
172 { "example.com", "example.com. NS", "",
173 ";flags QR AA rcode NOERROR\n"
175 "example.com. 3600 IN NS ns.example.com.\n"
176 ";additional section\n"
177 "ns.example.com. 3600 IN A 10.0.0.5\n"
180 { "example.com", "example.com. MX", "",
181 ";flags QR AA rcode NOERROR\n"
183 "example.com. 3600 IN MX 50 mail.example.com.\n"
184 ";additional section\n"
185 "mail.example.com. 3600 IN A 10.0.0.4\n"
188 { "example.com", "example.com. IN ANY", "",
189 ";flags QR AA rcode NOERROR\n"
191 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
192 "example.com. 3600 IN MX 50 mail.example.com.\n"
193 "example.com. 3600 IN A 10.0.0.1\n"
196 { "example.com", "nonexist.example.com. A", "",
197 ";flags QR AA rcode NXDOMAIN\n"
198 ";authority section\n"
199 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
202 { "example.com", "deep.ent.example.com. A", "",
203 ";flags QR AA rcode NOERROR\n"
205 "deep.ent.example.com. 3600 IN A 10.0.0.9\n"
208 { "example.com", "ent.example.com. A", "",
209 ";flags QR AA rcode NOERROR\n"
210 ";authority section\n"
211 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
214 { "example.com", "below.deep.ent.example.com. A", "",
215 ";flags QR AA rcode NXDOMAIN\n"
216 ";authority section\n"
217 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
220 { "example.com", "mail.example.com. A", "",
221 ";flags QR AA rcode NOERROR\n"
223 "mail.example.com. 3600 IN A 10.0.0.4\n"
226 { "example.com", "ns.example.com. A", "",
227 ";flags QR AA rcode NOERROR\n"
229 "ns.example.com. 3600 IN A 10.0.0.5\n"
232 { "example.com", "out.example.com. A", "",
233 ";flags QR AA rcode NOERROR\n"
235 "out.example.com. 3600 IN CNAME www.example.com.\n"
236 "www.example.com. 3600 IN A 10.0.0.2\n"
237 "www.example.com. 3600 IN A 10.0.0.3\n"
240 { "example.com", "out.example.com. CNAME", "",
241 ";flags QR AA rcode NOERROR\n"
243 "out.example.com. 3600 IN CNAME www.example.com.\n"
246 { "example.com", "plan.example.com. A", "",
247 ";flags QR AA rcode NOERROR\n"
249 "plan.example.com. 3600 IN CNAME nonexist.example.com.\n"
252 { "example.com", "plan.example.com. CNAME", "",
253 ";flags QR AA rcode NOERROR\n"
255 "plan.example.com. 3600 IN CNAME nonexist.example.com.\n"
258 { "example.com", "redir.example.com. A", "",
259 ";flags QR AA rcode NOERROR\n"
260 ";authority section\n"
261 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
264 { "example.com", "redir.example.com. DNAME", "",
265 ";flags QR AA rcode NOERROR\n"
267 "redir.example.com. 3600 IN DNAME redir.example.org.\n"
270 { "example.com", "abc.redir.example.com. A", "",
271 ";flags QR AA rcode NOERROR\n"
273 "redir.example.com. 3600 IN DNAME redir.example.org.\n"
274 "abc.redir.example.com. 0 IN CNAME abc.redir.example.org.\n"
277 { "example.com", "foo.abc.redir.example.com. A", "",
278 ";flags QR AA rcode NOERROR\n"
280 "redir.example.com. 3600 IN DNAME redir.example.org.\n"
281 "foo.abc.redir.example.com. 0 IN CNAME foo.abc.redir.example.org.\n"
284 { "example.com", "sub.example.com. NS", "",
285 ";flags QR rcode NOERROR\n"
286 ";authority section\n"
287 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
288 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
289 ";additional section\n"
290 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
291 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
294 { "example.com", "sub.example.com. DS", "",
295 ";flags QR AA rcode NOERROR\n"
296 ";authority section\n"
297 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
300 { "example.com", "www.sub.example.com. NS", "",
301 ";flags QR rcode NOERROR\n"
302 ";authority section\n"
303 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
304 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
305 ";additional section\n"
306 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
307 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
310 { "example.com", "foo.abc.sub.example.com. NS", "",
311 ";flags QR rcode NOERROR\n"
312 ";authority section\n"
313 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
314 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
315 ";additional section\n"
316 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
317 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
320 { "example.com", "ns1.sub.example.com. A", "",
321 ";flags QR rcode NOERROR\n"
322 ";authority section\n"
323 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
324 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
325 ";additional section\n"
326 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
327 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
330 { "example.com", "ns1.sub.example.com. AAAA", "",
331 ";flags QR rcode NOERROR\n"
332 ";authority section\n"
333 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
334 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
335 ";additional section\n"
336 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
337 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
340 { "example.com", "ns2.sub.example.com. A", "",
341 ";flags QR rcode NOERROR\n"
342 ";authority section\n"
343 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
344 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
345 ";additional section\n"
346 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
347 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
350 { "example.com", "ns2.sub.example.com. AAAA", "",
351 ";flags QR rcode NOERROR\n"
352 ";authority section\n"
353 "sub.example.com. 3600 IN NS ns1.sub.example.com.\n"
354 "sub.example.com. 3600 IN NS ns2.sub.example.com.\n"
355 ";additional section\n"
356 "ns1.sub.example.com. 3600 IN A 10.0.0.6\n"
357 "ns2.sub.example.com. 3600 IN AAAA 2001::7\n"
360 { "example.com", "wild.example.com. A", "",
361 ";flags QR AA rcode NOERROR\n"
362 ";authority section\n"
363 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
366 { "example.com", "*.wild.example.com. A", "",
367 ";flags QR AA rcode NOERROR\n"
369 "*.wild.example.com. 3600 IN A 10.0.0.8\n"
372 { "example.com", "*.wild.example.com. AAAA", "",
373 ";flags QR AA rcode NOERROR\n"
374 ";authority section\n"
375 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
378 { "example.com", "abc.wild.example.com. A", "",
379 ";flags QR AA rcode NOERROR\n"
381 "abc.wild.example.com. 3600 IN A 10.0.0.8\n"
384 { "example.com", "abc.wild.example.com. AAAA", "",
385 ";flags QR AA rcode NOERROR\n"
386 ";authority section\n"
387 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
390 { "example.com", "foo.abc.wild.example.com. A", "",
391 ";flags QR AA rcode NOERROR\n"
393 "foo.abc.wild.example.com. 3600 IN A 10.0.0.8\n"
396 { "example.com", "foo.abc.wild.example.com. AAAA", "",
397 ";flags QR AA rcode NOERROR\n"
398 ";authority section\n"
399 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
402 { "example.com", "wild2.example.com. A", "",
403 ";flags QR AA rcode NOERROR\n"
404 ";authority section\n"
405 "example.com. 3600 IN SOA ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
408 { "example.com", "*.wild2.example.com. A", "",
409 ";flags QR AA rcode NOERROR\n"
411 "*.wild2.example.com. 3600 IN CNAME www.example.com.\n"
412 "www.example.com. 3600 IN A 10.0.0.2\n"
413 "www.example.com. 3600 IN A 10.0.0.3\n"
416 { "example.com", "abc.wild2.example.com. A", "",
417 ";flags QR AA rcode NOERROR\n"
419 "abc.wild2.example.com. 3600 IN CNAME www.example.com.\n"
420 "www.example.com. 3600 IN A 10.0.0.2\n"
421 "www.example.com. 3600 IN A 10.0.0.3\n"
424 { "example.com", "foo.abc.wild2.example.com. A", "",
425 ";flags QR AA rcode NOERROR\n"
427 "foo.abc.wild2.example.com. 3600 IN CNAME www.example.com.\n"
428 "www.example.com. 3600 IN A 10.0.0.2\n"
429 "www.example.com. 3600 IN A 10.0.0.3\n"
432 { "example.com", "abc.wild2.example.com. CNAME", "",
433 ";flags QR AA rcode NOERROR\n"
435 "abc.wild2.example.com. 3600 IN CNAME www.example.com.\n"
438 { "example.com", "abc.wild3.example.com. IN ANY", "",
439 ";flags QR AA rcode NOERROR\n"
441 "abc.wild3.example.com. 3600 IN MX 50 mail.example.com.\n"
442 "abc.wild3.example.com. 3600 IN A 10.0.0.8\n"
445 { "example.com", "yy.example.com. TXT", "",
446 ";flags QR AA rcode NOERROR\n"
448 "yy.example.com. 3600 IN TXT \"a\"\n"
449 "yy.example.com. 3600 IN TXT \"b\"\n"
450 "yy.example.com. 3600 IN TXT \"c\"\n"
451 "yy.example.com. 3600 IN TXT \"d\"\n"
452 "yy.example.com. 3600 IN TXT \"e\"\n"
453 "yy.example.com. 3600 IN TXT \"f\"\n"
456 {NULL, NULL, NULL, NULL}
459 /** number of tmpfiles */
460 static int tempno = 0;
461 /** number of deleted files */
462 static int delno = 0;
464 /** cleanup tmp files at exit */
470 for(i=0; i<tempno; i++) {
471 snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
472 (unsigned)getpid(), i);
473 if(vbmp) printf("cleanup: unlink %s\n", buf);
478 /** create temp file, return (malloced) name string, write contents to it */
480 create_tmp_file(const char* s)
486 snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
487 (unsigned)getpid(), tempno++);
489 if(!fname) fatal_exit("out of memory");
490 /* if no string, just make the name */
492 /* if string, write to file */
493 out = fopen(fname, "w");
494 if(!out) fatal_exit("cannot open %s: %s", fname, strerror(errno));
495 r = fwrite(s, 1, strlen(s), out);
497 fatal_exit("write failed: %s", strerror(errno));
498 } else if(r < strlen(s)) {
499 fatal_exit("write failed: too short (disk full?)");
505 /** delete temp file and free name string */
507 del_tmp_file(char* fname)
512 if(delno == tempno) {
513 /* deleted all outstanding files, back to start condition */
519 /** Add zone from file for testing */
520 static struct auth_zone*
521 addzone(struct auth_zones* az, const char* name, char* fname)
525 uint8_t* nm = sldns_str2wire_dname(name, &nmlen);
526 struct config_file* cfg;
527 if(!nm) fatal_exit("out of memory");
528 lock_rw_wrlock(&az->lock);
529 z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN);
530 lock_rw_unlock(&az->lock);
531 if(!z) fatal_exit("cannot find zone");
532 auth_zone_set_zonefile(z, fname);
534 cfg = config_create();
535 free(cfg->chrootdir);
536 cfg->chrootdir = NULL;
538 if(!auth_zone_read_zonefile(z, cfg)) {
539 fatal_exit("parse failure for auth zone %s", name);
541 lock_rw_unlock(&z->lock);
547 /** check that file is the same as other file */
549 checkfile(char* f1, char *f2)
551 char buf1[10240], buf2[10240];
555 if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno));
557 if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno));
559 while(!feof(i1) && !feof(i2)) {
562 cp1 = fgets(buf1, (int)sizeof(buf1), i1);
563 cp2 = fgets(buf2, (int)sizeof(buf2), i2);
564 if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2)))
565 fatal_exit("fgets failed: %s", strerror(errno));
566 if(strncmp(buf1, "end_of_check", 12) == 0) {
571 if(strcmp(buf1, buf2) != 0) {
572 log_info("in files %s and %s:%d", f1, f2, line);
573 log_info("'%s'", buf1);
574 log_info("'%s'", buf2);
575 fatal_exit("files are not equal");
578 unit_assert(feof(i1) && feof(i2));
584 /** check that a zone (in string) can be read and reproduced */
586 check_read_exact(const char* name, const char* zone)
588 struct auth_zones* az;
591 if(vbmp) printf("check read zone %s\n", name);
592 fname = create_tmp_file(zone);
594 az = auth_zones_create();
596 z = addzone(az, name, fname);
598 outf = create_tmp_file(NULL);
599 if(!auth_zone_write_file(z, outf)) {
600 fatal_exit("write file failed for %s", fname);
602 checkfile(fname, outf);
606 auth_zones_delete(az);
609 /** parse q_ans structure for making query */
611 q_ans_parse(struct q_ans* q, struct regional* region,
612 struct query_info** qinfo, int* fallback, uint8_t** dp_nm,
617 size_t len, dname_len;
620 *fallback = 0; /* default fallback value */
621 if(strstr(q->flags, "fallback"))
625 *dp_nmlen = sizeof(buf);
626 if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0)
627 fatal_exit("cannot parse query dp zone %s : %s", q->zone,
628 sldns_get_errorstr_parse(ret));
629 *dp_nm = regional_alloc_init(region, buf, *dp_nmlen);
630 if(!dp_nm) fatal_exit("out of memory");
635 if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len,
636 *dp_nm, *dp_nmlen, NULL, 0))!=0)
637 fatal_exit("cannot parse query %s : %s", q->query,
638 sldns_get_errorstr_parse(ret));
639 *qinfo = (struct query_info*)regional_alloc_zero(region,
641 if(!*qinfo) fatal_exit("out of memory");
642 (*qinfo)->qname = regional_alloc_init(region, buf, dname_len);
643 if(!(*qinfo)->qname) fatal_exit("out of memory");
644 (*qinfo)->qname_len = dname_len;
645 (*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len);
646 (*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len);
649 /** print flags to string */
651 pr_flags(sldns_buffer* buf, uint16_t flags)
654 sldns_buffer_printf(buf, ";flags");
655 if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR");
656 if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA");
657 if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC");
658 if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD");
659 if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD");
660 if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA");
661 if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD");
662 if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z");
663 sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)),
664 rcode, sizeof(rcode));
665 sldns_buffer_printf(buf, " rcode %s", rcode);
666 sldns_buffer_printf(buf, "\n");
669 /** print RRs to string */
671 pr_rrs(sldns_buffer* buf, struct reply_info* rep)
675 struct packed_rrset_data* d;
676 log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets
677 + rep->ar_numrrsets);
678 for(i=0; i<rep->rrset_count; i++) {
679 /* section heading */
680 if(i == 0 && rep->an_numrrsets != 0)
681 sldns_buffer_printf(buf, ";answer section\n");
682 else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0)
683 sldns_buffer_printf(buf, ";authority section\n");
684 else if(i == rep->an_numrrsets+rep->ns_numrrsets &&
685 rep->ar_numrrsets != 0)
686 sldns_buffer_printf(buf, ";additional section\n");
688 d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
689 for(j=0; j<d->count+d->rrsig_count; j++) {
690 if(!packed_rr_to_string(rep->rrsets[i], j, 0,
692 fatal_exit("could not rr_to_string %d",
695 sldns_buffer_printf(buf, "%s", s);
700 /** create string for message */
702 msgtostr(struct dns_msg* msg)
705 sldns_buffer* buf = sldns_buffer_new(65535);
706 if(!buf) fatal_exit("out of memory");
708 sldns_buffer_printf(buf, "null packet\n");
710 pr_flags(buf, msg->rep->flags);
711 pr_rrs(buf, msg->rep);
714 str = strdup((char*)sldns_buffer_begin(buf));
715 if(!str) fatal_exit("out of memory");
716 sldns_buffer_free(buf);
720 /** find line diff between strings */
722 line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc)
724 char* pdup, *qdup, *pl, *ql;
728 if(!pdup || !qdup) fatal_exit("out of memory");
731 printf("linediff (<%s, >%s)\n", pdesc, qdesc);
732 while(pl && ql && *pl && *ql) {
733 char* ep = strchr(pl, '\n');
734 char* eq = strchr(ql, '\n');
735 /* terminate lines */
739 if(strcmp(pl, ql) == 0) {
740 printf("%3d %s\n", line, pl);
742 printf("%3d < %s\n", line, pl);
743 printf("%3d > %s\n", line, ql);
754 printf("%3d < %s\n", line, pl);
757 printf("%3d > %s\n", line, ql);
763 /** make q_ans query */
765 q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo,
766 struct regional* region, int expected_fallback, uint8_t* dp_nm,
769 int ret, fallback = 0;
770 struct dns_msg* msg = NULL;
772 int oldv = verbosity;
773 /* increase verbosity to printout logic in authzone */
774 if(vbmp) verbosity = 4;
775 ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm,
777 if(vbmp) verbosity = oldv;
779 /* check the answer */
780 ans_str = msgtostr(msg);
781 /* printout if vbmp */
782 if(vbmp) printf("got (ret=%s%s):\n%s",
783 (ret?"ok":"fail"), (fallback?" fallback":""), ans_str);
784 /* check expected value for ret */
785 if(expected_fallback && ret != 0) {
786 /* ret is zero on fallback */
787 if(vbmp) printf("fallback expected, but "
788 "return value is not false\n");
789 unit_assert(expected_fallback && ret == 0);
792 if(!expected_fallback) {
793 if(vbmp) printf("return value is false, "
796 unit_assert(expected_fallback);
798 /* check expected value for fallback */
799 if(expected_fallback && !fallback) {
800 if(vbmp) printf("expected fallback, but fallback is no\n");
801 } else if(!expected_fallback && fallback) {
802 if(vbmp) printf("expected no fallback, but fallback is yes\n");
804 unit_assert( (expected_fallback&&fallback) ||
805 (!expected_fallback&&!fallback));
806 /* check answer string */
807 if(strcmp(q->answer, ans_str) != 0) {
808 if(vbmp) printf("wanted:\n%s", q->answer);
809 line_diff(q->answer, ans_str, "wanted", "got");
811 unit_assert(strcmp(q->answer, ans_str) == 0);
812 if(vbmp) printf("query ok\n\n");
816 /** check queries on a loaded zone */
818 check_az_q_ans(struct auth_zones* az, struct q_ans* queries)
821 struct regional* region = regional_create();
822 struct query_info* qinfo;
826 for(q=queries; q->zone; q++) {
827 if(vbmp) printf("query %s: %s %s\n", q->zone, q->query,
829 q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen);
830 q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen);
831 regional_free_all(region);
833 regional_destroy(region);
836 /** check queries for a zone are returned as specified */
838 check_queries(const char* name, const char* zone, struct q_ans* queries)
840 struct auth_zones* az;
843 if(vbmp) printf("check queries %s\n", name);
844 fname = create_tmp_file(zone);
845 az = auth_zones_create();
846 if(!az) fatal_exit("out of memory");
847 z = addzone(az, name, fname);
848 if(!z) fatal_exit("could not read zone for queries test");
851 /* run queries and test them */
852 check_az_q_ans(az, queries);
854 auth_zones_delete(az);
857 /** Test authzone compare_serial */
859 authzone_compare_serial(void)
861 if(vbmp) printf("Testing compare_serial\n");
862 unit_assert(compare_serial(0, 1) < 0);
863 unit_assert(compare_serial(1, 0) > 0);
864 unit_assert(compare_serial(0, 0) == 0);
865 unit_assert(compare_serial(1, 1) == 0);
866 unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
867 unit_assert(compare_serial(0, 0xf0000000) > 0);
868 unit_assert(compare_serial(0xf0000000, 0) < 0);
869 unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
870 unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
871 unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
872 unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
875 /** Test authzone read from file */
877 authzone_read_test(void)
879 if(vbmp) printf("Testing read auth zone\n");
880 check_read_exact("example.com", zone_example_com);
883 /** Test authzone query from zone */
885 authzone_query_test(void)
887 if(vbmp) printf("Testing query auth zone\n");
888 check_queries("example.com", zone_example_com, example_com_queries);
891 /** test authzone code */
895 unit_show_feature("authzone");
896 atexit(tmpfilecleanup);
897 authzone_compare_serial();
898 authzone_read_test();
899 authzone_query_test();