Home | History | Annotate | Line # | Download | only in testcode
unitmsgparse.c revision 1.1
      1  1.1  christos /*
      2  1.1  christos  * testcode/unitmsgparse.c - unit test for msg parse routines.
      3  1.1  christos  *
      4  1.1  christos  * Copyright (c) 2007, NLnet Labs. All rights reserved.
      5  1.1  christos  *
      6  1.1  christos  * This software is open source.
      7  1.1  christos  *
      8  1.1  christos  * Redistribution and use in source and binary forms, with or without
      9  1.1  christos  * modification, are permitted provided that the following conditions
     10  1.1  christos  * are met:
     11  1.1  christos  *
     12  1.1  christos  * Redistributions of source code must retain the above copyright notice,
     13  1.1  christos  * this list of conditions and the following disclaimer.
     14  1.1  christos  *
     15  1.1  christos  * Redistributions in binary form must reproduce the above copyright notice,
     16  1.1  christos  * this list of conditions and the following disclaimer in the documentation
     17  1.1  christos  * and/or other materials provided with the distribution.
     18  1.1  christos  *
     19  1.1  christos  * Neither the name of the NLNET LABS nor the names of its contributors may
     20  1.1  christos  * be used to endorse or promote products derived from this software without
     21  1.1  christos  * specific prior written permission.
     22  1.1  christos  *
     23  1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24  1.1  christos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25  1.1  christos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     26  1.1  christos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     27  1.1  christos  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     28  1.1  christos  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     29  1.1  christos  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     30  1.1  christos  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     31  1.1  christos  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  1.1  christos  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  1.1  christos  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  1.1  christos  *
     35  1.1  christos  */
     36  1.1  christos /**
     37  1.1  christos  * \file
     38  1.1  christos  * Calls msg parse unit tests. Exits with code 1 on a failure.
     39  1.1  christos  */
     40  1.1  christos 
     41  1.1  christos #include "config.h"
     42  1.1  christos #include <sys/time.h>
     43  1.1  christos #include "util/log.h"
     44  1.1  christos #include "testcode/unitmain.h"
     45  1.1  christos #include "util/data/msgparse.h"
     46  1.1  christos #include "util/data/msgreply.h"
     47  1.1  christos #include "util/data/msgencode.h"
     48  1.1  christos #include "util/data/dname.h"
     49  1.1  christos #include "util/alloc.h"
     50  1.1  christos #include "util/regional.h"
     51  1.1  christos #include "util/net_help.h"
     52  1.1  christos #include "testcode/readhex.h"
     53  1.1  christos #include "testcode/testpkts.h"
     54  1.1  christos #include "sldns/sbuffer.h"
     55  1.1  christos #include "sldns/str2wire.h"
     56  1.1  christos #include "sldns/wire2str.h"
     57  1.1  christos 
     58  1.1  christos /** verbose message parse unit test */
     59  1.1  christos static int vbmp = 0;
     60  1.1  christos /** do not accept formerr */
     61  1.1  christos static int check_formerr_gone = 0;
     62  1.1  christos /** if matching within a section should disregard the order of RRs. */
     63  1.1  christos static int matches_nolocation = 0;
     64  1.1  christos /** see if RRSIGs are properly matched to RRsets. */
     65  1.1  christos static int check_rrsigs = 0;
     66  1.1  christos /** do not check buffer sameness */
     67  1.1  christos static int check_nosameness = 0;
     68  1.1  christos 
     69  1.1  christos /** see if buffers contain the same packet */
     70  1.1  christos static int
     71  1.1  christos test_buffers(sldns_buffer* pkt, sldns_buffer* out)
     72  1.1  christos {
     73  1.1  christos 	/* check binary same */
     74  1.1  christos 	if(sldns_buffer_limit(pkt) == sldns_buffer_limit(out) &&
     75  1.1  christos 		memcmp(sldns_buffer_begin(pkt), sldns_buffer_begin(out),
     76  1.1  christos 			sldns_buffer_limit(pkt)) == 0) {
     77  1.1  christos 		if(vbmp) printf("binary the same (length=%u)\n",
     78  1.1  christos 				(unsigned)sldns_buffer_limit(pkt));
     79  1.1  christos 		return 1;
     80  1.1  christos 	}
     81  1.1  christos 
     82  1.1  christos 	if(vbmp) {
     83  1.1  christos 		size_t sz = 16;
     84  1.1  christos 		size_t count;
     85  1.1  christos 		size_t lim = sldns_buffer_limit(out);
     86  1.1  christos 		if(sldns_buffer_limit(pkt) < lim)
     87  1.1  christos 			lim = sldns_buffer_limit(pkt);
     88  1.1  christos 		for(count=0; count<lim; count+=sz) {
     89  1.1  christos 			size_t rem = sz;
     90  1.1  christos 			if(lim-count < sz) rem = lim-count;
     91  1.1  christos 			if(memcmp(sldns_buffer_at(pkt, count),
     92  1.1  christos 				sldns_buffer_at(out, count), rem) == 0) {
     93  1.1  christos 				log_info("same %d %d", (int)count, (int)rem);
     94  1.1  christos 				log_hex("same: ", sldns_buffer_at(pkt, count),
     95  1.1  christos 					rem);
     96  1.1  christos 			} else {
     97  1.1  christos 				log_info("diff %d %d", (int)count, (int)rem);
     98  1.1  christos 				log_hex("difp: ", sldns_buffer_at(pkt, count),
     99  1.1  christos 					rem);
    100  1.1  christos 				log_hex("difo: ", sldns_buffer_at(out, count),
    101  1.1  christos 					rem);
    102  1.1  christos 			}
    103  1.1  christos 		}
    104  1.1  christos 	}
    105  1.1  christos 
    106  1.1  christos 	/* check if it 'means the same' */
    107  1.1  christos 	if(vbmp) {
    108  1.1  christos 		char* s1, *s2;
    109  1.1  christos 		log_buf(0, "orig in hex", pkt);
    110  1.1  christos 		log_buf(0, "unbound out in hex", out);
    111  1.1  christos 		printf("\npacket from unbound (%d):\n",
    112  1.1  christos 			(int)sldns_buffer_limit(out));
    113  1.1  christos 		s1 = sldns_wire2str_pkt(sldns_buffer_begin(out),
    114  1.1  christos 			sldns_buffer_limit(out));
    115  1.1  christos 		printf("%s\n", s1?s1:"null");
    116  1.1  christos 		free(s1);
    117  1.1  christos 
    118  1.1  christos 		printf("\npacket original (%d):\n",
    119  1.1  christos 			(int)sldns_buffer_limit(pkt));
    120  1.1  christos 		s2 = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
    121  1.1  christos 			sldns_buffer_limit(pkt));
    122  1.1  christos 		printf("%s\n", s2?s2:"null");
    123  1.1  christos 		free(s2);
    124  1.1  christos 		printf("\n");
    125  1.1  christos 	}
    126  1.1  christos 	/* if it had two EDNS sections, skip comparison */
    127  1.1  christos 	if(1) {
    128  1.1  christos 		char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
    129  1.1  christos 			sldns_buffer_limit(pkt));
    130  1.1  christos 		char* e1 = strstr(s, "; EDNS:");
    131  1.1  christos 		if(e1 && strstr(e1+4, "; EDNS:")) {
    132  1.1  christos 			free(s);
    133  1.1  christos 			return 0;
    134  1.1  christos 		}
    135  1.1  christos 		free(s);
    136  1.1  christos 	}
    137  1.1  christos 	/* compare packets */
    138  1.1  christos 	unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
    139  1.1  christos 		sldns_buffer_begin(out), sldns_buffer_limit(out), 1,
    140  1.1  christos 		matches_nolocation));
    141  1.1  christos 	return 0;
    142  1.1  christos }
    143  1.1  christos 
    144  1.1  christos /** check if unbound formerr equals ldns formerr */
    145  1.1  christos static void
    146  1.1  christos checkformerr(sldns_buffer* pkt)
    147  1.1  christos {
    148  1.1  christos 	int status = 0;
    149  1.1  christos 	char* s = sldns_wire2str_pkt(sldns_buffer_begin(pkt),
    150  1.1  christos 		sldns_buffer_limit(pkt));
    151  1.1  christos 	if(!s) fatal_exit("out of memory");
    152  1.1  christos 	if(strstr(s, "Error")) status = 1;
    153  1.1  christos 	if(strstr(s, "error")) status = 1;
    154  1.1  christos 	if(status == 0) {
    155  1.1  christos 		printf("Formerr, but ldns gives packet:\n");
    156  1.1  christos 		printf("%s\n", s);
    157  1.1  christos 		free(s);
    158  1.1  christos 		exit(1);
    159  1.1  christos 	}
    160  1.1  christos 	free(s);
    161  1.1  christos 	unit_assert(status != 0);
    162  1.1  christos }
    163  1.1  christos 
    164  1.1  christos /** performance test message encoding */
    165  1.1  christos static void
    166  1.1  christos perf_encode(struct query_info* qi, struct reply_info* rep, uint16_t id,
    167  1.1  christos 	uint16_t flags, sldns_buffer* out, time_t timenow,
    168  1.1  christos 	struct edns_data* edns)
    169  1.1  christos {
    170  1.1  christos 	static int num = 0;
    171  1.1  christos 	int ret;
    172  1.1  christos 	size_t max = 10000;
    173  1.1  christos 	size_t i;
    174  1.1  christos 	struct timeval start, end;
    175  1.1  christos 	double dt;
    176  1.1  christos 	struct regional* r2 = regional_create();
    177  1.1  christos 	if(gettimeofday(&start, NULL) < 0)
    178  1.1  christos 		fatal_exit("gettimeofday: %s", strerror(errno));
    179  1.1  christos 	/* encode a couple times */
    180  1.1  christos 	for(i=0; i<max; i++) {
    181  1.1  christos 		ret = reply_info_encode(qi, rep, id, flags, out, timenow,
    182  1.1  christos 			r2, 65535, (int)(edns->bits & EDNS_DO) );
    183  1.1  christos 		unit_assert(ret != 0); /* udp packets should fit */
    184  1.1  christos 		attach_edns_record(out, edns);
    185  1.1  christos 		regional_free_all(r2);
    186  1.1  christos 	}
    187  1.1  christos 	if(gettimeofday(&end, NULL) < 0)
    188  1.1  christos 		fatal_exit("gettimeofday: %s", strerror(errno));
    189  1.1  christos 	/* time in millisec */
    190  1.1  christos 	dt = (double)(end.tv_sec - start.tv_sec)*1000. +
    191  1.1  christos 		((double)end.tv_usec - (double)start.tv_usec)/1000.;
    192  1.1  christos 	printf("[%d] did %u in %g msec for %f encode/sec size %d\n", num++,
    193  1.1  christos 		(unsigned)max, dt, (double)max / (dt/1000.),
    194  1.1  christos 		(int)sldns_buffer_limit(out));
    195  1.1  christos 	regional_destroy(r2);
    196  1.1  christos }
    197  1.1  christos 
    198  1.1  christos /** perf test a packet */
    199  1.1  christos static void
    200  1.1  christos perftestpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out,
    201  1.1  christos 	const char* hex)
    202  1.1  christos {
    203  1.1  christos 	struct query_info qi;
    204  1.1  christos 	struct reply_info* rep = 0;
    205  1.1  christos 	int ret;
    206  1.1  christos 	uint16_t id;
    207  1.1  christos 	uint16_t flags;
    208  1.1  christos 	time_t timenow = 0;
    209  1.1  christos 	struct regional* region = regional_create();
    210  1.1  christos 	struct edns_data edns;
    211  1.1  christos 
    212  1.1  christos 	hex_to_buf(pkt, hex);
    213  1.1  christos 	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
    214  1.1  christos 	if(sldns_buffer_limit(pkt) < 2)
    215  1.1  christos 		flags = 0;
    216  1.1  christos 	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
    217  1.1  christos 	flags = ntohs(flags);
    218  1.1  christos 	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
    219  1.1  christos 	if(ret != 0) {
    220  1.1  christos 		char rbuf[16];
    221  1.1  christos 		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
    222  1.1  christos 		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
    223  1.1  christos 		if(ret == LDNS_RCODE_FORMERR)
    224  1.1  christos 			checkformerr(pkt);
    225  1.1  christos 		unit_assert(ret != LDNS_RCODE_SERVFAIL);
    226  1.1  christos 	} else {
    227  1.1  christos 		perf_encode(&qi, rep, id, flags, out, timenow, &edns);
    228  1.1  christos 	}
    229  1.1  christos 
    230  1.1  christos 	query_info_clear(&qi);
    231  1.1  christos 	reply_info_parsedelete(rep, alloc);
    232  1.1  christos 	regional_destroy(region);
    233  1.1  christos }
    234  1.1  christos 
    235  1.1  christos /** print packed rrset */
    236  1.1  christos static void
    237  1.1  christos print_rrset(struct ub_packed_rrset_key* rrset)
    238  1.1  christos {
    239  1.1  christos 	struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
    240  1.1  christos 	                entry.data;
    241  1.1  christos 	char buf[65535];
    242  1.1  christos 	size_t i;
    243  1.1  christos 	for(i=0; i<d->count+d->rrsig_count; i++) {
    244  1.1  christos 		if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf)))
    245  1.1  christos 			printf("failedtoconvert %d\n", (int)i);
    246  1.1  christos 		else
    247  1.1  christos 			printf("%s\n", buf);
    248  1.1  christos 	}
    249  1.1  christos }
    250  1.1  christos 
    251  1.1  christos /** debug print a packet that failed */
    252  1.1  christos static void
    253  1.1  christos print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep)
    254  1.1  christos {
    255  1.1  christos 	size_t i;
    256  1.1  christos 	log_query_info(0, "failed query", qinfo);
    257  1.1  christos 	printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets);
    258  1.1  christos 	for(i=0; i<rep->an_numrrsets; i++) {
    259  1.1  christos 		printf("; rrset %d\n", (int)i);
    260  1.1  christos 		print_rrset(rep->rrsets[i]);
    261  1.1  christos 	}
    262  1.1  christos 	printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets);
    263  1.1  christos 	for(i=rep->an_numrrsets; i<rep->an_numrrsets+rep->ns_numrrsets; i++) {
    264  1.1  christos 		printf("; rrset %d\n", (int)i);
    265  1.1  christos 		print_rrset(rep->rrsets[i]);
    266  1.1  christos 	}
    267  1.1  christos 	printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets);
    268  1.1  christos 	for(i=rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) {
    269  1.1  christos 		printf("; rrset %d\n", (int)i);
    270  1.1  christos 		print_rrset(rep->rrsets[i]);
    271  1.1  christos 	}
    272  1.1  christos 	printf(";; packet end\n");
    273  1.1  christos }
    274  1.1  christos 
    275  1.1  christos /** check that there is no data element that matches the RRSIG */
    276  1.1  christos static int
    277  1.1  christos no_data_for_rrsig(struct reply_info* rep, struct ub_packed_rrset_key* rrsig)
    278  1.1  christos {
    279  1.1  christos 	size_t i;
    280  1.1  christos 	for(i=0; i<rep->rrset_count; i++) {
    281  1.1  christos 		if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_RRSIG)
    282  1.1  christos 			continue;
    283  1.1  christos 		if(query_dname_compare(rep->rrsets[i]->rk.dname,
    284  1.1  christos 			rrsig->rk.dname) == 0)
    285  1.1  christos 			/* only name is compared right now */
    286  1.1  christos 			return 0;
    287  1.1  christos 	}
    288  1.1  christos 	return 1;
    289  1.1  christos }
    290  1.1  christos 
    291  1.1  christos /** check RRSIGs in packet */
    292  1.1  christos static void
    293  1.1  christos check_the_rrsigs(struct query_info* qinfo, struct reply_info* rep)
    294  1.1  christos {
    295  1.1  christos 	/* every RRSIG must be matched to an RRset */
    296  1.1  christos 	size_t i;
    297  1.1  christos 	for(i=0; i<rep->rrset_count; i++) {
    298  1.1  christos 		struct ub_packed_rrset_key* s = rep->rrsets[i];
    299  1.1  christos 		if(ntohs(s->rk.type) == LDNS_RR_TYPE_RRSIG) {
    300  1.1  christos 			/* see if really a problem, i.e. is there a data
    301  1.1  christos 			 * element. */
    302  1.1  christos 			if(no_data_for_rrsig(rep, rep->rrsets[i]))
    303  1.1  christos 				continue;
    304  1.1  christos 			log_dns_msg("rrsig failed for packet", qinfo, rep);
    305  1.1  christos 			print_packet_rrsets(qinfo, rep);
    306  1.1  christos 			printf("failed rrset is nr %d\n", (int)i);
    307  1.1  christos 			unit_assert(0);
    308  1.1  christos 		}
    309  1.1  christos 	}
    310  1.1  christos }
    311  1.1  christos 
    312  1.1  christos /** test a packet */
    313  1.1  christos static void
    314  1.1  christos testpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out,
    315  1.1  christos 	const char* hex)
    316  1.1  christos {
    317  1.1  christos 	struct query_info qi;
    318  1.1  christos 	struct reply_info* rep = 0;
    319  1.1  christos 	int ret;
    320  1.1  christos 	uint16_t id;
    321  1.1  christos 	uint16_t flags;
    322  1.1  christos 	uint32_t timenow = 0;
    323  1.1  christos 	struct regional* region = regional_create();
    324  1.1  christos 	struct edns_data edns;
    325  1.1  christos 
    326  1.1  christos 	hex_to_buf(pkt, hex);
    327  1.1  christos 	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
    328  1.1  christos 	if(sldns_buffer_limit(pkt) < 2)
    329  1.1  christos 		flags = 0;
    330  1.1  christos 	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
    331  1.1  christos 	flags = ntohs(flags);
    332  1.1  christos 	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
    333  1.1  christos 	if(ret != 0) {
    334  1.1  christos 		char rbuf[16];
    335  1.1  christos 		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
    336  1.1  christos 		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
    337  1.1  christos 		if(ret == LDNS_RCODE_FORMERR) {
    338  1.1  christos 			unit_assert(!check_formerr_gone);
    339  1.1  christos 			checkformerr(pkt);
    340  1.1  christos 		}
    341  1.1  christos 		unit_assert(ret != LDNS_RCODE_SERVFAIL);
    342  1.1  christos 	} else if(!check_formerr_gone) {
    343  1.1  christos 		const size_t lim = 512;
    344  1.1  christos 		ret = reply_info_encode(&qi, rep, id, flags, out, timenow,
    345  1.1  christos 			region, 65535, (int)(edns.bits & EDNS_DO) );
    346  1.1  christos 		unit_assert(ret != 0); /* udp packets should fit */
    347  1.1  christos 		attach_edns_record(out, &edns);
    348  1.1  christos 		if(vbmp) printf("inlen %u outlen %u\n",
    349  1.1  christos 			(unsigned)sldns_buffer_limit(pkt),
    350  1.1  christos 			(unsigned)sldns_buffer_limit(out));
    351  1.1  christos 		if(!check_nosameness)
    352  1.1  christos 			test_buffers(pkt, out);
    353  1.1  christos 		if(check_rrsigs)
    354  1.1  christos 			check_the_rrsigs(&qi, rep);
    355  1.1  christos 
    356  1.1  christos 		if(sldns_buffer_limit(out) > lim) {
    357  1.1  christos 			ret = reply_info_encode(&qi, rep, id, flags, out,
    358  1.1  christos 				timenow, region,
    359  1.1  christos 				lim - calc_edns_field_size(&edns),
    360  1.1  christos 				(int)(edns.bits & EDNS_DO));
    361  1.1  christos 			unit_assert(ret != 0); /* should fit, but with TC */
    362  1.1  christos 			attach_edns_record(out, &edns);
    363  1.1  christos 			if( LDNS_QDCOUNT(sldns_buffer_begin(out)) !=
    364  1.1  christos 				LDNS_QDCOUNT(sldns_buffer_begin(pkt)) ||
    365  1.1  christos 				LDNS_ANCOUNT(sldns_buffer_begin(out)) !=
    366  1.1  christos 				LDNS_ANCOUNT(sldns_buffer_begin(pkt)) ||
    367  1.1  christos 				LDNS_NSCOUNT(sldns_buffer_begin(out)) !=
    368  1.1  christos 				LDNS_NSCOUNT(sldns_buffer_begin(pkt)))
    369  1.1  christos 				unit_assert(
    370  1.1  christos 				LDNS_TC_WIRE(sldns_buffer_begin(out)));
    371  1.1  christos 				/* must set TC bit if shortened */
    372  1.1  christos 			unit_assert(sldns_buffer_limit(out) <= lim);
    373  1.1  christos 		}
    374  1.1  christos 	}
    375  1.1  christos 
    376  1.1  christos 	query_info_clear(&qi);
    377  1.1  christos 	reply_info_parsedelete(rep, alloc);
    378  1.1  christos 	regional_destroy(region);
    379  1.1  christos }
    380  1.1  christos 
    381  1.1  christos /** simple test of parsing */
    382  1.1  christos static void
    383  1.1  christos simpletest(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out)
    384  1.1  christos {
    385  1.1  christos 	/* a root query  drill -q - */
    386  1.1  christos 	testpkt(pkt, alloc, out,
    387  1.1  christos 		" c5 40 01 00 00 01 00 00 00 00 00 00 00 00 02 00 01 ");
    388  1.1  christos 
    389  1.1  christos 	/* very small packet */
    390  1.1  christos 	testpkt(pkt, alloc, out,
    391  1.1  christos "; 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19\n"
    392  1.1  christos ";-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n"
    393  1.1  christos "74 0c 85 83 00 01 00 00 00 01 00 00 03 62 6c 61 09 6e 6c 6e    ;          1-  20\n"
    394  1.1  christos "65 74 6c 61 62 73 02 6e 6c 00 00 0f 00 01 09 6e 6c 6e 65 74    ;         21-  40\n"
    395  1.1  christos "6c 61 62 73 02 6e 6c 00 00 06 00 01 00 00 46 50 00 40 04 6f    ;         41-  60\n"
    396  1.1  christos "70 65 6e 09 6e 6c 6e 65 74 6c 61 62 73 02 6e 6c 00 0a 68 6f    ;         61-  80\n"
    397  1.1  christos "73 74 6d 61 73 74 65 72 09 6e 6c 6e 65 74 6c 61 62 73 02 6e    ;         81- 100\n"
    398  1.1  christos "6c 00 77 a1 02 58 00 00 70 80 00 00 1c 20 00 09 3a 80 00 00    ;        101- 120\n"
    399  1.1  christos "46 50\n");
    400  1.1  christos 
    401  1.1  christos 	/* a root reply  drill -w - */
    402  1.1  christos 	testpkt(pkt, alloc, out,
    403  1.1  christos 	" ; 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19\n"
    404  1.1  christos 	" ;-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n"
    405  1.1  christos 	" 97 3f 81 80 00 01 00 0d 00 00 00 02 00 00 02 00 01 00 00 02    ;          1-  20\n"
    406  1.1  christos 	" 00 01 00 06 6d 38 00 14 01 49 0c 52 4f 4f 54 2d 53 45 52 56    ;         21-  40\n"
    407  1.1  christos 	" 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01    ;         41-  60\n"
    408  1.1  christos 	" 4a 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00    ;         61-  80\n"
    409  1.1  christos 	" 00 02 00 01 00 06 6d 38 00 14 01 4b 0c 52 4f 4f 54 2d 53 45    ;         81- 100\n"
    410  1.1  christos 	" 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00    ;        101- 120\n"
    411  1.1  christos 	" 14 01 4c 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54    ;        121- 140\n"
    412  1.1  christos 	" 00 00 00 02 00 01 00 06 6d 38 00 14 01 4d 0c 52 4f 4f 54 2d    ;        141- 160\n"
    413  1.1  christos 	" 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d    ;        161- 180\n"
    414  1.1  christos 	" 38 00 14 01 41 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e    ;        181- 200\n"
    415  1.1  christos 	" 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 42 0c 52 4f 4f    ;        201- 220\n"
    416  1.1  christos 	" 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00    ;        221- 240\n"
    417  1.1  christos 	" 06 6d 38 00 14 01 43 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53    ;        241- 260\n"
    418  1.1  christos 	" 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 44 0c 52    ;        261- 280\n"
    419  1.1  christos 	" 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00 02 00    ;        281- 300\n"
    420  1.1  christos 	" 01 00 06 6d 38 00 14 01 45 0c 52 4f 4f 54 2d 53 45 52 56 45    ;        301- 320\n"
    421  1.1  christos 	" 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14 01 46    ;        321- 340\n"
    422  1.1  christos 	" 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 00    ;        341- 360\n"
    423  1.1  christos 	" 02 00 01 00 06 6d 38 00 14 01 47 0c 52 4f 4f 54 2d 53 45 52    ;        361- 380\n"
    424  1.1  christos 	" 56 45 52 53 03 4e 45 54 00 00 00 02 00 01 00 06 6d 38 00 14    ;        381- 400\n"
    425  1.1  christos 	" 01 48 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00    ;        401- 420\n"
    426  1.1  christos 	" 01 41 0c 52 4f 4f 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00    ;        421- 440\n"
    427  1.1  christos 	" 00 01 00 01 00 02 64 b9 00 04 c6 29 00 04 01 4a 0c 52 4f 4f    ;        441- 460\n"
    428  1.1  christos 	" 54 2d 53 45 52 56 45 52 53 03 4e 45 54 00 00 01 00 01 00 02    ;        461- 480\n"
    429  1.1  christos 	" 64 b9 00 04 c0 3a 80 1e  ");
    430  1.1  christos 
    431  1.1  christos 	/* root delegation from unbound trace with new AAAA glue */
    432  1.1  christos 	perftestpkt(pkt, alloc, out,
    433  1.1  christos 	"55BC84000001000D00000014000002000100000200010007E900001401610C726F6F742D73657276657273036E65740000000200010007E90000040162C01E00000200010007E90000040163C01E00000200010007E90000040164C01E00000200010007E90000040165C01E00000200010007E90000040166C01E00000200010007E90000040167C01E00000200010007E90000040168C01E00000200010007E90000040169C01E00000200010007E9000004016AC01E00000200010007E9000004016BC01E00000200010007E9000004016CC01E00000200010007E9000004016DC01EC01C000100010007E9000004C6290004C03B000100010007E9000004C0E44FC9C04A000100010007E9000004C021040CC059000100010007E900000480080A5AC068000100010007E9000004C0CBE60AC077000100010007E9000004C00505F1C086000100010007E9000004C0702404C095000100010007E9000004803F0235C0A4000100010007E9000004C0249411C0B3000100010007E9000004C03A801EC0C2000100010007E9000004C1000E81C0D1000100010007E9000004C707532AC0E0000100010007E9000004CA0C1B21C01C001C00010007E900001020010503BA3E00000000000000020030C077001C00010007E900001020010500002F0000000000000000000FC095001C00010007E90000102001050000010000"
    434  1.1  christos 	"00000000803F0235C0B3001C00010007E9000010200105030C2700000000000000020030C0C2001C00010007E9000010200107FD000000000000000000000001C0E0001C00010007E900001020010DC30000000000000000000000350000291000000000000000"
    435  1.1  christos 	);
    436  1.1  christos }
    437  1.1  christos 
    438  1.1  christos /** simple test of parsing, pcat file */
    439  1.1  christos static void
    440  1.1  christos testfromfile(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out,
    441  1.1  christos 	const char* fname)
    442  1.1  christos {
    443  1.1  christos 	FILE* in = fopen(fname, "r");
    444  1.1  christos 	char buf[102400];
    445  1.1  christos 	int no=0;
    446  1.1  christos 	if(!in) {
    447  1.1  christos 		perror("fname");
    448  1.1  christos 		return;
    449  1.1  christos 	}
    450  1.1  christos 	while(fgets(buf, (int)sizeof(buf), in)) {
    451  1.1  christos 		if(buf[0] == ';') /* comment */
    452  1.1  christos 			continue;
    453  1.1  christos 		if(strlen(buf) < 10) /* skip pcat line numbers. */
    454  1.1  christos 			continue;
    455  1.1  christos 		if(vbmp) {
    456  1.1  christos 			printf("test no %d: %s", no, buf);
    457  1.1  christos 			fflush(stdout);
    458  1.1  christos 		}
    459  1.1  christos 		testpkt(pkt, alloc, out, buf);
    460  1.1  christos 		no++;
    461  1.1  christos 	}
    462  1.1  christos 	fclose(in);
    463  1.1  christos }
    464  1.1  christos 
    465  1.1  christos /** simple test of parsing, drill file */
    466  1.1  christos static void
    467  1.1  christos testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
    468  1.1  christos 	sldns_buffer* out, const char* fname)
    469  1.1  christos {
    470  1.1  christos 	/*  ;-- is used to indicate a new message */
    471  1.1  christos 	FILE* in = fopen(fname, "r");
    472  1.1  christos 	char buf[102400];
    473  1.1  christos 	char* np = buf;
    474  1.1  christos 	buf[0]=0;
    475  1.1  christos 	if(!in) {
    476  1.1  christos 		perror("fname");
    477  1.1  christos 		return;
    478  1.1  christos 	}
    479  1.1  christos 	while(fgets(np, (int)sizeof(buf) - (np-buf), in)) {
    480  1.1  christos 		if(strncmp(np, ";--", 3) == 0) {
    481  1.1  christos 			/* new entry */
    482  1.1  christos 			/* test previous */
    483  1.1  christos 			if(np != buf)
    484  1.1  christos 				testpkt(pkt, alloc, out, buf);
    485  1.1  christos 			/* set for new entry */
    486  1.1  christos 			np = buf;
    487  1.1  christos 			buf[0]=0;
    488  1.1  christos 			continue;
    489  1.1  christos 		}
    490  1.1  christos 		if(np[0] == ';') /* comment */
    491  1.1  christos 			continue;
    492  1.1  christos 		np = &np[strlen(np)];
    493  1.1  christos 	}
    494  1.1  christos 	testpkt(pkt, alloc, out, buf);
    495  1.1  christos 	fclose(in);
    496  1.1  christos }
    497  1.1  christos 
    498  1.1  christos void msgparse_test(void)
    499  1.1  christos {
    500  1.1  christos 	time_t origttl = MAX_NEG_TTL;
    501  1.1  christos 	sldns_buffer* pkt = sldns_buffer_new(65553);
    502  1.1  christos 	sldns_buffer* out = sldns_buffer_new(65553);
    503  1.1  christos 	struct alloc_cache super_a, alloc;
    504  1.1  christos 	MAX_NEG_TTL = 86400;
    505  1.1  christos 	/* init */
    506  1.1  christos 	alloc_init(&super_a, NULL, 0);
    507  1.1  christos 	alloc_init(&alloc, &super_a, 2);
    508  1.1  christos 
    509  1.1  christos 	unit_show_feature("message parse");
    510  1.1  christos 	simpletest(pkt, &alloc, out);
    511  1.1  christos 	/* plain hex dumps, like pcat */
    512  1.1  christos 	testfromfile(pkt, &alloc, out, "testdata/test_packets.1");
    513  1.1  christos 	testfromfile(pkt, &alloc, out, "testdata/test_packets.2");
    514  1.1  christos 	testfromfile(pkt, &alloc, out, "testdata/test_packets.3");
    515  1.1  christos 	/* like from drill -w - */
    516  1.1  christos 	testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.4");
    517  1.1  christos 	testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.5");
    518  1.1  christos 
    519  1.1  christos 	matches_nolocation = 1; /* RR order not important for the next test */
    520  1.1  christos 	testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6");
    521  1.1  christos 	check_rrsigs = 1;
    522  1.1  christos 	testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7");
    523  1.1  christos 	check_rrsigs = 0;
    524  1.1  christos 	matches_nolocation = 0;
    525  1.1  christos 
    526  1.1  christos 	check_formerr_gone = 1;
    527  1.1  christos 	testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8");
    528  1.1  christos 	check_formerr_gone = 0;
    529  1.1  christos 
    530  1.1  christos 	check_rrsigs = 1;
    531  1.1  christos 	check_nosameness = 1;
    532  1.1  christos 	testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.9");
    533  1.1  christos 	check_nosameness = 0;
    534  1.1  christos 	check_rrsigs = 0;
    535  1.1  christos 
    536  1.1  christos 	/* cleanup */
    537  1.1  christos 	alloc_clear(&alloc);
    538  1.1  christos 	alloc_clear(&super_a);
    539  1.1  christos 	sldns_buffer_free(pkt);
    540  1.1  christos 	sldns_buffer_free(out);
    541  1.1  christos 	MAX_NEG_TTL = origttl;
    542  1.1  christos }
    543