xref: /openbsd-src/usr.sbin/unbound/testcode/unitauth.c (revision 3f9cc7b6029925f4d59a34d33aa75058bcb3b2c0)
1712b2f30Ssthen /*
2712b2f30Ssthen  * testcode/unitauth.c - unit test for authzone authoritative zone code.
3712b2f30Ssthen  *
4712b2f30Ssthen  * Copyright (c) 2017, NLnet Labs. All rights reserved.
5712b2f30Ssthen  *
6712b2f30Ssthen  * This software is open source.
7712b2f30Ssthen  *
8712b2f30Ssthen  * Redistribution and use in source and binary forms, with or without
9712b2f30Ssthen  * modification, are permitted provided that the following conditions
10712b2f30Ssthen  * are met:
11712b2f30Ssthen  *
12712b2f30Ssthen  * Redistributions of source code must retain the above copyright notice,
13712b2f30Ssthen  * this list of conditions and the following disclaimer.
14712b2f30Ssthen  *
15712b2f30Ssthen  * Redistributions in binary form must reproduce the above copyright notice,
16712b2f30Ssthen  * this list of conditions and the following disclaimer in the documentation
17712b2f30Ssthen  * and/or other materials provided with the distribution.
18712b2f30Ssthen  *
19712b2f30Ssthen  * Neither the name of the NLNET LABS nor the names of its contributors may
20712b2f30Ssthen  * be used to endorse or promote products derived from this software without
21712b2f30Ssthen  * specific prior written permission.
22712b2f30Ssthen  *
23712b2f30Ssthen  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24712b2f30Ssthen  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25712b2f30Ssthen  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26712b2f30Ssthen  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27712b2f30Ssthen  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28712b2f30Ssthen  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29712b2f30Ssthen  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30712b2f30Ssthen  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31712b2f30Ssthen  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32712b2f30Ssthen  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33712b2f30Ssthen  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34712b2f30Ssthen  *
35712b2f30Ssthen  */
36712b2f30Ssthen /**
37712b2f30Ssthen  * \file
38712b2f30Ssthen  * Unit test for auth zone code.
39712b2f30Ssthen  */
40712b2f30Ssthen #include "config.h"
41712b2f30Ssthen #include "services/authzone.h"
42712b2f30Ssthen #include "testcode/unitmain.h"
43712b2f30Ssthen #include "util/regional.h"
44712b2f30Ssthen #include "util/net_help.h"
45dc90232dSsthen #include "util/config_file.h"
46712b2f30Ssthen #include "util/data/msgreply.h"
47712b2f30Ssthen #include "services/cache/dns.h"
48712b2f30Ssthen #include "sldns/str2wire.h"
49712b2f30Ssthen #include "sldns/wire2str.h"
50712b2f30Ssthen #include "sldns/sbuffer.h"
51712b2f30Ssthen 
52712b2f30Ssthen /** verbosity for this test */
53712b2f30Ssthen static int vbmp = 0;
54712b2f30Ssthen 
55712b2f30Ssthen /** struct for query and answer checks */
56712b2f30Ssthen struct q_ans {
57712b2f30Ssthen 	/** zone to query (delegpt) */
58712b2f30Ssthen 	const char* zone;
59712b2f30Ssthen 	/** query name, class, type */
60712b2f30Ssthen 	const char* query;
61712b2f30Ssthen 	/** additional flags or "" */
62712b2f30Ssthen 	const char* flags;
63712b2f30Ssthen 	/** expected answer to check against, multi-line string */
64712b2f30Ssthen 	const char* answer;
65712b2f30Ssthen };
66712b2f30Ssthen 
67712b2f30Ssthen /** auth zone for test */
68712b2f30Ssthen static const char* zone_example_com =
69712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
70712b2f30Ssthen "example.com.	3600	IN	A	10.0.0.1\n"
71712b2f30Ssthen "example.com.	3600	IN	NS	ns.example.com.\n"
72712b2f30Ssthen "example.com.	3600	IN	MX	50 mail.example.com.\n"
73712b2f30Ssthen "deep.ent.example.com.	3600	IN	A	10.0.0.9\n"
74712b2f30Ssthen "mail.example.com.	3600	IN	A	10.0.0.4\n"
75712b2f30Ssthen "ns.example.com.	3600	IN	A	10.0.0.5\n"
76712b2f30Ssthen "out.example.com.	3600	IN	CNAME	www.example.com.\n"
77712b2f30Ssthen "plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
78712b2f30Ssthen "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
799c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
809c7f0a49Ssthen "obscured.redir2.example.com.	3600	IN	A	10.0.0.12\n"
819c7f0a49Ssthen "under2.redir2.example.com.	3600	IN	DNAME	redir3.example.net.\n"
829c7f0a49Ssthen "doubleobscured.under2.redir2.example.com.	3600	IN	A	10.0.0.13\n"
83712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
84712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
85712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
86712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
879c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
889c7f0a49Ssthen "obscured.sub2.example.com.	3600	IN	A	10.0.0.10\n"
899c7f0a49Ssthen "under.sub2.example.com.	3600	IN	NS	ns.under.sub2.example.com.\n"
909c7f0a49Ssthen "doubleobscured.under.sub2.example.com.	3600	IN	A	10.0.0.11\n"
91712b2f30Ssthen "*.wild.example.com.	3600	IN	A	10.0.0.8\n"
92712b2f30Ssthen "*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
93712b2f30Ssthen "*.wild3.example.com.	3600	IN	A	10.0.0.8\n"
94712b2f30Ssthen "*.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
95712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.2\n"
96712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.3\n"
97712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"a\"\n"
98712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"b\"\n"
99712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"c\"\n"
100712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"d\"\n"
101712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"e\"\n"
102712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"f\"\n"
103712b2f30Ssthen 
104712b2f30Ssthen /* and some tests for RRSIGs (rrsig is www.nlnetlabs.nl copy) */
105712b2f30Ssthen /* normal: domain and 1 rrsig */
106712b2f30Ssthen "z1.example.com.	3600	IN	A	10.0.0.10\n"
107712b2f30Ssthen "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"
108712b2f30Ssthen /* normal: domain and 2 rrsigs */
109712b2f30Ssthen "z2.example.com.	3600	IN	A	10.0.0.10\n"
110712b2f30Ssthen "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"
111712b2f30Ssthen "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"
112712b2f30Ssthen /* normal: domain and 3 rrsigs */
113712b2f30Ssthen "z3.example.com.	3600	IN	A	10.0.0.10\n"
114712b2f30Ssthen "z3.example.com.	3600	IN	A	10.0.0.11\n"
115712b2f30Ssthen "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"
116712b2f30Ssthen "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"
117712b2f30Ssthen "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"
118712b2f30Ssthen /* just an RRSIG rrset with nothing else */
119712b2f30Ssthen "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"
120712b2f30Ssthen /* just an RRSIG rrset with nothing else, 2 rrsigs */
121712b2f30Ssthen "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"
122712b2f30Ssthen "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"
1237bc20e6dSsthen #if 1 /* comparison of file does not work on this part because duplicates */
124712b2f30Ssthen       /* are removed and the rrsets are reordered */
1257bc20e6dSsthen "end_of_check.z6.example.com. 3600 IN 	A	10.0.0.10\n"
126712b2f30Ssthen /* first rrsig, then A record */
127712b2f30Ssthen "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"
128712b2f30Ssthen "z6.example.com.	3600	IN	A	10.0.0.10\n"
129712b2f30Ssthen /* first two rrsigs, then A record */
130712b2f30Ssthen "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"
131712b2f30Ssthen "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"
132712b2f30Ssthen "z7.example.com.	3600	IN	A	10.0.0.10\n"
133712b2f30Ssthen /* first two rrsigs, then two A records */
134712b2f30Ssthen "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"
135712b2f30Ssthen "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"
136712b2f30Ssthen "z8.example.com.	3600	IN	A	10.0.0.10\n"
137712b2f30Ssthen "z8.example.com.	3600	IN	A	10.0.0.11\n"
138712b2f30Ssthen /* duplicate RR, duplicate RRsig */
139712b2f30Ssthen "z9.example.com.	3600	IN	A	10.0.0.10\n"
140712b2f30Ssthen "z9.example.com.	3600	IN	A	10.0.0.11\n"
141712b2f30Ssthen "z9.example.com.	3600	IN	A	10.0.0.10\n"
142712b2f30Ssthen "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"
143712b2f30Ssthen "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"
1447bc20e6dSsthen /* different covered types, first RRSIGs then, RRs, then another RRSIG */
1457bc20e6dSsthen "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"
1467bc20e6dSsthen "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"
1477bc20e6dSsthen "zz10.example.com.	3600	IN	A	10.0.0.10\n"
1487bc20e6dSsthen "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"
1497bc20e6dSsthen "zz10.example.com.	3600	IN	AAAA	::11\n"
150712b2f30Ssthen #endif /* if0 for duplicates and reordering */
151712b2f30Ssthen ;
152712b2f30Ssthen 
153712b2f30Ssthen /** queries for example.com: zone, query, flags, answer. end with NULL */
154712b2f30Ssthen static struct q_ans example_com_queries[] = {
155712b2f30Ssthen 	{ "example.com", "www.example.com. A", "",
156712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
157712b2f30Ssthen ";answer section\n"
158712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.2\n"
159712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.3\n"
160712b2f30Ssthen 	},
161712b2f30Ssthen 
162712b2f30Ssthen 	{ "example.com", "example.com. SOA", "",
163712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
164712b2f30Ssthen ";answer section\n"
165712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
166712b2f30Ssthen 	},
167712b2f30Ssthen 
168712b2f30Ssthen 	{ "example.com", "example.com. A", "",
169712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
170712b2f30Ssthen ";answer section\n"
171712b2f30Ssthen "example.com.	3600	IN	A	10.0.0.1\n"
172712b2f30Ssthen 	},
173712b2f30Ssthen 
174712b2f30Ssthen 	{ "example.com", "example.com. AAAA", "",
175712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
176712b2f30Ssthen ";authority section\n"
177712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
178712b2f30Ssthen 	},
179712b2f30Ssthen 
180712b2f30Ssthen 	{ "example.com", "example.com. NS", "",
181712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
182712b2f30Ssthen ";answer section\n"
183712b2f30Ssthen "example.com.	3600	IN	NS	ns.example.com.\n"
184712b2f30Ssthen ";additional section\n"
185712b2f30Ssthen "ns.example.com.	3600	IN	A	10.0.0.5\n"
186712b2f30Ssthen 	},
187712b2f30Ssthen 
188712b2f30Ssthen 	{ "example.com", "example.com. MX", "",
189712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
190712b2f30Ssthen ";answer section\n"
191712b2f30Ssthen "example.com.	3600	IN	MX	50 mail.example.com.\n"
192712b2f30Ssthen ";additional section\n"
193712b2f30Ssthen "mail.example.com.	3600	IN	A	10.0.0.4\n"
194712b2f30Ssthen 	},
195712b2f30Ssthen 
196712b2f30Ssthen 	{ "example.com", "example.com. IN ANY", "",
197712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
198712b2f30Ssthen ";answer section\n"
199712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
200712b2f30Ssthen "example.com.	3600	IN	MX	50 mail.example.com.\n"
201712b2f30Ssthen "example.com.	3600	IN	A	10.0.0.1\n"
202712b2f30Ssthen 	},
203712b2f30Ssthen 
204712b2f30Ssthen 	{ "example.com", "nonexist.example.com. A", "",
205712b2f30Ssthen ";flags QR AA rcode NXDOMAIN\n"
206712b2f30Ssthen ";authority section\n"
207712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
208712b2f30Ssthen 	},
209712b2f30Ssthen 
210712b2f30Ssthen 	{ "example.com", "deep.ent.example.com. A", "",
211712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
212712b2f30Ssthen ";answer section\n"
213712b2f30Ssthen "deep.ent.example.com.	3600	IN	A	10.0.0.9\n"
214712b2f30Ssthen 	},
215712b2f30Ssthen 
216712b2f30Ssthen 	{ "example.com", "ent.example.com. A", "",
217712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
218712b2f30Ssthen ";authority section\n"
219712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
220712b2f30Ssthen 	},
221712b2f30Ssthen 
222712b2f30Ssthen 	{ "example.com", "below.deep.ent.example.com. A", "",
223712b2f30Ssthen ";flags QR AA rcode NXDOMAIN\n"
224712b2f30Ssthen ";authority section\n"
225712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
226712b2f30Ssthen 	},
227712b2f30Ssthen 
228712b2f30Ssthen 	{ "example.com", "mail.example.com. A", "",
229712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
230712b2f30Ssthen ";answer section\n"
231712b2f30Ssthen "mail.example.com.	3600	IN	A	10.0.0.4\n"
232712b2f30Ssthen 	},
233712b2f30Ssthen 
234712b2f30Ssthen 	{ "example.com", "ns.example.com. A", "",
235712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
236712b2f30Ssthen ";answer section\n"
237712b2f30Ssthen "ns.example.com.	3600	IN	A	10.0.0.5\n"
238712b2f30Ssthen 	},
239712b2f30Ssthen 
240712b2f30Ssthen 	{ "example.com", "out.example.com. A", "",
241712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
242712b2f30Ssthen ";answer section\n"
243712b2f30Ssthen "out.example.com.	3600	IN	CNAME	www.example.com.\n"
244712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.2\n"
245712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.3\n"
246712b2f30Ssthen 	},
247712b2f30Ssthen 
248712b2f30Ssthen 	{ "example.com", "out.example.com. CNAME", "",
249712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
250712b2f30Ssthen ";answer section\n"
251712b2f30Ssthen "out.example.com.	3600	IN	CNAME	www.example.com.\n"
252712b2f30Ssthen 	},
253712b2f30Ssthen 
254712b2f30Ssthen 	{ "example.com", "plan.example.com. A", "",
255712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
256712b2f30Ssthen ";answer section\n"
257712b2f30Ssthen "plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
258712b2f30Ssthen 	},
259712b2f30Ssthen 
260712b2f30Ssthen 	{ "example.com", "plan.example.com. CNAME", "",
261712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
262712b2f30Ssthen ";answer section\n"
263712b2f30Ssthen "plan.example.com.	3600	IN	CNAME	nonexist.example.com.\n"
264712b2f30Ssthen 	},
265712b2f30Ssthen 
266712b2f30Ssthen 	{ "example.com", "redir.example.com. A", "",
267712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
268712b2f30Ssthen ";authority section\n"
269712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
270712b2f30Ssthen 	},
271712b2f30Ssthen 
272712b2f30Ssthen 	{ "example.com", "redir.example.com. DNAME", "",
273712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
274712b2f30Ssthen ";answer section\n"
275712b2f30Ssthen "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
276712b2f30Ssthen 	},
277712b2f30Ssthen 
278712b2f30Ssthen 	{ "example.com", "abc.redir.example.com. A", "",
279712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
280712b2f30Ssthen ";answer section\n"
281712b2f30Ssthen "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
282*3f9cc7b6Ssthen "abc.redir.example.com.	3600	IN	CNAME	abc.redir.example.org.\n"
283712b2f30Ssthen 	},
284712b2f30Ssthen 
285712b2f30Ssthen 	{ "example.com", "foo.abc.redir.example.com. A", "",
286712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
287712b2f30Ssthen ";answer section\n"
288712b2f30Ssthen "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
289*3f9cc7b6Ssthen "foo.abc.redir.example.com.	3600	IN	CNAME	foo.abc.redir.example.org.\n"
290712b2f30Ssthen 	},
291712b2f30Ssthen 
2929c7f0a49Ssthen 	{ "example.com", "redir2.example.com. DNAME", "",
2939c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
2949c7f0a49Ssthen ";answer section\n"
2959c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
2969c7f0a49Ssthen 	},
2979c7f0a49Ssthen 
2989c7f0a49Ssthen 	{ "example.com", "abc.redir2.example.com. A", "",
2999c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
3009c7f0a49Ssthen ";answer section\n"
3019c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
302*3f9cc7b6Ssthen "abc.redir2.example.com.	3600	IN	CNAME	abc.redir2.example.org.\n"
3039c7f0a49Ssthen 	},
3049c7f0a49Ssthen 
3059c7f0a49Ssthen 	{ "example.com", "obscured.redir2.example.com. A", "",
3069c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
3079c7f0a49Ssthen ";answer section\n"
3089c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
309*3f9cc7b6Ssthen "obscured.redir2.example.com.	3600	IN	CNAME	obscured.redir2.example.org.\n"
3109c7f0a49Ssthen 	},
3119c7f0a49Ssthen 
3129c7f0a49Ssthen 	{ "example.com", "under2.redir2.example.com. A", "",
3139c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
3149c7f0a49Ssthen ";answer section\n"
3159c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
316*3f9cc7b6Ssthen "under2.redir2.example.com.	3600	IN	CNAME	under2.redir2.example.org.\n"
3179c7f0a49Ssthen 	},
3189c7f0a49Ssthen 
3199c7f0a49Ssthen 	{ "example.com", "doubleobscured.under2.redir2.example.com. A", "",
3209c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
3219c7f0a49Ssthen ";answer section\n"
3229c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
323*3f9cc7b6Ssthen "doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	doubleobscured.under2.redir2.example.org.\n"
3249c7f0a49Ssthen 	},
3259c7f0a49Ssthen 
3269c7f0a49Ssthen 	{ "example.com", "foo.doubleobscured.under2.redir2.example.com. A", "",
3279c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
3289c7f0a49Ssthen ";answer section\n"
3299c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
330*3f9cc7b6Ssthen "foo.doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	foo.doubleobscured.under2.redir2.example.org.\n"
3319c7f0a49Ssthen 	},
3329c7f0a49Ssthen 
3339c7f0a49Ssthen 	{ "example.com", "foo.under2.redir2.example.com. A", "",
3349c7f0a49Ssthen ";flags QR AA rcode NOERROR\n"
3359c7f0a49Ssthen ";answer section\n"
3369c7f0a49Ssthen "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
337*3f9cc7b6Ssthen "foo.under2.redir2.example.com.	3600	IN	CNAME	foo.under2.redir2.example.org.\n"
3389c7f0a49Ssthen 	},
3399c7f0a49Ssthen 
340712b2f30Ssthen 	{ "example.com", "sub.example.com. NS", "",
341712b2f30Ssthen ";flags QR rcode NOERROR\n"
342712b2f30Ssthen ";authority section\n"
343712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
344712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
345712b2f30Ssthen ";additional section\n"
346712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
347712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
348712b2f30Ssthen 	},
349712b2f30Ssthen 
350712b2f30Ssthen 	{ "example.com", "sub.example.com. DS", "",
351712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
352712b2f30Ssthen ";authority section\n"
353712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
354712b2f30Ssthen 	},
355712b2f30Ssthen 
356712b2f30Ssthen 	{ "example.com", "www.sub.example.com. NS", "",
357712b2f30Ssthen ";flags QR rcode NOERROR\n"
358712b2f30Ssthen ";authority section\n"
359712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
360712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
361712b2f30Ssthen ";additional section\n"
362712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
363712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
364712b2f30Ssthen 	},
365712b2f30Ssthen 
366712b2f30Ssthen 	{ "example.com", "foo.abc.sub.example.com. NS", "",
367712b2f30Ssthen ";flags QR rcode NOERROR\n"
368712b2f30Ssthen ";authority section\n"
369712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
370712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
371712b2f30Ssthen ";additional section\n"
372712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
373712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
374712b2f30Ssthen 	},
375712b2f30Ssthen 
376712b2f30Ssthen 	{ "example.com", "ns1.sub.example.com. A", "",
377712b2f30Ssthen ";flags QR rcode NOERROR\n"
378712b2f30Ssthen ";authority section\n"
379712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
380712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
381712b2f30Ssthen ";additional section\n"
382712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
383712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
384712b2f30Ssthen 	},
385712b2f30Ssthen 
386712b2f30Ssthen 	{ "example.com", "ns1.sub.example.com. AAAA", "",
387712b2f30Ssthen ";flags QR rcode NOERROR\n"
388712b2f30Ssthen ";authority section\n"
389712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
390712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
391712b2f30Ssthen ";additional section\n"
392712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
393712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
394712b2f30Ssthen 	},
395712b2f30Ssthen 
396712b2f30Ssthen 	{ "example.com", "ns2.sub.example.com. A", "",
397712b2f30Ssthen ";flags QR rcode NOERROR\n"
398712b2f30Ssthen ";authority section\n"
399712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
400712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
401712b2f30Ssthen ";additional section\n"
402712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
403712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
404712b2f30Ssthen 	},
405712b2f30Ssthen 
406712b2f30Ssthen 	{ "example.com", "ns2.sub.example.com. AAAA", "",
407712b2f30Ssthen ";flags QR rcode NOERROR\n"
408712b2f30Ssthen ";authority section\n"
409712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
410712b2f30Ssthen "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
411712b2f30Ssthen ";additional section\n"
412712b2f30Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
413712b2f30Ssthen "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
414712b2f30Ssthen 	},
415712b2f30Ssthen 
4169c7f0a49Ssthen 	{ "example.com", "sub2.example.com. A", "",
4179c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4189c7f0a49Ssthen ";authority section\n"
4199c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4209c7f0a49Ssthen ";additional section\n"
4219c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4229c7f0a49Ssthen 	},
4239c7f0a49Ssthen 
4249c7f0a49Ssthen 	{ "example.com", "sub2.example.com. NS", "",
4259c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4269c7f0a49Ssthen ";authority section\n"
4279c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4289c7f0a49Ssthen ";additional section\n"
4299c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4309c7f0a49Ssthen 	},
4319c7f0a49Ssthen 
4329c7f0a49Ssthen 	{ "example.com", "obscured.sub2.example.com. A", "",
4339c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4349c7f0a49Ssthen ";authority section\n"
4359c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4369c7f0a49Ssthen ";additional section\n"
4379c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4389c7f0a49Ssthen 	},
4399c7f0a49Ssthen 
4409c7f0a49Ssthen 	{ "example.com", "abc.obscured.sub2.example.com. A", "",
4419c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4429c7f0a49Ssthen ";authority section\n"
4439c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4449c7f0a49Ssthen ";additional section\n"
4459c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4469c7f0a49Ssthen 	},
4479c7f0a49Ssthen 
4489c7f0a49Ssthen 	{ "example.com", "under.sub2.example.com. A", "",
4499c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4509c7f0a49Ssthen ";authority section\n"
4519c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4529c7f0a49Ssthen ";additional section\n"
4539c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4549c7f0a49Ssthen 	},
4559c7f0a49Ssthen 
4569c7f0a49Ssthen 	{ "example.com", "under.sub2.example.com. NS", "",
4579c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4589c7f0a49Ssthen ";authority section\n"
4599c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4609c7f0a49Ssthen ";additional section\n"
4619c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4629c7f0a49Ssthen 	},
4639c7f0a49Ssthen 
4649c7f0a49Ssthen 	{ "example.com", "abc.under.sub2.example.com. A", "",
4659c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4669c7f0a49Ssthen ";authority section\n"
4679c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4689c7f0a49Ssthen ";additional section\n"
4699c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4709c7f0a49Ssthen 	},
4719c7f0a49Ssthen 
4729c7f0a49Ssthen 	{ "example.com", "doubleobscured.under.sub2.example.com. A", "",
4739c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4749c7f0a49Ssthen ";authority section\n"
4759c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4769c7f0a49Ssthen ";additional section\n"
4779c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4789c7f0a49Ssthen 	},
4799c7f0a49Ssthen 
4809c7f0a49Ssthen 	{ "example.com", "abc.doubleobscured.under.sub2.example.com. A", "",
4819c7f0a49Ssthen ";flags QR rcode NOERROR\n"
4829c7f0a49Ssthen ";authority section\n"
4839c7f0a49Ssthen "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
4849c7f0a49Ssthen ";additional section\n"
4859c7f0a49Ssthen "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
4869c7f0a49Ssthen 	},
4879c7f0a49Ssthen 
488712b2f30Ssthen 	{ "example.com", "wild.example.com. A", "",
489712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
490712b2f30Ssthen ";authority section\n"
491712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
492712b2f30Ssthen 	},
493712b2f30Ssthen 
494712b2f30Ssthen 	{ "example.com", "*.wild.example.com. A", "",
495712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
496712b2f30Ssthen ";answer section\n"
497712b2f30Ssthen "*.wild.example.com.	3600	IN	A	10.0.0.8\n"
498712b2f30Ssthen 	},
499712b2f30Ssthen 
500712b2f30Ssthen 	{ "example.com", "*.wild.example.com. AAAA", "",
501712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
502712b2f30Ssthen ";authority section\n"
503712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
504712b2f30Ssthen 	},
505712b2f30Ssthen 
506712b2f30Ssthen 	{ "example.com", "abc.wild.example.com. A", "",
507712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
508712b2f30Ssthen ";answer section\n"
509712b2f30Ssthen "abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
510712b2f30Ssthen 	},
511712b2f30Ssthen 
512712b2f30Ssthen 	{ "example.com", "abc.wild.example.com. AAAA", "",
513712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
514712b2f30Ssthen ";authority section\n"
515712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
516712b2f30Ssthen 	},
517712b2f30Ssthen 
518712b2f30Ssthen 	{ "example.com", "foo.abc.wild.example.com. A", "",
519712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
520712b2f30Ssthen ";answer section\n"
521712b2f30Ssthen "foo.abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
522712b2f30Ssthen 	},
523712b2f30Ssthen 
524712b2f30Ssthen 	{ "example.com", "foo.abc.wild.example.com. AAAA", "",
525712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
526712b2f30Ssthen ";authority section\n"
527712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
528712b2f30Ssthen 	},
529712b2f30Ssthen 
530712b2f30Ssthen 	{ "example.com", "wild2.example.com. A", "",
531712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
532712b2f30Ssthen ";authority section\n"
533712b2f30Ssthen "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
534712b2f30Ssthen 	},
535712b2f30Ssthen 
536712b2f30Ssthen 	{ "example.com", "*.wild2.example.com. A", "",
537712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
538712b2f30Ssthen ";answer section\n"
539712b2f30Ssthen "*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
540712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.2\n"
541712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.3\n"
542712b2f30Ssthen 	},
543712b2f30Ssthen 
544712b2f30Ssthen 	{ "example.com", "abc.wild2.example.com. A", "",
545712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
546712b2f30Ssthen ";answer section\n"
547712b2f30Ssthen "abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
548712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.2\n"
549712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.3\n"
550712b2f30Ssthen 	},
551712b2f30Ssthen 
552712b2f30Ssthen 	{ "example.com", "foo.abc.wild2.example.com. A", "",
553712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
554712b2f30Ssthen ";answer section\n"
555712b2f30Ssthen "foo.abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
556712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.2\n"
557712b2f30Ssthen "www.example.com.	3600	IN	A	10.0.0.3\n"
558712b2f30Ssthen 	},
559712b2f30Ssthen 
560712b2f30Ssthen 	{ "example.com", "abc.wild2.example.com. CNAME", "",
561712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
562712b2f30Ssthen ";answer section\n"
563712b2f30Ssthen "abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
564712b2f30Ssthen 	},
565712b2f30Ssthen 
566712b2f30Ssthen 	{ "example.com", "abc.wild3.example.com. IN ANY", "",
567712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
568712b2f30Ssthen ";answer section\n"
569712b2f30Ssthen "abc.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
570712b2f30Ssthen "abc.wild3.example.com.	3600	IN	A	10.0.0.8\n"
571712b2f30Ssthen 	},
572712b2f30Ssthen 
573712b2f30Ssthen 	{ "example.com", "yy.example.com. TXT", "",
574712b2f30Ssthen ";flags QR AA rcode NOERROR\n"
575712b2f30Ssthen ";answer section\n"
576712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"a\"\n"
577712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"b\"\n"
578712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"c\"\n"
579712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"d\"\n"
580712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"e\"\n"
581712b2f30Ssthen "yy.example.com.	3600	IN	TXT	\"f\"\n"
582712b2f30Ssthen 	},
583712b2f30Ssthen 
584712b2f30Ssthen 	{NULL, NULL, NULL, NULL}
585712b2f30Ssthen };
586712b2f30Ssthen 
587712b2f30Ssthen /** number of tmpfiles */
588712b2f30Ssthen static int tempno = 0;
589712b2f30Ssthen /** number of deleted files */
590712b2f30Ssthen static int delno = 0;
591712b2f30Ssthen 
592712b2f30Ssthen /** cleanup tmp files at exit */
593712b2f30Ssthen static void
tmpfilecleanup(void)594712b2f30Ssthen tmpfilecleanup(void)
595712b2f30Ssthen {
596712b2f30Ssthen 	int i;
597712b2f30Ssthen 	char buf[256];
598712b2f30Ssthen 	for(i=0; i<tempno; i++) {
599a6cc1574Ssthen #ifdef USE_WINSOCK
600a6cc1574Ssthen 		snprintf(buf, sizeof(buf), "unbound.unittest.%u.%d",
601a6cc1574Ssthen 			(unsigned)getpid(), i);
602a6cc1574Ssthen #else
603712b2f30Ssthen 		snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
604712b2f30Ssthen 			(unsigned)getpid(), i);
605a6cc1574Ssthen #endif
606712b2f30Ssthen 		if(vbmp) printf("cleanup: unlink %s\n", buf);
607712b2f30Ssthen 		unlink(buf);
608712b2f30Ssthen 	}
609712b2f30Ssthen }
610712b2f30Ssthen 
611712b2f30Ssthen /** create temp file, return (malloced) name string, write contents to it */
612712b2f30Ssthen static char*
create_tmp_file(const char * s)613712b2f30Ssthen create_tmp_file(const char* s)
614712b2f30Ssthen {
615712b2f30Ssthen 	char buf[256];
616712b2f30Ssthen 	char *fname;
617712b2f30Ssthen 	FILE *out;
618712b2f30Ssthen 	size_t r;
619a6cc1574Ssthen #ifdef USE_WINSOCK
620a6cc1574Ssthen 	snprintf(buf, sizeof(buf), "unbound.unittest.%u.%d",
621a6cc1574Ssthen 		(unsigned)getpid(), tempno++);
622a6cc1574Ssthen #else
623712b2f30Ssthen 	snprintf(buf, sizeof(buf), "/tmp/unbound.unittest.%u.%d",
624712b2f30Ssthen 		(unsigned)getpid(), tempno++);
625a6cc1574Ssthen #endif
626712b2f30Ssthen 	fname = strdup(buf);
627712b2f30Ssthen 	if(!fname) fatal_exit("out of memory");
628712b2f30Ssthen 	/* if no string, just make the name */
629712b2f30Ssthen 	if(!s) return fname;
630712b2f30Ssthen 	/* if string, write to file */
631712b2f30Ssthen 	out = fopen(fname, "w");
632712b2f30Ssthen 	if(!out) fatal_exit("cannot open %s: %s", fname, strerror(errno));
633712b2f30Ssthen 	r = fwrite(s, 1, strlen(s), out);
634712b2f30Ssthen 	if(r == 0) {
635712b2f30Ssthen 		fatal_exit("write failed: %s", strerror(errno));
636712b2f30Ssthen 	} else if(r < strlen(s)) {
637712b2f30Ssthen 		fatal_exit("write failed: too short (disk full?)");
638712b2f30Ssthen 	}
639712b2f30Ssthen 	fclose(out);
640712b2f30Ssthen 	return fname;
641712b2f30Ssthen }
642712b2f30Ssthen 
643712b2f30Ssthen /** delete temp file and free name string */
644712b2f30Ssthen static void
del_tmp_file(char * fname)645712b2f30Ssthen del_tmp_file(char* fname)
646712b2f30Ssthen {
647712b2f30Ssthen 	unlink(fname);
648712b2f30Ssthen 	free(fname);
649712b2f30Ssthen 	delno++;
650712b2f30Ssthen 	if(delno == tempno) {
651712b2f30Ssthen 		/* deleted all outstanding files, back to start condition */
652712b2f30Ssthen 		tempno = 0;
653712b2f30Ssthen 		delno = 0;
654712b2f30Ssthen 	}
655712b2f30Ssthen }
656712b2f30Ssthen 
657712b2f30Ssthen /** Add zone from file for testing */
658a6cc1574Ssthen struct auth_zone*
authtest_addzone(struct auth_zones * az,const char * name,char * fname)659a6cc1574Ssthen authtest_addzone(struct auth_zones* az, const char* name, char* fname)
660712b2f30Ssthen {
661712b2f30Ssthen 	struct auth_zone* z;
662712b2f30Ssthen 	size_t nmlen;
663712b2f30Ssthen 	uint8_t* nm = sldns_str2wire_dname(name, &nmlen);
664dc90232dSsthen 	struct config_file* cfg;
665712b2f30Ssthen 	if(!nm) fatal_exit("out of memory");
666712b2f30Ssthen 	lock_rw_wrlock(&az->lock);
667712b2f30Ssthen 	z = auth_zone_create(az, nm, nmlen, LDNS_RR_CLASS_IN);
668712b2f30Ssthen 	lock_rw_unlock(&az->lock);
669712b2f30Ssthen 	if(!z) fatal_exit("cannot find zone");
670712b2f30Ssthen 	auth_zone_set_zonefile(z, fname);
671712b2f30Ssthen 	z->for_upstream = 1;
672dc90232dSsthen 	cfg = config_create();
673dc90232dSsthen 	free(cfg->chrootdir);
674dc90232dSsthen 	cfg->chrootdir = NULL;
675712b2f30Ssthen 
676dc90232dSsthen 	if(!auth_zone_read_zonefile(z, cfg)) {
677712b2f30Ssthen 		fatal_exit("parse failure for auth zone %s", name);
678712b2f30Ssthen 	}
679712b2f30Ssthen 	lock_rw_unlock(&z->lock);
680712b2f30Ssthen 	free(nm);
681dc90232dSsthen 	config_delete(cfg);
682712b2f30Ssthen 	return z;
683712b2f30Ssthen }
684712b2f30Ssthen 
685712b2f30Ssthen /** check that file is the same as other file */
686712b2f30Ssthen static void
checkfile(char * f1,char * f2)687712b2f30Ssthen checkfile(char* f1, char *f2)
688712b2f30Ssthen {
689712b2f30Ssthen 	char buf1[10240], buf2[10240];
690712b2f30Ssthen 	int line = 0;
691712b2f30Ssthen 	FILE* i1, *i2;
692712b2f30Ssthen 	i1 = fopen(f1, "r");
693712b2f30Ssthen 	if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno));
694712b2f30Ssthen 	i2 = fopen(f2, "r");
695712b2f30Ssthen 	if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno));
696712b2f30Ssthen 
697712b2f30Ssthen 	while(!feof(i1) && !feof(i2)) {
698712b2f30Ssthen 		char* cp1, *cp2;
699712b2f30Ssthen 		line++;
700712b2f30Ssthen 		cp1 = fgets(buf1, (int)sizeof(buf1), i1);
701712b2f30Ssthen 		cp2 = fgets(buf2, (int)sizeof(buf2), i2);
702712b2f30Ssthen 		if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2)))
703712b2f30Ssthen 			fatal_exit("fgets failed: %s", strerror(errno));
7047bc20e6dSsthen 		if(strncmp(buf1, "end_of_check", 12) == 0) {
7057bc20e6dSsthen 			fclose(i1);
7067bc20e6dSsthen 			fclose(i2);
7077bc20e6dSsthen 			return;
7087bc20e6dSsthen 		}
709712b2f30Ssthen 		if(strcmp(buf1, buf2) != 0) {
710712b2f30Ssthen 			log_info("in files %s and %s:%d", f1, f2, line);
711712b2f30Ssthen 			log_info("'%s'", buf1);
712712b2f30Ssthen 			log_info("'%s'", buf2);
7137bc20e6dSsthen 			fatal_exit("files are not equal");
714712b2f30Ssthen 		}
715712b2f30Ssthen 	}
716712b2f30Ssthen 	unit_assert(feof(i1) && feof(i2));
717712b2f30Ssthen 
718712b2f30Ssthen 	fclose(i1);
719712b2f30Ssthen 	fclose(i2);
720712b2f30Ssthen }
721712b2f30Ssthen 
722712b2f30Ssthen /** check that a zone (in string) can be read and reproduced */
723712b2f30Ssthen static void
check_read_exact(const char * name,const char * zone)724712b2f30Ssthen check_read_exact(const char* name, const char* zone)
725712b2f30Ssthen {
726712b2f30Ssthen 	struct auth_zones* az;
727712b2f30Ssthen 	struct auth_zone* z;
728712b2f30Ssthen 	char* fname, *outf;
729712b2f30Ssthen 	if(vbmp) printf("check read zone %s\n", name);
730712b2f30Ssthen 	fname = create_tmp_file(zone);
731712b2f30Ssthen 
732712b2f30Ssthen 	az = auth_zones_create();
733712b2f30Ssthen 	unit_assert(az);
734a6cc1574Ssthen 	z = authtest_addzone(az, name, fname);
735712b2f30Ssthen 	unit_assert(z);
736712b2f30Ssthen 	outf = create_tmp_file(NULL);
737712b2f30Ssthen 	if(!auth_zone_write_file(z, outf)) {
738712b2f30Ssthen 		fatal_exit("write file failed for %s", fname);
739712b2f30Ssthen 	}
740712b2f30Ssthen 	checkfile(fname, outf);
741712b2f30Ssthen 
742712b2f30Ssthen 	del_tmp_file(fname);
743712b2f30Ssthen 	del_tmp_file(outf);
744712b2f30Ssthen 	auth_zones_delete(az);
745712b2f30Ssthen }
746712b2f30Ssthen 
747712b2f30Ssthen /** parse q_ans structure for making query */
748712b2f30Ssthen static void
q_ans_parse(struct q_ans * q,struct regional * region,struct query_info ** qinfo,int * fallback,uint8_t ** dp_nm,size_t * dp_nmlen)749712b2f30Ssthen q_ans_parse(struct q_ans* q, struct regional* region,
750712b2f30Ssthen 	struct query_info** qinfo, int* fallback, uint8_t** dp_nm,
751712b2f30Ssthen 	size_t* dp_nmlen)
752712b2f30Ssthen {
753712b2f30Ssthen 	int ret;
754712b2f30Ssthen 	uint8_t buf[65535];
755712b2f30Ssthen 	size_t len, dname_len;
756712b2f30Ssthen 
757712b2f30Ssthen 	/* parse flags */
758712b2f30Ssthen 	*fallback = 0; /* default fallback value */
759712b2f30Ssthen 	if(strstr(q->flags, "fallback"))
760712b2f30Ssthen 		*fallback = 1;
761712b2f30Ssthen 
762712b2f30Ssthen 	/* parse zone */
763712b2f30Ssthen 	*dp_nmlen = sizeof(buf);
764712b2f30Ssthen 	if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0)
765712b2f30Ssthen 		fatal_exit("cannot parse query dp zone %s : %s", q->zone,
766712b2f30Ssthen 			sldns_get_errorstr_parse(ret));
767712b2f30Ssthen 	*dp_nm = regional_alloc_init(region, buf, *dp_nmlen);
768712b2f30Ssthen 	if(!dp_nm) fatal_exit("out of memory");
769712b2f30Ssthen 
770712b2f30Ssthen 	/* parse query */
771712b2f30Ssthen 	len = sizeof(buf);
772712b2f30Ssthen 	dname_len = 0;
773712b2f30Ssthen 	if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len,
774712b2f30Ssthen 		*dp_nm, *dp_nmlen, NULL, 0))!=0)
775712b2f30Ssthen 		fatal_exit("cannot parse query %s : %s", q->query,
776712b2f30Ssthen 			sldns_get_errorstr_parse(ret));
777712b2f30Ssthen 	*qinfo = (struct query_info*)regional_alloc_zero(region,
778712b2f30Ssthen 		sizeof(**qinfo));
779712b2f30Ssthen 	if(!*qinfo) fatal_exit("out of memory");
780712b2f30Ssthen 	(*qinfo)->qname = regional_alloc_init(region, buf, dname_len);
781712b2f30Ssthen 	if(!(*qinfo)->qname) fatal_exit("out of memory");
782712b2f30Ssthen 	(*qinfo)->qname_len = dname_len;
783712b2f30Ssthen 	(*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len);
784712b2f30Ssthen 	(*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len);
785712b2f30Ssthen }
786712b2f30Ssthen 
787712b2f30Ssthen /** print flags to string */
788712b2f30Ssthen static void
pr_flags(sldns_buffer * buf,uint16_t flags)789712b2f30Ssthen pr_flags(sldns_buffer* buf, uint16_t flags)
790712b2f30Ssthen {
791712b2f30Ssthen 	char rcode[32];
792712b2f30Ssthen 	sldns_buffer_printf(buf, ";flags");
793712b2f30Ssthen 	if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR");
794712b2f30Ssthen 	if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA");
795712b2f30Ssthen 	if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC");
796712b2f30Ssthen 	if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD");
797712b2f30Ssthen 	if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD");
798712b2f30Ssthen 	if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA");
799712b2f30Ssthen 	if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD");
800712b2f30Ssthen 	if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z");
801712b2f30Ssthen 	sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)),
802712b2f30Ssthen 		rcode, sizeof(rcode));
803712b2f30Ssthen 	sldns_buffer_printf(buf, " rcode %s", rcode);
804712b2f30Ssthen 	sldns_buffer_printf(buf, "\n");
805712b2f30Ssthen }
806712b2f30Ssthen 
807712b2f30Ssthen /** print RRs to string */
808712b2f30Ssthen static void
pr_rrs(sldns_buffer * buf,struct reply_info * rep)809712b2f30Ssthen pr_rrs(sldns_buffer* buf, struct reply_info* rep)
810712b2f30Ssthen {
811712b2f30Ssthen 	char s[65536];
812712b2f30Ssthen 	size_t i, j;
813712b2f30Ssthen 	struct packed_rrset_data* d;
814712b2f30Ssthen 	log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets
815712b2f30Ssthen 		+ rep->ar_numrrsets);
816712b2f30Ssthen 	for(i=0; i<rep->rrset_count; i++) {
817712b2f30Ssthen 		/* section heading */
818712b2f30Ssthen 		if(i == 0 && rep->an_numrrsets != 0)
819712b2f30Ssthen 			sldns_buffer_printf(buf, ";answer section\n");
820712b2f30Ssthen 		else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0)
821712b2f30Ssthen 			sldns_buffer_printf(buf, ";authority section\n");
822712b2f30Ssthen 		else if(i == rep->an_numrrsets+rep->ns_numrrsets &&
823712b2f30Ssthen 			rep->ar_numrrsets != 0)
824712b2f30Ssthen 			sldns_buffer_printf(buf, ";additional section\n");
825712b2f30Ssthen 		/* spool RRset */
826712b2f30Ssthen 		d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
827712b2f30Ssthen 		for(j=0; j<d->count+d->rrsig_count; j++) {
828712b2f30Ssthen 			if(!packed_rr_to_string(rep->rrsets[i], j, 0,
829712b2f30Ssthen 				s, sizeof(s))) {
830712b2f30Ssthen 				fatal_exit("could not rr_to_string %d",
831712b2f30Ssthen 					(int)i);
832712b2f30Ssthen 			}
833712b2f30Ssthen 			sldns_buffer_printf(buf, "%s", s);
834712b2f30Ssthen 		}
835712b2f30Ssthen 	}
836712b2f30Ssthen }
837712b2f30Ssthen 
838712b2f30Ssthen /** create string for message */
839712b2f30Ssthen static char*
msgtostr(struct dns_msg * msg)840712b2f30Ssthen msgtostr(struct dns_msg* msg)
841712b2f30Ssthen {
842712b2f30Ssthen 	char* str;
843712b2f30Ssthen 	sldns_buffer* buf = sldns_buffer_new(65535);
844712b2f30Ssthen 	if(!buf) fatal_exit("out of memory");
845712b2f30Ssthen 	if(!msg) {
846712b2f30Ssthen 		sldns_buffer_printf(buf, "null packet\n");
847712b2f30Ssthen 	} else {
848712b2f30Ssthen 		pr_flags(buf, msg->rep->flags);
849712b2f30Ssthen 		pr_rrs(buf, msg->rep);
850712b2f30Ssthen 	}
851712b2f30Ssthen 
852712b2f30Ssthen 	str = strdup((char*)sldns_buffer_begin(buf));
853712b2f30Ssthen 	if(!str) fatal_exit("out of memory");
854712b2f30Ssthen 	sldns_buffer_free(buf);
855712b2f30Ssthen 	return str;
856712b2f30Ssthen }
857712b2f30Ssthen 
858712b2f30Ssthen /** find line diff between strings */
859712b2f30Ssthen static void
line_diff(const char * p,const char * q,const char * pdesc,const char * qdesc)860712b2f30Ssthen line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc)
861712b2f30Ssthen {
862712b2f30Ssthen 	char* pdup, *qdup, *pl, *ql;
863712b2f30Ssthen 	int line = 1;
864712b2f30Ssthen 	pdup = strdup(p);
865712b2f30Ssthen 	qdup = strdup(q);
866712b2f30Ssthen 	if(!pdup || !qdup) fatal_exit("out of memory");
867712b2f30Ssthen 	pl=pdup;
868712b2f30Ssthen 	ql=qdup;
869712b2f30Ssthen 	printf("linediff (<%s, >%s)\n", pdesc, qdesc);
870712b2f30Ssthen 	while(pl && ql && *pl && *ql) {
871712b2f30Ssthen 		char* ep = strchr(pl, '\n');
872712b2f30Ssthen 		char* eq = strchr(ql, '\n');
873712b2f30Ssthen 		/* terminate lines */
874712b2f30Ssthen 		if(ep) *ep = 0;
875712b2f30Ssthen 		if(eq) *eq = 0;
876712b2f30Ssthen 		/* printout */
877712b2f30Ssthen 		if(strcmp(pl, ql) == 0) {
878712b2f30Ssthen 			printf("%3d   %s\n", line, pl);
879712b2f30Ssthen 		} else {
880712b2f30Ssthen 			printf("%3d < %s\n", line, pl);
881712b2f30Ssthen 			printf("%3d > %s\n", line, ql);
882712b2f30Ssthen 		}
883712b2f30Ssthen 		if(ep) *ep = '\n';
884712b2f30Ssthen 		if(eq) *eq = '\n';
885712b2f30Ssthen 		if(ep) pl = ep+1;
886712b2f30Ssthen 		else pl = NULL;
887712b2f30Ssthen 		if(eq) ql = eq+1;
888712b2f30Ssthen 		else ql = NULL;
889712b2f30Ssthen 		line++;
890712b2f30Ssthen 	}
891712b2f30Ssthen 	if(pl && *pl) {
892712b2f30Ssthen 		printf("%3d < %s\n", line, pl);
893712b2f30Ssthen 	}
894712b2f30Ssthen 	if(ql && *ql) {
895712b2f30Ssthen 		printf("%3d > %s\n", line, ql);
896712b2f30Ssthen 	}
897712b2f30Ssthen 	free(pdup);
898712b2f30Ssthen 	free(qdup);
899712b2f30Ssthen }
900712b2f30Ssthen 
901712b2f30Ssthen /** make q_ans query */
902712b2f30Ssthen static void
q_ans_query(struct q_ans * q,struct auth_zones * az,struct query_info * qinfo,struct regional * region,int expected_fallback,uint8_t * dp_nm,size_t dp_nmlen)903712b2f30Ssthen q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo,
904712b2f30Ssthen 	struct regional* region, int expected_fallback, uint8_t* dp_nm,
905712b2f30Ssthen 	size_t dp_nmlen)
906712b2f30Ssthen {
907712b2f30Ssthen 	int ret, fallback = 0;
908712b2f30Ssthen 	struct dns_msg* msg = NULL;
909712b2f30Ssthen 	char* ans_str;
910712b2f30Ssthen 	int oldv = verbosity;
911712b2f30Ssthen 	/* increase verbosity to printout logic in authzone */
912712b2f30Ssthen 	if(vbmp) verbosity = 4;
913712b2f30Ssthen 	ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm,
914712b2f30Ssthen 		dp_nmlen);
915712b2f30Ssthen 	if(vbmp) verbosity = oldv;
916712b2f30Ssthen 
917712b2f30Ssthen 	/* check the answer */
918712b2f30Ssthen 	ans_str = msgtostr(msg);
919712b2f30Ssthen 	/* printout if vbmp */
920712b2f30Ssthen 	if(vbmp) printf("got (ret=%s%s):\n%s",
921712b2f30Ssthen 		(ret?"ok":"fail"), (fallback?" fallback":""), ans_str);
922712b2f30Ssthen 	/* check expected value for ret */
923712b2f30Ssthen 	if(expected_fallback && ret != 0) {
924712b2f30Ssthen 		/* ret is zero on fallback */
925712b2f30Ssthen 		if(vbmp) printf("fallback expected, but "
926712b2f30Ssthen 			"return value is not false\n");
927712b2f30Ssthen 		unit_assert(expected_fallback && ret == 0);
928712b2f30Ssthen 	}
929712b2f30Ssthen 	if(ret == 0) {
930712b2f30Ssthen 		if(!expected_fallback) {
931712b2f30Ssthen 			if(vbmp) printf("return value is false, "
932712b2f30Ssthen 				"(unexpected)\n");
933712b2f30Ssthen 		}
934712b2f30Ssthen 		unit_assert(expected_fallback);
935712b2f30Ssthen 	}
936712b2f30Ssthen 	/* check expected value for fallback */
937712b2f30Ssthen 	if(expected_fallback && !fallback) {
938712b2f30Ssthen 		if(vbmp) printf("expected fallback, but fallback is no\n");
939712b2f30Ssthen 	} else if(!expected_fallback && fallback) {
940712b2f30Ssthen 		if(vbmp) printf("expected no fallback, but fallback is yes\n");
941712b2f30Ssthen 	}
942712b2f30Ssthen 	unit_assert( (expected_fallback&&fallback) ||
943712b2f30Ssthen 		(!expected_fallback&&!fallback));
944712b2f30Ssthen 	/* check answer string */
945712b2f30Ssthen 	if(strcmp(q->answer, ans_str) != 0) {
946712b2f30Ssthen 		if(vbmp) printf("wanted:\n%s", q->answer);
947712b2f30Ssthen 		line_diff(q->answer, ans_str, "wanted", "got");
948712b2f30Ssthen 	}
949712b2f30Ssthen 	unit_assert(strcmp(q->answer, ans_str) == 0);
950712b2f30Ssthen 	if(vbmp) printf("query ok\n\n");
951712b2f30Ssthen 	free(ans_str);
952712b2f30Ssthen }
953712b2f30Ssthen 
954712b2f30Ssthen /** check queries on a loaded zone */
955712b2f30Ssthen static void
check_az_q_ans(struct auth_zones * az,struct q_ans * queries)956712b2f30Ssthen check_az_q_ans(struct auth_zones* az, struct q_ans* queries)
957712b2f30Ssthen {
958712b2f30Ssthen 	struct q_ans* q;
959712b2f30Ssthen 	struct regional* region = regional_create();
960712b2f30Ssthen 	struct query_info* qinfo;
961712b2f30Ssthen 	int fallback;
962712b2f30Ssthen 	uint8_t* dp_nm;
963712b2f30Ssthen 	size_t dp_nmlen;
964712b2f30Ssthen 	for(q=queries; q->zone; q++) {
965712b2f30Ssthen 		if(vbmp) printf("query %s: %s %s\n", q->zone, q->query,
966712b2f30Ssthen 			q->flags);
967712b2f30Ssthen 		q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen);
968712b2f30Ssthen 		q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen);
969712b2f30Ssthen 		regional_free_all(region);
970712b2f30Ssthen 	}
971712b2f30Ssthen 	regional_destroy(region);
972712b2f30Ssthen }
973712b2f30Ssthen 
974712b2f30Ssthen /** check queries for a zone are returned as specified */
975712b2f30Ssthen static void
check_queries(const char * name,const char * zone,struct q_ans * queries)976712b2f30Ssthen check_queries(const char* name, const char* zone, struct q_ans* queries)
977712b2f30Ssthen {
978712b2f30Ssthen 	struct auth_zones* az;
979712b2f30Ssthen 	struct auth_zone* z;
980712b2f30Ssthen 	char* fname;
981712b2f30Ssthen 	if(vbmp) printf("check queries %s\n", name);
982712b2f30Ssthen 	fname = create_tmp_file(zone);
983712b2f30Ssthen 	az = auth_zones_create();
984712b2f30Ssthen 	if(!az) fatal_exit("out of memory");
985a6cc1574Ssthen 	z = authtest_addzone(az, name, fname);
986712b2f30Ssthen 	if(!z) fatal_exit("could not read zone for queries test");
987712b2f30Ssthen 	del_tmp_file(fname);
988712b2f30Ssthen 
989712b2f30Ssthen 	/* run queries and test them */
990712b2f30Ssthen 	check_az_q_ans(az, queries);
991712b2f30Ssthen 
992712b2f30Ssthen 	auth_zones_delete(az);
993712b2f30Ssthen }
994712b2f30Ssthen 
995712b2f30Ssthen /** Test authzone compare_serial */
996712b2f30Ssthen static void
authzone_compare_serial(void)997712b2f30Ssthen authzone_compare_serial(void)
998712b2f30Ssthen {
999712b2f30Ssthen 	if(vbmp) printf("Testing compare_serial\n");
1000712b2f30Ssthen 	unit_assert(compare_serial(0, 1) < 0);
1001712b2f30Ssthen 	unit_assert(compare_serial(1, 0) > 0);
1002712b2f30Ssthen 	unit_assert(compare_serial(0, 0) == 0);
1003712b2f30Ssthen 	unit_assert(compare_serial(1, 1) == 0);
1004712b2f30Ssthen 	unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
1005712b2f30Ssthen 	unit_assert(compare_serial(0, 0xf0000000) > 0);
1006712b2f30Ssthen 	unit_assert(compare_serial(0xf0000000, 0) < 0);
1007712b2f30Ssthen 	unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
1008712b2f30Ssthen 	unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
1009712b2f30Ssthen 	unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
1010712b2f30Ssthen 	unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
1011712b2f30Ssthen }
1012712b2f30Ssthen 
1013712b2f30Ssthen /** Test authzone read from file */
1014712b2f30Ssthen static void
authzone_read_test(void)1015712b2f30Ssthen authzone_read_test(void)
1016712b2f30Ssthen {
1017712b2f30Ssthen 	if(vbmp) printf("Testing read auth zone\n");
1018712b2f30Ssthen 	check_read_exact("example.com", zone_example_com);
1019712b2f30Ssthen }
1020712b2f30Ssthen 
1021712b2f30Ssthen /** Test authzone query from zone */
1022712b2f30Ssthen static void
authzone_query_test(void)1023712b2f30Ssthen authzone_query_test(void)
1024712b2f30Ssthen {
1025712b2f30Ssthen 	if(vbmp) printf("Testing query auth zone\n");
1026712b2f30Ssthen 	check_queries("example.com", zone_example_com, example_com_queries);
1027712b2f30Ssthen }
1028712b2f30Ssthen 
1029712b2f30Ssthen /** test authzone code */
1030712b2f30Ssthen void
authzone_test(void)1031712b2f30Ssthen authzone_test(void)
1032712b2f30Ssthen {
1033712b2f30Ssthen 	unit_show_feature("authzone");
1034712b2f30Ssthen 	atexit(tmpfilecleanup);
1035712b2f30Ssthen 	authzone_compare_serial();
1036712b2f30Ssthen 	authzone_read_test();
1037712b2f30Ssthen 	authzone_query_test();
1038712b2f30Ssthen }
1039