Home | History | Annotate | Line # | Download | only in testcode
      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.1.4  christos 		matches_nolocation, 0));
    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.1.3  christos 			r2, 65535, (int)(edns->bits & EDNS_DO), 0);
    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.1.3  christos 			region, 65535, (int)(edns.bits & EDNS_DO), 0);
    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.1.3  christos 				(int)(edns.bits & EDNS_DO), 0);
    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.1.2  christos #define xstr(s) str(s)
    499  1.1.1.2  christos #define str(s) #s
    500  1.1.1.2  christos 
    501  1.1.1.2  christos #define SRCDIRSTR xstr(SRCDIR)
    502  1.1.1.2  christos 
    503      1.1  christos void msgparse_test(void)
    504      1.1  christos {
    505      1.1  christos 	time_t origttl = MAX_NEG_TTL;
    506      1.1  christos 	sldns_buffer* pkt = sldns_buffer_new(65553);
    507      1.1  christos 	sldns_buffer* out = sldns_buffer_new(65553);
    508      1.1  christos 	struct alloc_cache super_a, alloc;
    509      1.1  christos 	MAX_NEG_TTL = 86400;
    510      1.1  christos 	/* init */
    511      1.1  christos 	alloc_init(&super_a, NULL, 0);
    512      1.1  christos 	alloc_init(&alloc, &super_a, 2);
    513      1.1  christos 
    514      1.1  christos 	unit_show_feature("message parse");
    515      1.1  christos 	simpletest(pkt, &alloc, out);
    516      1.1  christos 	/* plain hex dumps, like pcat */
    517  1.1.1.2  christos 	testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.1");
    518  1.1.1.2  christos 	testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.2");
    519  1.1.1.2  christos 	testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.3");
    520      1.1  christos 	/* like from drill -w - */
    521  1.1.1.2  christos 	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.4");
    522  1.1.1.2  christos 	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.5");
    523      1.1  christos 
    524      1.1  christos 	matches_nolocation = 1; /* RR order not important for the next test */
    525  1.1.1.2  christos 	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.6");
    526      1.1  christos 	check_rrsigs = 1;
    527  1.1.1.2  christos 	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.7");
    528      1.1  christos 	check_rrsigs = 0;
    529      1.1  christos 	matches_nolocation = 0;
    530      1.1  christos 
    531      1.1  christos 	check_formerr_gone = 1;
    532  1.1.1.2  christos 	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.8");
    533      1.1  christos 	check_formerr_gone = 0;
    534      1.1  christos 
    535      1.1  christos 	check_rrsigs = 1;
    536      1.1  christos 	check_nosameness = 1;
    537  1.1.1.2  christos 	testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.9");
    538      1.1  christos 	check_nosameness = 0;
    539      1.1  christos 	check_rrsigs = 0;
    540      1.1  christos 
    541      1.1  christos 	/* cleanup */
    542      1.1  christos 	alloc_clear(&alloc);
    543      1.1  christos 	alloc_clear(&super_a);
    544      1.1  christos 	sldns_buffer_free(pkt);
    545      1.1  christos 	sldns_buffer_free(out);
    546      1.1  christos 	MAX_NEG_TTL = origttl;
    547      1.1  christos }
    548