Home | History | Annotate | Line # | Download | only in testcode
      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.	3600	IN	CNAME	abc.redir.example.org.\n"
    283 	},
    284 
    285 	{ "example.com", "foo.abc.redir.example.com. A", "",
    286 ";flags QR AA rcode NOERROR\n"
    287 ";answer section\n"
    288 "redir.example.com.	3600	IN	DNAME	redir.example.org.\n"
    289 "foo.abc.redir.example.com.	3600	IN	CNAME	foo.abc.redir.example.org.\n"
    290 	},
    291 
    292 	{ "example.com", "redir2.example.com. DNAME", "",
    293 ";flags QR AA rcode NOERROR\n"
    294 ";answer section\n"
    295 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    296 	},
    297 
    298 	{ "example.com", "abc.redir2.example.com. A", "",
    299 ";flags QR AA rcode NOERROR\n"
    300 ";answer section\n"
    301 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    302 "abc.redir2.example.com.	3600	IN	CNAME	abc.redir2.example.org.\n"
    303 	},
    304 
    305 	{ "example.com", "obscured.redir2.example.com. A", "",
    306 ";flags QR AA rcode NOERROR\n"
    307 ";answer section\n"
    308 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    309 "obscured.redir2.example.com.	3600	IN	CNAME	obscured.redir2.example.org.\n"
    310 	},
    311 
    312 	{ "example.com", "under2.redir2.example.com. A", "",
    313 ";flags QR AA rcode NOERROR\n"
    314 ";answer section\n"
    315 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    316 "under2.redir2.example.com.	3600	IN	CNAME	under2.redir2.example.org.\n"
    317 	},
    318 
    319 	{ "example.com", "doubleobscured.under2.redir2.example.com. A", "",
    320 ";flags QR AA rcode NOERROR\n"
    321 ";answer section\n"
    322 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    323 "doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	doubleobscured.under2.redir2.example.org.\n"
    324 	},
    325 
    326 	{ "example.com", "foo.doubleobscured.under2.redir2.example.com. A", "",
    327 ";flags QR AA rcode NOERROR\n"
    328 ";answer section\n"
    329 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    330 "foo.doubleobscured.under2.redir2.example.com.	3600	IN	CNAME	foo.doubleobscured.under2.redir2.example.org.\n"
    331 	},
    332 
    333 	{ "example.com", "foo.under2.redir2.example.com. A", "",
    334 ";flags QR AA rcode NOERROR\n"
    335 ";answer section\n"
    336 "redir2.example.com.	3600	IN	DNAME	redir2.example.org.\n"
    337 "foo.under2.redir2.example.com.	3600	IN	CNAME	foo.under2.redir2.example.org.\n"
    338 	},
    339 
    340 	{ "example.com", "sub.example.com. NS", "",
    341 ";flags QR rcode NOERROR\n"
    342 ";authority section\n"
    343 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    344 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    345 ";additional section\n"
    346 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    347 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    348 	},
    349 
    350 	{ "example.com", "sub.example.com. DS", "",
    351 ";flags QR AA rcode NOERROR\n"
    352 ";authority section\n"
    353 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
    354 	},
    355 
    356 	{ "example.com", "www.sub.example.com. NS", "",
    357 ";flags QR rcode NOERROR\n"
    358 ";authority section\n"
    359 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    360 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    361 ";additional section\n"
    362 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    363 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    364 	},
    365 
    366 	{ "example.com", "foo.abc.sub.example.com. NS", "",
    367 ";flags QR rcode NOERROR\n"
    368 ";authority section\n"
    369 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    370 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    371 ";additional section\n"
    372 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    373 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    374 	},
    375 
    376 	{ "example.com", "ns1.sub.example.com. A", "",
    377 ";flags QR rcode NOERROR\n"
    378 ";authority section\n"
    379 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    380 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    381 ";additional section\n"
    382 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    383 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    384 	},
    385 
    386 	{ "example.com", "ns1.sub.example.com. AAAA", "",
    387 ";flags QR rcode NOERROR\n"
    388 ";authority section\n"
    389 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    390 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    391 ";additional section\n"
    392 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    393 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    394 	},
    395 
    396 	{ "example.com", "ns2.sub.example.com. A", "",
    397 ";flags QR rcode NOERROR\n"
    398 ";authority section\n"
    399 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    400 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    401 ";additional section\n"
    402 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    403 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    404 	},
    405 
    406 	{ "example.com", "ns2.sub.example.com. AAAA", "",
    407 ";flags QR rcode NOERROR\n"
    408 ";authority section\n"
    409 "sub.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    410 "sub.example.com.	3600	IN	NS	ns2.sub.example.com.\n"
    411 ";additional section\n"
    412 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    413 "ns2.sub.example.com.	3600	IN	AAAA	2001::7\n"
    414 	},
    415 
    416 	{ "example.com", "sub2.example.com. A", "",
    417 ";flags QR rcode NOERROR\n"
    418 ";authority section\n"
    419 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    420 ";additional section\n"
    421 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    422 	},
    423 
    424 	{ "example.com", "sub2.example.com. NS", "",
    425 ";flags QR rcode NOERROR\n"
    426 ";authority section\n"
    427 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    428 ";additional section\n"
    429 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    430 	},
    431 
    432 	{ "example.com", "obscured.sub2.example.com. A", "",
    433 ";flags QR rcode NOERROR\n"
    434 ";authority section\n"
    435 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    436 ";additional section\n"
    437 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    438 	},
    439 
    440 	{ "example.com", "abc.obscured.sub2.example.com. A", "",
    441 ";flags QR rcode NOERROR\n"
    442 ";authority section\n"
    443 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    444 ";additional section\n"
    445 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    446 	},
    447 
    448 	{ "example.com", "under.sub2.example.com. A", "",
    449 ";flags QR rcode NOERROR\n"
    450 ";authority section\n"
    451 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    452 ";additional section\n"
    453 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    454 	},
    455 
    456 	{ "example.com", "under.sub2.example.com. NS", "",
    457 ";flags QR rcode NOERROR\n"
    458 ";authority section\n"
    459 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    460 ";additional section\n"
    461 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    462 	},
    463 
    464 	{ "example.com", "abc.under.sub2.example.com. A", "",
    465 ";flags QR rcode NOERROR\n"
    466 ";authority section\n"
    467 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    468 ";additional section\n"
    469 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    470 	},
    471 
    472 	{ "example.com", "doubleobscured.under.sub2.example.com. A", "",
    473 ";flags QR rcode NOERROR\n"
    474 ";authority section\n"
    475 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    476 ";additional section\n"
    477 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    478 	},
    479 
    480 	{ "example.com", "abc.doubleobscured.under.sub2.example.com. A", "",
    481 ";flags QR rcode NOERROR\n"
    482 ";authority section\n"
    483 "sub2.example.com.	3600	IN	NS	ns1.sub.example.com.\n"
    484 ";additional section\n"
    485 "ns1.sub.example.com.	3600	IN	A	10.0.0.6\n"
    486 	},
    487 
    488 	{ "example.com", "wild.example.com. A", "",
    489 ";flags QR AA rcode NOERROR\n"
    490 ";authority section\n"
    491 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
    492 	},
    493 
    494 	{ "example.com", "*.wild.example.com. A", "",
    495 ";flags QR AA rcode NOERROR\n"
    496 ";answer section\n"
    497 "*.wild.example.com.	3600	IN	A	10.0.0.8\n"
    498 	},
    499 
    500 	{ "example.com", "*.wild.example.com. AAAA", "",
    501 ";flags QR AA rcode NOERROR\n"
    502 ";authority section\n"
    503 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
    504 	},
    505 
    506 	{ "example.com", "abc.wild.example.com. A", "",
    507 ";flags QR AA rcode NOERROR\n"
    508 ";answer section\n"
    509 "abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
    510 	},
    511 
    512 	{ "example.com", "abc.wild.example.com. AAAA", "",
    513 ";flags QR AA rcode NOERROR\n"
    514 ";authority section\n"
    515 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
    516 	},
    517 
    518 	{ "example.com", "foo.abc.wild.example.com. A", "",
    519 ";flags QR AA rcode NOERROR\n"
    520 ";answer section\n"
    521 "foo.abc.wild.example.com.	3600	IN	A	10.0.0.8\n"
    522 	},
    523 
    524 	{ "example.com", "foo.abc.wild.example.com. AAAA", "",
    525 ";flags QR AA rcode NOERROR\n"
    526 ";authority section\n"
    527 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
    528 	},
    529 
    530 	{ "example.com", "wild2.example.com. A", "",
    531 ";flags QR AA rcode NOERROR\n"
    532 ";authority section\n"
    533 "example.com.	3600	IN	SOA	ns.example.org. noc.example.org. 2017042710 7200 3600 1209600 3600\n"
    534 	},
    535 
    536 	{ "example.com", "*.wild2.example.com. A", "",
    537 ";flags QR AA rcode NOERROR\n"
    538 ";answer section\n"
    539 "*.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
    540 "www.example.com.	3600	IN	A	10.0.0.2\n"
    541 "www.example.com.	3600	IN	A	10.0.0.3\n"
    542 	},
    543 
    544 	{ "example.com", "abc.wild2.example.com. A", "",
    545 ";flags QR AA rcode NOERROR\n"
    546 ";answer section\n"
    547 "abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
    548 "www.example.com.	3600	IN	A	10.0.0.2\n"
    549 "www.example.com.	3600	IN	A	10.0.0.3\n"
    550 	},
    551 
    552 	{ "example.com", "foo.abc.wild2.example.com. A", "",
    553 ";flags QR AA rcode NOERROR\n"
    554 ";answer section\n"
    555 "foo.abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
    556 "www.example.com.	3600	IN	A	10.0.0.2\n"
    557 "www.example.com.	3600	IN	A	10.0.0.3\n"
    558 	},
    559 
    560 	{ "example.com", "abc.wild2.example.com. CNAME", "",
    561 ";flags QR AA rcode NOERROR\n"
    562 ";answer section\n"
    563 "abc.wild2.example.com.	3600	IN	CNAME	www.example.com.\n"
    564 	},
    565 
    566 	{ "example.com", "abc.wild3.example.com. IN ANY", "",
    567 ";flags QR AA rcode NOERROR\n"
    568 ";answer section\n"
    569 "abc.wild3.example.com.	3600	IN	MX	50 mail.example.com.\n"
    570 "abc.wild3.example.com.	3600	IN	A	10.0.0.8\n"
    571 	},
    572 
    573 	{ "example.com", "yy.example.com. TXT", "",
    574 ";flags QR AA rcode NOERROR\n"
    575 ";answer section\n"
    576 "yy.example.com.	3600	IN	TXT	\"a\"\n"
    577 "yy.example.com.	3600	IN	TXT	\"b\"\n"
    578 "yy.example.com.	3600	IN	TXT	\"c\"\n"
    579 "yy.example.com.	3600	IN	TXT	\"d\"\n"
    580 "yy.example.com.	3600	IN	TXT	\"e\"\n"
    581 "yy.example.com.	3600	IN	TXT	\"f\"\n"
    582 	},
    583 
    584 	{NULL, NULL, NULL, NULL}
    585 };
    586 
    587 /** number of tmpfiles */
    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 	config_auto_slab_values(cfg);
    674 	free(cfg->chrootdir);
    675 	cfg->chrootdir = NULL;
    676 
    677 	if(!auth_zone_read_zonefile(z, cfg)) {
    678 		fatal_exit("parse failure for auth zone %s", name);
    679 	}
    680 	lock_rw_unlock(&z->lock);
    681 	free(nm);
    682 	config_delete(cfg);
    683 	return z;
    684 }
    685 
    686 /** check that file is the same as other file */
    687 static void
    688 checkfile(char* f1, char *f2)
    689 {
    690 	char buf1[10240], buf2[10240];
    691 	int line = 0;
    692 	FILE* i1, *i2;
    693 	i1 = fopen(f1, "r");
    694 	if(!i1) fatal_exit("cannot open %s: %s", f1, strerror(errno));
    695 	i2 = fopen(f2, "r");
    696 	if(!i2) fatal_exit("cannot open %s: %s", f2, strerror(errno));
    697 
    698 	while(!feof(i1) && !feof(i2)) {
    699 		char* cp1, *cp2;
    700 		line++;
    701 		cp1 = fgets(buf1, (int)sizeof(buf1), i1);
    702 		cp2 = fgets(buf2, (int)sizeof(buf2), i2);
    703 		if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2)))
    704 			fatal_exit("fgets failed: %s", strerror(errno));
    705 		if(strncmp(buf1, "end_of_check", 12) == 0) {
    706 			fclose(i1);
    707 			fclose(i2);
    708 			return;
    709 		}
    710 		if(strcmp(buf1, buf2) != 0) {
    711 			log_info("in files %s and %s:%d", f1, f2, line);
    712 			log_info("'%s'", buf1);
    713 			log_info("'%s'", buf2);
    714 			fatal_exit("files are not equal");
    715 		}
    716 	}
    717 	unit_assert(feof(i1) && feof(i2));
    718 
    719 	fclose(i1);
    720 	fclose(i2);
    721 }
    722 
    723 /** check that a zone (in string) can be read and reproduced */
    724 static void
    725 check_read_exact(const char* name, const char* zone)
    726 {
    727 	struct auth_zones* az;
    728 	struct auth_zone* z;
    729 	char* fname, *outf;
    730 	if(vbmp) printf("check read zone %s\n", name);
    731 	fname = create_tmp_file(zone);
    732 
    733 	az = auth_zones_create();
    734 	unit_assert(az);
    735 	z = authtest_addzone(az, name, fname);
    736 	unit_assert(z);
    737 	outf = create_tmp_file(NULL);
    738 	if(!auth_zone_write_file(z, outf)) {
    739 		fatal_exit("write file failed for %s", fname);
    740 	}
    741 	checkfile(fname, outf);
    742 
    743 	del_tmp_file(fname);
    744 	del_tmp_file(outf);
    745 	auth_zones_delete(az);
    746 }
    747 
    748 /** parse q_ans structure for making query */
    749 static void
    750 q_ans_parse(struct q_ans* q, struct regional* region,
    751 	struct query_info** qinfo, int* fallback, uint8_t** dp_nm,
    752 	size_t* dp_nmlen)
    753 {
    754 	int ret;
    755 	uint8_t buf[65535];
    756 	size_t len, dname_len;
    757 
    758 	/* parse flags */
    759 	*fallback = 0; /* default fallback value */
    760 	if(strstr(q->flags, "fallback"))
    761 		*fallback = 1;
    762 
    763 	/* parse zone */
    764 	*dp_nmlen = sizeof(buf);
    765 	if((ret=sldns_str2wire_dname_buf(q->zone, buf, dp_nmlen))!=0)
    766 		fatal_exit("cannot parse query dp zone %s : %s", q->zone,
    767 			sldns_get_errorstr_parse(ret));
    768 	*dp_nm = regional_alloc_init(region, buf, *dp_nmlen);
    769 	if(!dp_nm) fatal_exit("out of memory");
    770 
    771 	/* parse query */
    772 	len = sizeof(buf);
    773 	dname_len = 0;
    774 	if((ret=sldns_str2wire_rr_question_buf(q->query, buf, &len, &dname_len,
    775 		*dp_nm, *dp_nmlen, NULL, 0))!=0)
    776 		fatal_exit("cannot parse query %s : %s", q->query,
    777 			sldns_get_errorstr_parse(ret));
    778 	*qinfo = (struct query_info*)regional_alloc_zero(region,
    779 		sizeof(**qinfo));
    780 	if(!*qinfo) fatal_exit("out of memory");
    781 	(*qinfo)->qname = regional_alloc_init(region, buf, dname_len);
    782 	if(!(*qinfo)->qname) fatal_exit("out of memory");
    783 	(*qinfo)->qname_len = dname_len;
    784 	(*qinfo)->qtype = sldns_wirerr_get_type(buf, len, dname_len);
    785 	(*qinfo)->qclass = sldns_wirerr_get_class(buf, len, dname_len);
    786 }
    787 
    788 /** print flags to string */
    789 static void
    790 pr_flags(sldns_buffer* buf, uint16_t flags)
    791 {
    792 	char rcode[32];
    793 	sldns_buffer_printf(buf, ";flags");
    794 	if((flags&BIT_QR)!=0) sldns_buffer_printf(buf, " QR");
    795 	if((flags&BIT_AA)!=0) sldns_buffer_printf(buf, " AA");
    796 	if((flags&BIT_TC)!=0) sldns_buffer_printf(buf, " TC");
    797 	if((flags&BIT_RD)!=0) sldns_buffer_printf(buf, " RD");
    798 	if((flags&BIT_CD)!=0) sldns_buffer_printf(buf, " CD");
    799 	if((flags&BIT_RA)!=0) sldns_buffer_printf(buf, " RA");
    800 	if((flags&BIT_AD)!=0) sldns_buffer_printf(buf, " AD");
    801 	if((flags&BIT_Z)!=0) sldns_buffer_printf(buf, " Z");
    802 	sldns_wire2str_rcode_buf((int)(FLAGS_GET_RCODE(flags)),
    803 		rcode, sizeof(rcode));
    804 	sldns_buffer_printf(buf, " rcode %s", rcode);
    805 	sldns_buffer_printf(buf, "\n");
    806 }
    807 
    808 /** print RRs to string */
    809 static void
    810 pr_rrs(sldns_buffer* buf, struct reply_info* rep)
    811 {
    812 	char s[65536];
    813 	size_t i, j;
    814 	struct packed_rrset_data* d;
    815 	log_assert(rep->rrset_count == rep->an_numrrsets + rep->ns_numrrsets
    816 		+ rep->ar_numrrsets);
    817 	for(i=0; i<rep->rrset_count; i++) {
    818 		/* section heading */
    819 		if(i == 0 && rep->an_numrrsets != 0)
    820 			sldns_buffer_printf(buf, ";answer section\n");
    821 		else if(i == rep->an_numrrsets && rep->ns_numrrsets != 0)
    822 			sldns_buffer_printf(buf, ";authority section\n");
    823 		else if(i == rep->an_numrrsets+rep->ns_numrrsets &&
    824 			rep->ar_numrrsets != 0)
    825 			sldns_buffer_printf(buf, ";additional section\n");
    826 		/* spool RRset */
    827 		d = (struct packed_rrset_data*)rep->rrsets[i]->entry.data;
    828 		for(j=0; j<d->count+d->rrsig_count; j++) {
    829 			if(!packed_rr_to_string(rep->rrsets[i], j, 0,
    830 				s, sizeof(s))) {
    831 				fatal_exit("could not rr_to_string %d",
    832 					(int)i);
    833 			}
    834 			sldns_buffer_printf(buf, "%s", s);
    835 		}
    836 	}
    837 }
    838 
    839 /** create string for message */
    840 static char*
    841 msgtostr(struct dns_msg* msg)
    842 {
    843 	char* str;
    844 	sldns_buffer* buf = sldns_buffer_new(65535);
    845 	if(!buf) fatal_exit("out of memory");
    846 	if(!msg) {
    847 		sldns_buffer_printf(buf, "null packet\n");
    848 	} else {
    849 		pr_flags(buf, msg->rep->flags);
    850 		pr_rrs(buf, msg->rep);
    851 	}
    852 
    853 	str = strdup((char*)sldns_buffer_begin(buf));
    854 	if(!str) fatal_exit("out of memory");
    855 	sldns_buffer_free(buf);
    856 	return str;
    857 }
    858 
    859 /** find line diff between strings */
    860 static void
    861 line_diff(const char* p, const char* q, const char* pdesc, const char* qdesc)
    862 {
    863 	char* pdup, *qdup, *pl, *ql;
    864 	int line = 1;
    865 	pdup = strdup(p);
    866 	qdup = strdup(q);
    867 	if(!pdup || !qdup) fatal_exit("out of memory");
    868 	pl=pdup;
    869 	ql=qdup;
    870 	printf("linediff (<%s, >%s)\n", pdesc, qdesc);
    871 	while(pl && ql && *pl && *ql) {
    872 		char* ep = strchr(pl, '\n');
    873 		char* eq = strchr(ql, '\n');
    874 		/* terminate lines */
    875 		if(ep) *ep = 0;
    876 		if(eq) *eq = 0;
    877 		/* printout */
    878 		if(strcmp(pl, ql) == 0) {
    879 			printf("%3d   %s\n", line, pl);
    880 		} else {
    881 			printf("%3d < %s\n", line, pl);
    882 			printf("%3d > %s\n", line, ql);
    883 		}
    884 		if(ep) *ep = '\n';
    885 		if(eq) *eq = '\n';
    886 		if(ep) pl = ep+1;
    887 		else pl = NULL;
    888 		if(eq) ql = eq+1;
    889 		else ql = NULL;
    890 		line++;
    891 	}
    892 	if(pl && *pl) {
    893 		printf("%3d < %s\n", line, pl);
    894 	}
    895 	if(ql && *ql) {
    896 		printf("%3d > %s\n", line, ql);
    897 	}
    898 	free(pdup);
    899 	free(qdup);
    900 }
    901 
    902 /** make q_ans query */
    903 static void
    904 q_ans_query(struct q_ans* q, struct auth_zones* az, struct query_info* qinfo,
    905 	struct regional* region, int expected_fallback, uint8_t* dp_nm,
    906 	size_t dp_nmlen)
    907 {
    908 	int ret, fallback = 0;
    909 	struct dns_msg* msg = NULL;
    910 	char* ans_str;
    911 	int oldv = verbosity;
    912 	/* increase verbosity to printout logic in authzone */
    913 	if(vbmp) verbosity = 4;
    914 	ret = auth_zones_lookup(az, qinfo, region, &msg, &fallback, dp_nm,
    915 		dp_nmlen);
    916 	if(vbmp) verbosity = oldv;
    917 
    918 	/* check the answer */
    919 	ans_str = msgtostr(msg);
    920 	/* printout if vbmp */
    921 	if(vbmp) printf("got (ret=%s%s):\n%s",
    922 		(ret?"ok":"fail"), (fallback?" fallback":""), ans_str);
    923 	/* check expected value for ret */
    924 	if(expected_fallback && ret != 0) {
    925 		/* ret is zero on fallback */
    926 		if(vbmp) printf("fallback expected, but "
    927 			"return value is not false\n");
    928 		unit_assert(expected_fallback && ret == 0);
    929 	}
    930 	if(ret == 0) {
    931 		if(!expected_fallback) {
    932 			if(vbmp) printf("return value is false, "
    933 				"(unexpected)\n");
    934 		}
    935 		unit_assert(expected_fallback);
    936 	}
    937 	/* check expected value for fallback */
    938 	if(expected_fallback && !fallback) {
    939 		if(vbmp) printf("expected fallback, but fallback is no\n");
    940 	} else if(!expected_fallback && fallback) {
    941 		if(vbmp) printf("expected no fallback, but fallback is yes\n");
    942 	}
    943 	unit_assert( (expected_fallback&&fallback) ||
    944 		(!expected_fallback&&!fallback));
    945 	/* check answer string */
    946 	if(strcmp(q->answer, ans_str) != 0) {
    947 		if(vbmp) printf("wanted:\n%s", q->answer);
    948 		line_diff(q->answer, ans_str, "wanted", "got");
    949 	}
    950 	unit_assert(strcmp(q->answer, ans_str) == 0);
    951 	if(vbmp) printf("query ok\n\n");
    952 	free(ans_str);
    953 }
    954 
    955 /** check queries on a loaded zone */
    956 static void
    957 check_az_q_ans(struct auth_zones* az, struct q_ans* queries)
    958 {
    959 	struct q_ans* q;
    960 	struct regional* region = regional_create();
    961 	struct query_info* qinfo;
    962 	int fallback;
    963 	uint8_t* dp_nm;
    964 	size_t dp_nmlen;
    965 	for(q=queries; q->zone; q++) {
    966 		if(vbmp) printf("query %s: %s %s\n", q->zone, q->query,
    967 			q->flags);
    968 		q_ans_parse(q, region, &qinfo, &fallback, &dp_nm, &dp_nmlen);
    969 		q_ans_query(q, az, qinfo, region, fallback, dp_nm, dp_nmlen);
    970 		regional_free_all(region);
    971 	}
    972 	regional_destroy(region);
    973 }
    974 
    975 /** check queries for a zone are returned as specified */
    976 static void
    977 check_queries(const char* name, const char* zone, struct q_ans* queries)
    978 {
    979 	struct auth_zones* az;
    980 	struct auth_zone* z;
    981 	char* fname;
    982 	if(vbmp) printf("check queries %s\n", name);
    983 	fname = create_tmp_file(zone);
    984 	az = auth_zones_create();
    985 	if(!az) fatal_exit("out of memory");
    986 	z = authtest_addzone(az, name, fname);
    987 	if(!z) fatal_exit("could not read zone for queries test");
    988 	del_tmp_file(fname);
    989 
    990 	/* run queries and test them */
    991 	check_az_q_ans(az, queries);
    992 
    993 	auth_zones_delete(az);
    994 }
    995 
    996 /** Test authzone compare_serial */
    997 static void
    998 authzone_compare_serial(void)
    999 {
   1000 	if(vbmp) printf("Testing compare_serial\n");
   1001 	unit_assert(compare_serial(0, 1) < 0);
   1002 	unit_assert(compare_serial(1, 0) > 0);
   1003 	unit_assert(compare_serial(0, 0) == 0);
   1004 	unit_assert(compare_serial(1, 1) == 0);
   1005 	unit_assert(compare_serial(0xf0000000, 0xf0000000) == 0);
   1006 	unit_assert(compare_serial(0, 0xf0000000) > 0);
   1007 	unit_assert(compare_serial(0xf0000000, 0) < 0);
   1008 	unit_assert(compare_serial(0xf0000000, 0xf0000001) < 0);
   1009 	unit_assert(compare_serial(0xf0000002, 0xf0000001) > 0);
   1010 	unit_assert(compare_serial(0x70000000, 0x80000000) < 0);
   1011 	unit_assert(compare_serial(0x90000000, 0x70000000) > 0);
   1012 }
   1013 
   1014 /** Test authzone read from file */
   1015 static void
   1016 authzone_read_test(void)
   1017 {
   1018 	if(vbmp) printf("Testing read auth zone\n");
   1019 	check_read_exact("example.com", zone_example_com);
   1020 }
   1021 
   1022 /** Test authzone query from zone */
   1023 static void
   1024 authzone_query_test(void)
   1025 {
   1026 	if(vbmp) printf("Testing query auth zone\n");
   1027 	check_queries("example.com", zone_example_com, example_com_queries);
   1028 }
   1029 
   1030 /** Test chunkline_count_parens output */
   1031 static void
   1032 authzone_chunkline_count_parens_test(void)
   1033 {
   1034 	sldns_buffer* buf;
   1035 	if(vbmp) printf("Testing chunkline_count_parens\n");
   1036 	buf = sldns_buffer_new(1024);
   1037 	if(!buf) fatal_exit("out of memory");
   1038 
   1039 	/* Check that escaped characters are handled, '\x', and in quotes. */
   1040 	sldns_buffer_printf(buf, "TXT \"x\" \\(");
   1041 	unit_assert(chunkline_count_parens(buf, 0) == 0);
   1042 
   1043 	sldns_buffer_clear(buf);
   1044 	sldns_buffer_printf(buf, "TXT ';x' (");
   1045 	unit_assert(chunkline_count_parens(buf, 0) == 0);
   1046 
   1047 	sldns_buffer_clear(buf);
   1048 	sldns_buffer_printf(buf, "TXT \"a;b\" (");
   1049 	unit_assert(chunkline_count_parens(buf, 0) == 1);
   1050 
   1051 	sldns_buffer_clear(buf);
   1052 	sldns_buffer_printf(buf, "TXT \\) )");
   1053 	unit_assert(chunkline_count_parens(buf, 0) == -1);
   1054 
   1055 	sldns_buffer_clear(buf);
   1056 	sldns_buffer_printf(buf, "TXT \"a\\\\\" \"(\" ");
   1057 	unit_assert(chunkline_count_parens(buf, 0) == 0);
   1058 
   1059 	sldns_buffer_free(buf);
   1060 }
   1061 
   1062 /** test authzone code */
   1063 void
   1064 authzone_test(void)
   1065 {
   1066 	unit_show_feature("authzone");
   1067 	atexit(tmpfilecleanup);
   1068 	authzone_compare_serial();
   1069 	authzone_read_test();
   1070 	authzone_query_test();
   1071 	authzone_chunkline_count_parens_test();
   1072 }
   1073