1/*
2 * testcode/unitauth.c - unit test for authzone authoritative zone code.
3 *
4 * Copyright (c) 2017, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
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.
18 *
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.
22 *
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.
34 *
35 */
36/**
37 * \file
38 * Unit test for auth zone code.
39 */
40#include "config.h"
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"
51
52/** verbosity for this test */
53static int vbmp = 0;
54
55/** struct for query and answer checks */
56struct q_ans {
57	/** zone to query (delegpt) */
58	const char* zone;
59	/** query name, class, type */
60	const char* query;
61	/** additional flags or "" */
62	const char* flags;
63	/** expected answer to check against, multi-line string */
64	const char* answer;
65};
66
67/** auth zone for test */
68static 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"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
80"obscured.redir2.example.com.	3600	IN	A	10.0.0.12\n"
81"under2.redir2.example.com.	3600	IN	DNAME	redir3.example.net.\n"
82"doubleobscured.under2.redir2.example.com.	3600	IN	A	10.0.0.13\n"
83"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
84"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
85"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
86"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
87"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
88"obscured.sub2.example.com.	3600	IN	A	10.0.0.10\n"
89"under.sub2.example.com.	3600	IN	NS	ns.under.sub2.example.com.\n"
90"doubleobscured.under.sub2.example.com.	3600	IN	A	10.0.0.11\n"
91"*.wild.example.com.	3600	IN	A	10.0.0.8\n"
92"*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
93"*.wild3.example.com.	3600	IN	A	10.0.0.8\n"
94"*.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
95"www.example.com.	3600	IN	A	10.0.0.2\n"
96"www.example.com.	3600	IN	A	10.0.0.3\n"
97"yy.example.com.	3600	IN	TXT	\"a\"\n"
98"yy.example.com.	3600	IN	TXT	\"b\"\n"
99"yy.example.com.	3600	IN	TXT	\"c\"\n"
100"yy.example.com.	3600	IN	TXT	\"d\"\n"
101"yy.example.com.	3600	IN	TXT	\"e\"\n"
102"yy.example.com.	3600	IN	TXT	\"f\"\n"
103
104/* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */
105/* normal: domain and 1 rrsig */
106"z1.example.com.	3600	IN	A	10.0.0.10\n"
107"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"
108/* normal: domain and 2 rrsigs */
109"z2.example.com.	3600	IN	A	10.0.0.10\n"
110"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"
111"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"
112/* normal: domain and 3 rrsigs */
113"z3.example.com.	3600	IN	A	10.0.0.10\n"
114"z3.example.com.	3600	IN	A	10.0.0.11\n"
115"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"
116"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"
117"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"
118/* just an RRSIG rrset with nothing else */
119"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"
120/* just an RRSIG rrset with nothing else, 2 rrsigs */
121"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"
122"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"
123#if 1 /* comparison of file does not work on this part because duplicates */
124      /* are removed and the rrsets are reordered */
125"end_of_check.z6.example.com. 3600 IN 	A	10.0.0.10\n"
126/* first rrsig, then A record */
127"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"
128"z6.example.com.	3600	IN	A	10.0.0.10\n"
129/* first two rrsigs, then A record */
130"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"
131"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"
132"z7.example.com.	3600	IN	A	10.0.0.10\n"
133/* first two rrsigs, then two A records */
134"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"
135"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"
136"z8.example.com.	3600	IN	A	10.0.0.10\n"
137"z8.example.com.	3600	IN	A	10.0.0.11\n"
138/* duplicate RR, duplicate RRsig */
139"z9.example.com.	3600	IN	A	10.0.0.10\n"
140"z9.example.com.	3600	IN	A	10.0.0.11\n"
141"z9.example.com.	3600	IN	A	10.0.0.10\n"
142"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"
143"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"
144/* different covered types, first RRSIGs then, RRs, then another RRSIG */
145"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"
146"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"
147"zz10.example.com.	3600	IN	A	10.0.0.10\n"
148"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"
149"zz10.example.com.	3600	IN	AAAA	::11\n"
150#endif /* if0 for duplicates and reordering */
151;
152
153/** queries for example.com: zone, query, flags, answer. end with NULL */
154static struct q_ans example_com_queries[] = {
155	{ "example.com", "www.example.com. A", "",
156";flags QR AA rcode NOERROR\n"
157";answer section\n"
158"www.example.com.	3600	IN	A	10.0.0.2\n"
159"www.example.com.	3600	IN	A	10.0.0.3\n"
160	},
161
162	{ "example.com", "example.com. SOA", "",
163";flags QR AA rcode NOERROR\n"
164";answer section\n"
165"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
166	},
167
168	{ "example.com", "example.com. A", "",
169";flags QR AA rcode NOERROR\n"
170";answer section\n"
171"example.com.	3600	IN	A	10.0.0.1\n"
172	},
173
174	{ "example.com", "example.com. AAAA", "",
175";flags QR AA rcode NOERROR\n"
176";authority section\n"
177"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
178	},
179
180	{ "example.com", "example.com. NS", "",
181";flags QR AA rcode NOERROR\n"
182";answer section\n"
183"example.com.	3600	IN	NS	ns.example.com.\n"
184";additional section\n"
185"ns.example.com.	3600	IN	A	10.0.0.5\n"
186	},
187
188	{ "example.com", "example.com. MX", "",
189";flags QR AA rcode NOERROR\n"
190";answer section\n"
191"example.com.	3600	IN	MX	50 mail.example.com.\n"
192";additional section\n"
193"mail.example.com.	3600	IN	A	10.0.0.4\n"
194	},
195
196	{ "example.com", "example.com. IN ANY", "",
197";flags QR AA rcode NOERROR\n"
198";answer section\n"
199"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
200"example.com.	3600	IN	MX	50 mail.example.com.\n"
201"example.com.	3600	IN	A	10.0.0.1\n"
202	},
203
204	{ "example.com", "nonexist.example.com. A", "",
205";flags QR AA rcode NXDOMAIN\n"
206";authority section\n"
207"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
208	},
209
210	{ "example.com", "deep.ent.example.com. A", "",
211";flags QR AA rcode NOERROR\n"
212";answer section\n"
213"deep.ent.example.com.	3600	IN	A	10.0.0.9\n"
214	},
215
216	{ "example.com", "ent.example.com. A", "",
217";flags QR AA rcode NOERROR\n"
218";authority section\n"
219"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
220	},
221
222	{ "example.com", "below.deep.ent.example.com. A", "",
223";flags QR AA rcode NXDOMAIN\n"
224";authority section\n"
225"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
226	},
227
228	{ "example.com", "mail.example.com. A", "",
229";flags QR AA rcode NOERROR\n"
230";answer section\n"
231"mail.example.com.	3600	IN	A	10.0.0.4\n"
232	},
233
234	{ "example.com", "ns.example.com. A", "",
235";flags QR AA rcode NOERROR\n"
236";answer section\n"
237"ns.example.com.	3600	IN	A	10.0.0.5\n"
238	},
239
240	{ "example.com", "out.example.com. A", "",
241";flags QR AA rcode NOERROR\n"
242";answer section\n"
243"out.example.com.	3600	IN	CNAME	www.example.com.\n"
244"www.example.com.	3600	IN	A	10.0.0.2\n"
245"www.example.com.	3600	IN	A	10.0.0.3\n"
246	},
247
248	{ "example.com", "out.example.com. CNAME", "",
249";flags QR AA rcode NOERROR\n"
250";answer section\n"
251"out.example.com.	3600	IN	CNAME	www.example.com.\n"
252	},
253
254	{ "example.com", "plan.example.com. A", "",
255";flags QR AA rcode NOERROR\n"
256";answer section\n"
257"plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
258	},
259
260	{ "example.com", "plan.example.com. CNAME", "",
261";flags QR AA rcode NOERROR\n"
262";answer section\n"
263"plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
264	},
265
266	{ "example.com", "redir.example.com. A", "",
267";flags QR AA rcode NOERROR\n"
268";authority section\n"
269"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
270	},
271
272	{ "example.com", "redir.example.com. DNAME", "",
273";flags QR AA rcode NOERROR\n"
274";answer section\n"
275"redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
276	},
277
278	{ "example.com", "abc.redir.example.com. A", "",
279";flags QR AA rcode NOERROR\n"
280";answer section\n"
281"redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
282"abc.redir.example.com.	3600	IN	CNAME	abc.redir.example.org.\n"
283	},
284
285	{ "example.com", "foo.abc.redir.example.com. A", "",
286";flags QR AA rcode NOERROR\n"
287";answer section\n"
288"redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
289"foo.abc.redir.example.com.	3600	IN	CNAME	foo.abc.redir.example.org.\n"
290	},
291
292	{ "example.com", "redir2.example.com. DNAME", "",
293";flags QR AA rcode NOERROR\n"
294";answer section\n"
295"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
296	},
297
298	{ "example.com", "abc.redir2.example.com. A", "",
299";flags QR AA rcode NOERROR\n"
300";answer section\n"
301"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
302"abc.redir2.example.com.	3600	IN	CNAME	abc.redir2.example.org.\n"
303	},
304
305	{ "example.com", "obscured.redir2.example.com. A", "",
306";flags QR AA rcode NOERROR\n"
307";answer section\n"
308"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
309"obscured.redir2.example.com.	3600	IN	CNAME	obscured.redir2.example.org.\n"
310	},
311
312	{ "example.com", "under2.redir2.example.com. A", "",
313";flags QR AA rcode NOERROR\n"
314";answer section\n"
315"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
316"under2.redir2.example.com.	3600	IN	CNAME	under2.redir2.example.org.\n"
317	},
318
319	{ "example.com", "doubleobscured.under2.redir2.example.com. A", "",
320";flags QR AA rcode NOERROR\n"
321";answer section\n"
322"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
323"doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	doubleobscured.under2.redir2.example.org.\n"
324	},
325
326	{ "example.com", "foo.doubleobscured.under2.redir2.example.com. A", "",
327";flags QR AA rcode NOERROR\n"
328";answer section\n"
329"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
330"foo.doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	foo.doubleobscured.under2.redir2.example.org.\n"
331	},
332
333	{ "example.com", "foo.under2.redir2.example.com. A", "",
334";flags QR AA rcode NOERROR\n"
335";answer section\n"
336"redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
337"foo.under2.redir2.example.com.	3600	IN	CNAME	foo.under2.redir2.example.org.\n"
338	},
339
340	{ "example.com", "sub.example.com. NS", "",
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"
348	},
349
350	{ "example.com", "sub.example.com. DS", "",
351";flags QR AA rcode NOERROR\n"
352";authority section\n"
353"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
354	},
355
356	{ "example.com", "www.sub.example.com. NS", "",
357";flags QR rcode NOERROR\n"
358";authority section\n"
359"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
360"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
361";additional section\n"
362"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
363"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
364	},
365
366	{ "example.com", "foo.abc.sub.example.com. NS", "",
367";flags QR rcode NOERROR\n"
368";authority section\n"
369"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
370"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
371";additional section\n"
372"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
373"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
374	},
375
376	{ "example.com", "ns1.sub.example.com. A", "",
377";flags QR rcode NOERROR\n"
378";authority section\n"
379"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
380"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
381";additional section\n"
382"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
383"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
384	},
385
386	{ "example.com", "ns1.sub.example.com. AAAA", "",
387";flags QR rcode NOERROR\n"
388";authority section\n"
389"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
390"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
391";additional section\n"
392"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
393"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
394	},
395
396	{ "example.com", "ns2.sub.example.com. A", "",
397";flags QR rcode NOERROR\n"
398";authority section\n"
399"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
400"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
401";additional section\n"
402"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
403"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
404	},
405
406	{ "example.com", "ns2.sub.example.com. AAAA", "",
407";flags QR rcode NOERROR\n"
408";authority section\n"
409"sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
410"sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
411";additional section\n"
412"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
413"ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
414	},
415
416	{ "example.com", "sub2.example.com. A", "",
417";flags QR rcode NOERROR\n"
418";authority section\n"
419"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
420";additional section\n"
421"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
422	},
423
424	{ "example.com", "sub2.example.com. NS", "",
425";flags QR rcode NOERROR\n"
426";authority section\n"
427"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
428";additional section\n"
429"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
430	},
431
432	{ "example.com", "obscured.sub2.example.com. A", "",
433";flags QR rcode NOERROR\n"
434";authority section\n"
435"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
436";additional section\n"
437"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
438	},
439
440	{ "example.com", "abc.obscured.sub2.example.com. A", "",
441";flags QR rcode NOERROR\n"
442";authority section\n"
443"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
444";additional section\n"
445"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
446	},
447
448	{ "example.com", "under.sub2.example.com. A", "",
449";flags QR rcode NOERROR\n"
450";authority section\n"
451"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
452";additional section\n"
453"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
454	},
455
456	{ "example.com", "under.sub2.example.com. NS", "",
457";flags QR rcode NOERROR\n"
458";authority section\n"
459"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
460";additional section\n"
461"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
462	},
463
464	{ "example.com", "abc.under.sub2.example.com. A", "",
465";flags QR rcode NOERROR\n"
466";authority section\n"
467"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
468";additional section\n"
469"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
470	},
471
472	{ "example.com", "doubleobscured.under.sub2.example.com. A", "",
473";flags QR rcode NOERROR\n"
474";authority section\n"
475"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
476";additional section\n"
477"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
478	},
479
480	{ "example.com", "abc.doubleobscured.under.sub2.example.com. A", "",
481";flags QR rcode NOERROR\n"
482";authority section\n"
483"sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
484";additional section\n"
485"ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
486	},
487
488	{ "example.com", "wild.example.com. A", "",
489";flags QR AA rcode NOERROR\n"
490";authority section\n"
491"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
492	},
493
494	{ "example.com", "*.wild.example.com. A", "",
495";flags QR AA rcode NOERROR\n"
496";answer section\n"
497"*.wild.example.com.	3600	IN	A	10.0.0.8\n"
498	},
499
500	{ "example.com", "*.wild.example.com. AAAA", "",
501";flags QR AA rcode NOERROR\n"
502";authority section\n"
503"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
504	},
505
506	{ "example.com", "abc.wild.example.com. A", "",
507";flags QR AA rcode NOERROR\n"
508";answer section\n"
509"abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
510	},
511
512	{ "example.com", "abc.wild.example.com. AAAA", "",
513";flags QR AA rcode NOERROR\n"
514";authority section\n"
515"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
516	},
517
518	{ "example.com", "foo.abc.wild.example.com. A", "",
519";flags QR AA rcode NOERROR\n"
520";answer section\n"
521"foo.abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
522	},
523
524	{ "example.com", "foo.abc.wild.example.com. AAAA", "",
525";flags QR AA rcode NOERROR\n"
526";authority section\n"
527"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
528	},
529
530	{ "example.com", "wild2.example.com. A", "",
531";flags QR AA rcode NOERROR\n"
532";authority section\n"
533"example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
534	},
535
536	{ "example.com", "*.wild2.example.com. A", "",
537";flags QR AA rcode NOERROR\n"
538";answer section\n"
539"*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
540"www.example.com.	3600	IN	A	10.0.0.2\n"
541"www.example.com.	3600	IN	A	10.0.0.3\n"
542	},
543
544	{ "example.com", "abc.wild2.example.com. A", "",
545";flags QR AA rcode NOERROR\n"
546";answer section\n"
547"abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
548"www.example.com.	3600	IN	A	10.0.0.2\n"
549"www.example.com.	3600	IN	A	10.0.0.3\n"
550	},
551
552	{ "example.com", "foo.abc.wild2.example.com. A", "",
553";flags QR AA rcode NOERROR\n"
554";answer section\n"
555"foo.abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
556"www.example.com.	3600	IN	A	10.0.0.2\n"
557"www.example.com.	3600	IN	A	10.0.0.3\n"
558	},
559
560	{ "example.com", "abc.wild2.example.com. CNAME", "",
561";flags QR AA rcode NOERROR\n"
562";answer section\n"
563"abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
564	},
565
566	{ "example.com", "abc.wild3.example.com. IN ANY", "",
567";flags QR AA rcode NOERROR\n"
568";answer section\n"
569"abc.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
570"abc.wild3.example.com.	3600	IN	A	10.0.0.8\n"
571	},
572
573	{ "example.com", "yy.example.com. TXT", "",
574";flags QR AA rcode NOERROR\n"
575";answer section\n"
576"yy.example.com.	3600	IN	TXT	\"a\"\n"
577"yy.example.com.	3600	IN	TXT	\"b\"\n"
578"yy.example.com.	3600	IN	TXT	\"c\"\n"
579"yy.example.com.	3600	IN	TXT	\"d\"\n"
580"yy.example.com.	3600	IN	TXT	\"e\"\n"
581"yy.example.com.	3600	IN	TXT	\"f\"\n"
582	},
583
584	{NULL, NULL, NULL, NULL}
585};
586
587/** number of tmpfiles */
588static int tempno = 0;
589/** number of deleted files */
590static int delno = 0;
591
592/** cleanup tmp files at exit */
593static void
594tmpfilecleanup(void)
595{
596	int i;
597	char buf[256];
598	for(i=0; i<tempno; i++) {
599#ifdef USE_WINSOCK
600		snprintf(buf, sizeof(buf), "unbound.unittest.%u.%d",
601			(unsigned)getpid(), i);
602#else
603		snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
604			(unsigned)getpid(), i);
605#endif
606		if(vbmp) printf("cleanup: unlink %s\n", buf);
607		unlink(buf);
608	}
609}
610
611/** create temp file, return (malloced) name string, write contents to it */
612static char*
613create_tmp_file(const char* s)
614{
615	char buf[256];
616	char *fname;
617	FILE *out;
618	size_t r;
619#ifdef USE_WINSOCK
620	snprintf(buf, sizeof(buf), "unbound.unittest.%u.%d",
621		(unsigned)getpid(), tempno++);
622#else
623	snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
624		(unsigned)getpid(), tempno++);
625#endif
626	fname = strdup(buf);
627	if(!fname) fatal_exit("out of memory");
628	/* if no string, just make the name */
629	if(!s) return fname;
630	/* if string, write to file */
631	out = fopen(fname, "w");
632	if(!out) fatal_exit("cannot open %s: %s", fname, strerror(errno));
633	r = fwrite(s, 1, strlen(s), out);
634	if(r == 0) {
635		fatal_exit("write failed: %s", strerror(errno));
636	} else if(r < strlen(s)) {
637		fatal_exit("write failed: too short (disk full?)");
638	}
639	fclose(out);
640	return fname;
641}
642
643/** delete temp file and free name string */
644static void
645del_tmp_file(char* fname)
646{
647	unlink(fname);
648	free(fname);
649	delno++;
650	if(delno == tempno) {
651		/* deleted all outstanding files, back to start condition */
652		tempno = 0;
653		delno = 0;
654	}
655}
656
657/** Add zone from file for testing */
658struct auth_zone*
659authtest_addzone(struct auth_zones* az, const char* name, char* fname)
660{
661	struct auth_zone* z;
662	size_t nmlen;
663	uint8_t* nm = sldns_str2wire_dname(name, &nmlen);
664	struct config_file* cfg;
665	if(!nm) fatal_exit("out of memory");
666	lock_rw_wrlock(&az->lock);
667	z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN);
668	lock_rw_unlock(&az->lock);
669	if(!z) fatal_exit("cannot find zone");
670	auth_zone_set_zonefile(z, fname);
671	z->for_upstream = 1;
672	cfg = config_create();
673	free(cfg->chrootdir);
674	cfg->chrootdir = NULL;
675
676	if(!auth_zone_read_zonefile(z, cfg)) {
677		fatal_exit("parse failure for auth zone %s", name);
678	}
679	lock_rw_unlock(&z->lock);
680	free(nm);
681	config_delete(cfg);
682	return z;
683}
684
685/** check that file is the same as other file */
686static void
687checkfile(char* f1, char *f2)
688{
689	char buf1[10240], buf2[10240];
690	int line = 0;
691	FILE* i1, *i2;
692	i1 = fopen(f1, "r");
693	if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno));
694	i2 = fopen(f2, "r");
695	if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno));
696
697	while(!feof(i1) && !feof(i2)) {
698		char* cp1, *cp2;
699		line++;
700		cp1 = fgets(buf1, (int)sizeof(buf1), i1);
701		cp2 = fgets(buf2, (int)sizeof(buf2), i2);
702		if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2)))
703			fatal_exit("fgets failed: %s", strerror(errno));
704		if(strncmp(buf1, "end_of_check", 12) == 0) {
705			fclose(i1);
706			fclose(i2);
707			return;
708		}
709		if(strcmp(buf1, buf2) != 0) {
710			log_info("in files %s and %s:%d", f1, f2, line);
711			log_info("'%s'", buf1);
712			log_info("'%s'", buf2);
713			fatal_exit("files are not equal");
714		}
715	}
716	unit_assert(feof(i1) && feof(i2));
717
718	fclose(i1);
719	fclose(i2);
720}
721
722/** check that a zone (in string) can be read and reproduced */
723static void
724check_read_exact(const char* name, const char* zone)
725{
726	struct auth_zones* az;
727	struct auth_zone* z;
728	char* fname, *outf;
729	if(vbmp) printf("check read zone %s\n", name);
730	fname = create_tmp_file(zone);
731
732	az = auth_zones_create();
733	unit_assert(az);
734	z = authtest_addzone(az, name, fname);
735	unit_assert(z);
736	outf = create_tmp_file(NULL);
737	if(!auth_zone_write_file(z, outf)) {
738		fatal_exit("write file failed for %s", fname);
739	}
740	checkfile(fname, outf);
741
742	del_tmp_file(fname);
743	del_tmp_file(outf);
744	auth_zones_delete(az);
745}
746
747/** parse q_ans structure for making query */
748static void
749q_ans_parse(struct q_ans* q, struct regional* region,
750	struct query_info** qinfo, int* fallback, uint8_t** dp_nm,
751	size_t* dp_nmlen)
752{
753	int ret;
754	uint8_t buf[65535];
755	size_t len, dname_len;
756
757	/* parse flags */
758	*fallback = 0; /* default fallback value */
759	if(strstr(q->flags, "fallback"))
760		*fallback = 1;
761
762	/* parse zone */
763	*dp_nmlen = sizeof(buf);
764	if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0)
765		fatal_exit("cannot parse query dp zone %s : %s", q->zone,
766			sldns_get_errorstr_parse(ret));
767	*dp_nm = regional_alloc_init(region, buf, *dp_nmlen);
768	if(!dp_nm) fatal_exit("out of memory");
769
770	/* parse query */
771	len = sizeof(buf);
772	dname_len = 0;
773	if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len,
774		*dp_nm, *dp_nmlen, NULL, 0))!=0)
775		fatal_exit("cannot parse query %s : %s", q->query,
776			sldns_get_errorstr_parse(ret));
777	*qinfo = (struct query_info*)regional_alloc_zero(region,
778		sizeof(**qinfo));
779	if(!*qinfo) fatal_exit("out of memory");
780	(*qinfo)->qname = regional_alloc_init(region, buf, dname_len);
781	if(!(*qinfo)->qname) fatal_exit("out of memory");
782	(*qinfo)->qname_len = dname_len;
783	(*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len);
784	(*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len);
785}
786
787/** print flags to string */
788static void
789pr_flags(sldns_buffer* buf, uint16_t flags)
790{
791	char rcode[32];
792	sldns_buffer_printf(buf, ";flags");
793	if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR");
794	if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA");
795	if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC");
796	if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD");
797	if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD");
798	if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA");
799	if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD");
800	if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z");
801	sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)),
802		rcode, sizeof(rcode));
803	sldns_buffer_printf(buf, " rcode %s", rcode);
804	sldns_buffer_printf(buf, "\n");
805}
806
807/** print RRs to string */
808static void
809pr_rrs(sldns_buffer* buf, struct reply_info* rep)
810{
811	char s[65536];
812	size_t i, j;
813	struct packed_rrset_data* d;
814	log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets
815		+ rep->ar_numrrsets);
816	for(i=0; i<rep->rrset_count; i++) {
817		/* section heading */
818		if(i == 0 && rep->an_numrrsets != 0)
819			sldns_buffer_printf(buf, ";answer section\n");
820		else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0)
821			sldns_buffer_printf(buf, ";authority section\n");
822		else if(i == rep->an_numrrsets+rep->ns_numrrsets &&
823			rep->ar_numrrsets != 0)
824			sldns_buffer_printf(buf, ";additional section\n");
825		/* spool RRset */
826		d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
827		for(j=0; j<d->count+d->rrsig_count; j++) {
828			if(!packed_rr_to_string(rep->rrsets[i], j, 0,
829				s, sizeof(s))) {
830				fatal_exit("could not rr_to_string %d",
831					(int)i);
832			}
833			sldns_buffer_printf(buf, "%s", s);
834		}
835	}
836}
837
838/** create string for message */
839static char*
840msgtostr(struct dns_msg* msg)
841{
842	char* str;
843	sldns_buffer* buf = sldns_buffer_new(65535);
844	if(!buf) fatal_exit("out of memory");
845	if(!msg) {
846		sldns_buffer_printf(buf, "null packet\n");
847	} else {
848		pr_flags(buf, msg->rep->flags);
849		pr_rrs(buf, msg->rep);
850	}
851
852	str = strdup((char*)sldns_buffer_begin(buf));
853	if(!str) fatal_exit("out of memory");
854	sldns_buffer_free(buf);
855	return str;
856}
857
858/** find line diff between strings */
859static void
860line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc)
861{
862	char* pdup, *qdup, *pl, *ql;
863	int line = 1;
864	pdup = strdup(p);
865	qdup = strdup(q);
866	if(!pdup || !qdup) fatal_exit("out of memory");
867	pl=pdup;
868	ql=qdup;
869	printf("linediff (<%s, >%s)\n", pdesc, qdesc);
870	while(pl && ql && *pl && *ql) {
871		char* ep = strchr(pl, '\n');
872		char* eq = strchr(ql, '\n');
873		/* terminate lines */
874		if(ep) *ep = 0;
875		if(eq) *eq = 0;
876		/* printout */
877		if(strcmp(pl, ql) == 0) {
878			printf("%3d   %s\n", line, pl);
879		} else {
880			printf("%3d < %s\n", line, pl);
881			printf("%3d > %s\n", line, ql);
882		}
883		if(ep) *ep = '\n';
884		if(eq) *eq = '\n';
885		if(ep) pl = ep+1;
886		else pl = NULL;
887		if(eq) ql = eq+1;
888		else ql = NULL;
889		line++;
890	}
891	if(pl && *pl) {
892		printf("%3d < %s\n", line, pl);
893	}
894	if(ql && *ql) {
895		printf("%3d > %s\n", line, ql);
896	}
897	free(pdup);
898	free(qdup);
899}
900
901/** make q_ans query */
902static void
903q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo,
904	struct regional* region, int expected_fallback, uint8_t* dp_nm,
905	size_t dp_nmlen)
906{
907	int ret, fallback = 0;
908	struct dns_msg* msg = NULL;
909	char* ans_str;
910	int oldv = verbosity;
911	/* increase verbosity to printout logic in authzone */
912	if(vbmp) verbosity = 4;
913	ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm,
914		dp_nmlen);
915	if(vbmp) verbosity = oldv;
916
917	/* check the answer */
918	ans_str = msgtostr(msg);
919	/* printout if vbmp */
920	if(vbmp) printf("got (ret=%s%s):\n%s",
921		(ret?"ok":"fail"), (fallback?" fallback":""), ans_str);
922	/* check expected value for ret */
923	if(expected_fallback && ret != 0) {
924		/* ret is zero on fallback */
925		if(vbmp) printf("fallback expected, but "
926			"return value is not false\n");
927		unit_assert(expected_fallback && ret == 0);
928	}
929	if(ret == 0) {
930		if(!expected_fallback) {
931			if(vbmp) printf("return value is false, "
932				"(unexpected)\n");
933		}
934		unit_assert(expected_fallback);
935	}
936	/* check expected value for fallback */
937	if(expected_fallback && !fallback) {
938		if(vbmp) printf("expected fallback, but fallback is no\n");
939	} else if(!expected_fallback && fallback) {
940		if(vbmp) printf("expected no fallback, but fallback is yes\n");
941	}
942	unit_assert( (expected_fallback&&fallback) ||
943		(!expected_fallback&&!fallback));
944	/* check answer string */
945	if(strcmp(q->answer, ans_str) != 0) {
946		if(vbmp) printf("wanted:\n%s", q->answer);
947		line_diff(q->answer, ans_str, "wanted", "got");
948	}
949	unit_assert(strcmp(q->answer, ans_str) == 0);
950	if(vbmp) printf("query ok\n\n");
951	free(ans_str);
952}
953
954/** check queries on a loaded zone */
955static void
956check_az_q_ans(struct auth_zones* az, struct q_ans* queries)
957{
958	struct q_ans* q;
959	struct regional* region = regional_create();
960	struct query_info* qinfo;
961	int fallback;
962	uint8_t* dp_nm;
963	size_t dp_nmlen;
964	for(q=queries; q->zone; q++) {
965		if(vbmp) printf("query %s: %s %s\n", q->zone, q->query,
966			q->flags);
967		q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen);
968		q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen);
969		regional_free_all(region);
970	}
971	regional_destroy(region);
972}
973
974/** check queries for a zone are returned as specified */
975static void
976check_queries(const char* name, const char* zone, struct q_ans* queries)
977{
978	struct auth_zones* az;
979	struct auth_zone* z;
980	char* fname;
981	if(vbmp) printf("check queries %s\n", name);
982	fname = create_tmp_file(zone);
983	az = auth_zones_create();
984	if(!az) fatal_exit("out of memory");
985	z = authtest_addzone(az, name, fname);
986	if(!z) fatal_exit("could not read zone for queries test");
987	del_tmp_file(fname);
988
989	/* run queries and test them */
990	check_az_q_ans(az, queries);
991
992	auth_zones_delete(az);
993}
994
995/** Test authzone compare_serial */
996static void
997authzone_compare_serial(void)
998{
999	if(vbmp) printf("Testing compare_serial\n");
1000	unit_assert(compare_serial(0, 1) < 0);
1001	unit_assert(compare_serial(1, 0) > 0);
1002	unit_assert(compare_serial(0, 0) == 0);
1003	unit_assert(compare_serial(1, 1) == 0);
1004	unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
1005	unit_assert(compare_serial(0, 0xf0000000) > 0);
1006	unit_assert(compare_serial(0xf0000000, 0) < 0);
1007	unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
1008	unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
1009	unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
1010	unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
1011}
1012
1013/** Test authzone read from file */
1014static void
1015authzone_read_test(void)
1016{
1017	if(vbmp) printf("Testing read auth zone\n");
1018	check_read_exact("example.com", zone_example_com);
1019}
1020
1021/** Test authzone query from zone */
1022static void
1023authzone_query_test(void)
1024{
1025	if(vbmp) printf("Testing query auth zone\n");
1026	check_queries("example.com", zone_example_com, example_com_queries);
1027}
1028
1029/** test authzone code */
1030void
1031authzone_test(void)
1032{
1033	unit_show_feature("authzone");
1034	atexit(tmpfilecleanup);
1035	authzone_compare_serial();
1036	authzone_read_test();
1037	authzone_query_test();
1038}
1039