]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/unitauth.c
unbound: Vendor import 1.19.0
[FreeBSD/FreeBSD.git] / testcode / unitauth.c
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 "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 */
154 static 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. 0       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.     0       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.        0       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.   0       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.     0       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.      0       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.  0       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. 0       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 */
588 static int tempno = 0;
589 /** number of deleted files */
590 static int delno = 0;
591
592 /** cleanup tmp files at exit */
593 static void
594 tmpfilecleanup(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 */
612 static char*
613 create_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 */
644 static void
645 del_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 */
658 struct auth_zone*
659 authtest_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 */
686 static void
687 checkfile(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 */
723 static void
724 check_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 */
748 static void
749 q_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 */
788 static void
789 pr_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 */
808 static void
809 pr_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 */
839 static char*
840 msgtostr(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 */
859 static void
860 line_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 */
902 static void
903 q_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 */
955 static void
956 check_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 */
975 static void
976 check_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 */
996 static void
997 authzone_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 */
1014 static void
1015 authzone_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 */
1022 static void
1023 authzone_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 */
1030 void 
1031 authzone_test(void)
1032 {
1033         unit_show_feature("authzone");
1034         atexit(tmpfilecleanup);
1035         authzone_compare_serial();
1036         authzone_read_test();
1037         authzone_query_test();
1038 }