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