1/*
2 * testcode/unitdname.c - unit test for dname routines.
3 *
4 * Copyright (c) 2007, 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 * Calls dname unit tests. Exits with code 1 on a failure.
39 */
40
41#include "config.h"
42#include "util/log.h"
43#include "testcode/unitmain.h"
44#include "util/data/dname.h"
45#include "sldns/sbuffer.h"
46#include "sldns/str2wire.h"
47
48/** put dname into buffer */
49static sldns_buffer*
50dname_to_buf(sldns_buffer* b, const char* str)
51{
52	int e;
53	size_t len = sldns_buffer_capacity(b);
54	sldns_buffer_clear(b);
55	e = sldns_str2wire_dname_buf(str, sldns_buffer_begin(b), &len);
56	if(e != 0)
57		fatal_exit("%s ldns: %s", __func__,
58			sldns_get_errorstr_parse(e));
59	sldns_buffer_set_position(b, len);
60	sldns_buffer_flip(b);
61	return b;
62}
63
64/** test query_dname_len function */
65static void
66dname_test_qdl(sldns_buffer* buff)
67{
68	unit_show_func("util/data/dname.c", "query_dname_len");
69	unit_assert( query_dname_len(buff) == 0);
70	unit_assert( query_dname_len(dname_to_buf(buff, ".")) == 1 );
71	unit_assert( query_dname_len(dname_to_buf(buff, "bla.foo.")) == 9 );
72	unit_assert( query_dname_len(dname_to_buf(buff, "x.y.z.example.com."
73		)) == 19 );
74}
75
76/** test query_dname_tolower */
77static void
78dname_test_qdtl(sldns_buffer* buff)
79{
80	unit_show_func("util/data/dname.c", "query_dname_tolower");
81	sldns_buffer_write_at(buff, 0, "\012abCDeaBCde\003cOm\000", 16);
82	query_dname_tolower(sldns_buffer_begin(buff));
83	unit_assert( memcmp(sldns_buffer_begin(buff),
84		"\012abcdeabcde\003com\000", 16) == 0);
85
86	sldns_buffer_write_at(buff, 0, "\001+\012abC{e-ZYXe\003NET\000", 18);
87	query_dname_tolower(sldns_buffer_begin(buff));
88	unit_assert( memcmp(sldns_buffer_begin(buff),
89		"\001+\012abc{e-zyxe\003net\000", 18) == 0);
90
91	sldns_buffer_write_at(buff, 0, "\000", 1);
92	query_dname_tolower(sldns_buffer_begin(buff));
93	unit_assert( memcmp(sldns_buffer_begin(buff), "\000", 1) == 0);
94
95	sldns_buffer_write_at(buff, 0, "\002NL\000", 4);
96	query_dname_tolower(sldns_buffer_begin(buff));
97	unit_assert( memcmp(sldns_buffer_begin(buff), "\002nl\000", 4) == 0);
98}
99
100/** test query_dname_compare */
101static void
102dname_test_query_dname_compare(void)
103{
104	unit_show_func("util/data/dname.c", "query_dname_compare");
105	unit_assert(query_dname_compare((uint8_t*)"", (uint8_t*)"") == 0);
106	unit_assert(query_dname_compare((uint8_t*)"\001a",
107					(uint8_t*)"\001a") == 0);
108	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
109					(uint8_t*)"\003abc\001a") == 0);
110	unit_assert(query_dname_compare((uint8_t*)"\003aBc\001a",
111					(uint8_t*)"\003AbC\001A") == 0);
112	unit_assert(query_dname_compare((uint8_t*)"\003abc",
113					(uint8_t*)"\003abc\001a") == -1);
114	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
115					(uint8_t*)"\003abc") == +1);
116	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
117					(uint8_t*)"") == +1);
118	unit_assert(query_dname_compare((uint8_t*)"",
119					(uint8_t*)"\003abc\001a") == -1);
120	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
121					(uint8_t*)"\003xxx\001a") == -1);
122	unit_assert(query_dname_compare((uint8_t*)"\003axx\001a",
123					(uint8_t*)"\003abc\001a") == 1);
124	unit_assert(query_dname_compare((uint8_t*)"\003abc\001a",
125					(uint8_t*)"\003abc\001Z") == -1);
126	unit_assert(query_dname_compare((uint8_t*)"\003abc\001Z",
127					(uint8_t*)"\003abc\001a") == 1);
128}
129
130/** test dname_count_labels */
131static void
132dname_test_count_labels(void)
133{
134	unit_show_func("util/data/dname.c", "dname_count_labels");
135	unit_assert(dname_count_labels((uint8_t*)"") == 1);
136	unit_assert(dname_count_labels((uint8_t*)"\003com") == 2);
137	unit_assert(dname_count_labels((uint8_t*)"\003org") == 2);
138	unit_assert(dname_count_labels((uint8_t*)"\007example\003com") == 3);
139	unit_assert(dname_count_labels((uint8_t*)"\003bla\007example\003com")
140		== 4);
141}
142
143/** test dname_count_size_labels */
144static void
145dname_test_count_size_labels(void)
146{
147	size_t sz = 0;
148	unit_show_func("util/data/dname.c", "dname_count_size_labels");
149	unit_assert(dname_count_size_labels((uint8_t*)"", &sz) == 1);
150	unit_assert(sz == 1);
151	unit_assert(dname_count_size_labels((uint8_t*)"\003com", &sz) == 2);
152	unit_assert(sz == 5);
153	unit_assert(dname_count_size_labels((uint8_t*)"\003org", &sz) == 2);
154	unit_assert(sz == 5);
155	unit_assert(dname_count_size_labels((uint8_t*)"\007example\003com",
156		&sz) == 3);
157	unit_assert(sz == 13);
158	unit_assert(dname_count_size_labels((uint8_t*)"\003bla\007example"
159		"\003com", &sz) == 4);
160	unit_assert(sz == 17);
161}
162
163
164/** test pkt_dname_len */
165static void
166dname_test_pkt_dname_len(sldns_buffer* buff)
167{
168	unit_show_func("util/data/dname.c", "pkt_dname_len");
169	sldns_buffer_clear(buff);
170	sldns_buffer_write(buff, "\000", 1);
171	sldns_buffer_flip(buff);
172	unit_assert( pkt_dname_len(buff) == 1 );
173	unit_assert( sldns_buffer_position(buff) == 1);
174
175	sldns_buffer_clear(buff);
176	sldns_buffer_write(buff, "\003org\000", 5);
177	sldns_buffer_flip(buff);
178	unit_assert( pkt_dname_len(buff) == 5 );
179	unit_assert( sldns_buffer_position(buff) == 5);
180
181	sldns_buffer_clear(buff);
182	sldns_buffer_write(buff, "\002os\007example\003org\000", 16);
183	sldns_buffer_flip(buff);
184	unit_assert( pkt_dname_len(buff) == 16 );
185	unit_assert( sldns_buffer_position(buff) == 16);
186
187	/* invalid compression pointer: to self */
188	sldns_buffer_clear(buff);
189	sldns_buffer_write(buff, "\300\000os\007example\003org\000", 17);
190	sldns_buffer_flip(buff);
191	unit_assert( pkt_dname_len(buff) == 0 );
192
193	/* valid compression pointer */
194	sldns_buffer_clear(buff);
195	sldns_buffer_write(buff, "\003com\000\040\300\000", 8);
196	sldns_buffer_flip(buff);
197	sldns_buffer_set_position(buff, 6);
198	unit_assert( pkt_dname_len(buff) == 5 );
199	unit_assert( sldns_buffer_position(buff) == 8);
200
201	/* unknown label type */
202	sldns_buffer_clear(buff);
203	sldns_buffer_write(buff, "\002os\107example\003org\000", 16);
204	sldns_buffer_flip(buff);
205	unit_assert( pkt_dname_len(buff) == 0 );
206
207	/* label too long */
208	sldns_buffer_clear(buff);
209	sldns_buffer_write(buff, "\002os\047example\003org\000", 16);
210	sldns_buffer_flip(buff);
211	unit_assert( pkt_dname_len(buff) == 0 );
212
213	/* label exceeds packet */
214	sldns_buffer_clear(buff);
215	sldns_buffer_write(buff, "\002os\007example\007org\004", 16);
216	sldns_buffer_flip(buff);
217	unit_assert( pkt_dname_len(buff) == 0 );
218
219	/* name very long */
220	sldns_buffer_clear(buff);
221	sldns_buffer_write(buff,
222		"\020a1cdef5555544444"
223		"\020a2cdef5555544444"
224		"\020a3cdef5555544444"
225		"\020a4cdef5555544444"
226		"\020a5cdef5555544444"
227		"\020a6cdef5555544444"
228		"\020a7cdef5555544444"
229		"\020a8cdef5555544444"
230		"\020a9cdef5555544444"
231		"\020aAcdef5555544444"
232		"\020aBcdef5555544444"
233		"\020aCcdef5555544444"
234		"\020aDcdef5555544444"
235		"\020aEcdef5555544444"	/* 238 up to here */
236		"\007aabbccd"		/* 246 up to here */
237		"\007example\000"	/* 255 to here */
238		, 255);
239	sldns_buffer_flip(buff);
240	unit_assert( pkt_dname_len(buff) == 255 );
241	unit_assert( sldns_buffer_position(buff) == 255);
242
243	/* name too long */
244	sldns_buffer_clear(buff);
245	sldns_buffer_write(buff,
246		"\020a1cdef5555544444"
247		"\020a2cdef5555544444"
248		"\020a3cdef5555544444"
249		"\020a4cdef5555544444"
250		"\020a5cdef5555544444"
251		"\020a6cdef5555544444"
252		"\020a7cdef5555544444"
253		"\020a8cdef5555544444"
254		"\020a9cdef5555544444"
255		"\020aAcdef5555544444"
256		"\020aBcdef5555544444"
257		"\020aCcdef5555544444"
258		"\020aXcdef5555544444"
259		"\020aXcdef5555544444"
260		"\020aXcdef5555544444"
261		"\020aDcdef5555544444"
262		"\020aEcdef5555544444"	/* 238 up to here */
263		"\007aabbccd"		/* 246 up to here */
264		"\007example\000"	/* 255 to here */
265		, 255);
266	sldns_buffer_flip(buff);
267	unit_assert( pkt_dname_len(buff) == 0 );
268}
269
270/** test dname_lab_cmp */
271static void
272dname_test_dname_lab_cmp(void)
273{
274	int ml = 0; /* number of labels that matched exactly */
275	unit_show_func("util/data/dname.c", "dname_lab_cmp");
276
277	/* test for equality succeeds */
278	unit_assert(dname_lab_cmp((uint8_t*)"", 1, (uint8_t*)"", 1, &ml) == 0);
279	unit_assert(ml == 1);
280	unit_assert(dname_lab_cmp(
281		(uint8_t*)"\003net", 2,
282		(uint8_t*)"\003net", 2,
283		&ml) == 0);
284	unit_assert(ml == 2);
285	unit_assert(dname_lab_cmp(
286		(uint8_t*)"\007example\003net", 3,
287		(uint8_t*)"\007example\003net", 3,
288		&ml) == 0);
289	unit_assert(ml == 3);
290	unit_assert(dname_lab_cmp(
291		(uint8_t*)"\004test\007example\003net", 4,
292		(uint8_t*)"\004test\007example\003net", 4,
293		&ml) == 0);
294	unit_assert(ml == 4);
295
296	/* root is smaller than anything else */
297	unit_assert(dname_lab_cmp(
298		(uint8_t*)"", 1,
299		(uint8_t*)"\003net", 2,
300		&ml) == -1);
301	unit_assert(ml == 1);
302	unit_assert(dname_lab_cmp(
303		(uint8_t*)"\003net", 2,
304		(uint8_t*)"", 1,
305		&ml) == 1);
306	unit_assert(ml == 1);
307	unit_assert(dname_lab_cmp(
308		(uint8_t*)"", 1,
309		(uint8_t*)"\007example\003net", 3,
310		&ml) == -1);
311	unit_assert(ml == 1);
312	unit_assert(dname_lab_cmp(
313		(uint8_t*)"\007example\003net", 3,
314		(uint8_t*)"", 1,
315		&ml) == 1);
316	unit_assert(ml == 1);
317
318	/* label length makes a difference */
319	unit_assert(dname_lab_cmp(
320		(uint8_t*)"\004neta", 2,
321		(uint8_t*)"\003net", 2,
322		&ml) != 0);
323	unit_assert(ml == 1);
324	unit_assert(dname_lab_cmp(
325		(uint8_t*)"\002ne", 2,
326		(uint8_t*)"\004neta", 2,
327		&ml) != 0);
328	unit_assert(ml == 1);
329
330	/* contents follow the zone apex */
331	unit_assert(dname_lab_cmp(
332		(uint8_t*)"\003bla\007example\003net", 4,
333		(uint8_t*)"\007example\003net", 3,
334		&ml) == 1);
335	unit_assert(ml == 3);
336	unit_assert(dname_lab_cmp(
337		(uint8_t*)"\007example\003net", 3,
338		(uint8_t*)"\003bla\007example\003net", 4,
339		&ml) == -1);
340	unit_assert(ml == 3);
341
342	/* label content makes a difference */
343	unit_assert(dname_lab_cmp(
344		(uint8_t*)"\003aag\007example\003net", 4,
345		(uint8_t*)"\003bla\007example\003net", 4,
346		&ml) == -1);
347	unit_assert(ml == 3);
348	unit_assert(dname_lab_cmp(
349		(uint8_t*)"\003aag\007example\003net", 4,
350		(uint8_t*)"\003bla\007example\003net", 4,
351		&ml) == -1);
352	unit_assert(ml == 3);
353	unit_assert(dname_lab_cmp(
354		(uint8_t*)"\003bla\003aag\007example\003net", 5,
355		(uint8_t*)"\003aag\003bla\007example\003net", 5,
356		&ml) == -1);
357	unit_assert(ml == 3);
358	unit_assert(dname_lab_cmp(
359		(uint8_t*)"\02sn\003opt\003aag\007example\003net", 6,
360		(uint8_t*)"\02sn\003opt\003bla\007example\003net", 6,
361		&ml) == -1);
362	unit_assert(ml == 3);
363
364	/* but lowercase/uppercase does not make a difference. */
365	unit_assert(dname_lab_cmp(
366		(uint8_t*)"\003bLa\007examPLe\003net", 4,
367		(uint8_t*)"\003bla\007eXAmple\003nET", 4,
368		&ml) == 0);
369	unit_assert(ml == 4);
370}
371
372/** test dname_subdomain_c */
373static void
374dname_test_subdomain(void)
375{
376	unit_show_func("util/data/dname.c", "dname_subdomain");
377	unit_assert(dname_subdomain_c(
378		(uint8_t*)"",
379		(uint8_t*)""));
380	unit_assert(dname_subdomain_c(
381		(uint8_t*)"\003com",
382		(uint8_t*)""));
383	unit_assert(!dname_subdomain_c(
384		(uint8_t*)"",
385		(uint8_t*)"\003com"));
386	unit_assert(dname_subdomain_c(
387		(uint8_t*)"\007example\003com",
388		(uint8_t*)"\003com"));
389	unit_assert(!dname_subdomain_c(
390		(uint8_t*)"\003com",
391		(uint8_t*)"\007example\003com"));
392	unit_assert(dname_subdomain_c(
393		(uint8_t*)"\007example\003com",
394		(uint8_t*)""));
395	unit_assert(!dname_subdomain_c(
396		(uint8_t*)"\003net",
397		(uint8_t*)"\003com"));
398	unit_assert(!dname_subdomain_c(
399		(uint8_t*)"\003net",
400		(uint8_t*)"\003org"));
401	unit_assert(!dname_subdomain_c(
402		(uint8_t*)"\007example\003net",
403		(uint8_t*)"\003org"));
404	unit_assert(!dname_subdomain_c(
405		(uint8_t*)"\003net",
406		(uint8_t*)"\007example\003org"));
407}
408
409/** test dname_strict_subdomain */
410static void
411dname_test_strict_subdomain(void)
412{
413	unit_show_func("util/data/dname.c", "dname_strict_subdomain");
414	unit_assert(!dname_strict_subdomain(
415		(uint8_t*)"", 1,
416		(uint8_t*)"", 1));
417	unit_assert(dname_strict_subdomain(
418		(uint8_t*)"\003com", 2,
419		(uint8_t*)"", 1));
420	unit_assert(!dname_strict_subdomain(
421		(uint8_t*)"", 1,
422		(uint8_t*)"\003com", 2));
423	unit_assert(dname_strict_subdomain(
424		(uint8_t*)"\007example\003com", 3,
425		(uint8_t*)"\003com", 2));
426	unit_assert(!dname_strict_subdomain(
427		(uint8_t*)"\003com", 2,
428		(uint8_t*)"\007example\003com", 3));
429	unit_assert(dname_strict_subdomain(
430		(uint8_t*)"\007example\003com", 3,
431		(uint8_t*)"", 1));
432	unit_assert(!dname_strict_subdomain(
433		(uint8_t*)"\003net", 2,
434		(uint8_t*)"\003com", 2));
435	unit_assert(!dname_strict_subdomain(
436		(uint8_t*)"\003net", 2,
437		(uint8_t*)"\003org", 2));
438	unit_assert(!dname_strict_subdomain(
439		(uint8_t*)"\007example\003net", 3,
440		(uint8_t*)"\003org", 2));
441	unit_assert(!dname_strict_subdomain(
442		(uint8_t*)"\003net", 2,
443		(uint8_t*)"\007example\003org", 3));
444}
445
446/** test dname_is_root */
447static void
448dname_test_isroot(void)
449{
450	unit_show_func("util/data/dname.c", "dname_isroot");
451	unit_assert(dname_is_root((uint8_t*)"\000"));
452	unit_assert(!dname_is_root((uint8_t*)"\001a\000"));
453	unit_assert(!dname_is_root((uint8_t*)"\005abvcd\003com\000"));
454	/* malformed dname in this test, but should work */
455	unit_assert(!dname_is_root((uint8_t*)"\077a\000"));
456	unit_assert(dname_is_root((uint8_t*)"\000"));
457}
458
459/** test dname_remove_label */
460static void
461dname_test_removelabel(void)
462{
463	uint8_t* orig = (uint8_t*)"\007example\003com\000";
464	uint8_t* n = orig;
465	size_t l = 13;
466	unit_show_func("util/data/dname.c", "dname_remove_label");
467	dname_remove_label(&n, &l);
468	unit_assert( n == orig+8 );
469	unit_assert( l == 5 );
470	dname_remove_label(&n, &l);
471	unit_assert( n == orig+12 );
472	unit_assert( l == 1 );
473	dname_remove_label(&n, &l);
474	unit_assert( n == orig+12 );
475	unit_assert( l == 1 );
476}
477
478/** test dname_signame_label_count */
479static void
480dname_test_sigcount(void)
481{
482	unit_show_func("util/data/dname.c", "dname_signame_label_count");
483	unit_assert(dname_signame_label_count((uint8_t*)"\000") == 0);
484	unit_assert(dname_signame_label_count((uint8_t*)"\001*\000") == 0);
485	unit_assert(dname_signame_label_count((uint8_t*)"\003xom\000") == 1);
486	unit_assert(dname_signame_label_count(
487		(uint8_t*)"\001*\003xom\000") == 1);
488	unit_assert(dname_signame_label_count(
489		(uint8_t*)"\007example\003xom\000") == 2);
490	unit_assert(dname_signame_label_count(
491		(uint8_t*)"\001*\007example\003xom\000") == 2);
492	unit_assert(dname_signame_label_count(
493		(uint8_t*)"\003www\007example\003xom\000") == 3);
494	unit_assert(dname_signame_label_count(
495		(uint8_t*)"\001*\003www\007example\003xom\000") == 3);
496}
497
498/** test dname_is_wild routine */
499static void
500dname_test_iswild(void)
501{
502	unit_show_func("util/data/dname.c", "dname_iswild");
503	unit_assert( !dname_is_wild((uint8_t*)"\000") );
504	unit_assert( dname_is_wild((uint8_t*)"\001*\000") );
505	unit_assert( !dname_is_wild((uint8_t*)"\003net\000") );
506	unit_assert( dname_is_wild((uint8_t*)"\001*\003net\000") );
507}
508
509/** test dname_canonical_compare */
510static void
511dname_test_canoncmp(void)
512{
513	unit_show_func("util/data/dname.c", "dname_canonical_compare");
514	/* equality */
515	unit_assert( dname_canonical_compare(
516		(uint8_t*)"\000",
517		(uint8_t*)"\000"
518		) == 0);
519	unit_assert( dname_canonical_compare(
520		(uint8_t*)"\003net\000",
521		(uint8_t*)"\003net\000"
522		) == 0);
523	unit_assert( dname_canonical_compare(
524		(uint8_t*)"\007example\003net\000",
525		(uint8_t*)"\007example\003net\000"
526		) == 0);
527	unit_assert( dname_canonical_compare(
528		(uint8_t*)"\004test\007example\003net\000",
529		(uint8_t*)"\004test\007example\003net\000"
530		) == 0);
531
532	/* subdomains */
533	unit_assert( dname_canonical_compare(
534		(uint8_t*)"\003com",
535		(uint8_t*)"\000"
536		) == 1);
537	unit_assert( dname_canonical_compare(
538		(uint8_t*)"\000",
539		(uint8_t*)"\003com"
540		) == -1);
541	unit_assert( dname_canonical_compare(
542		(uint8_t*)"\007example\003com",
543		(uint8_t*)"\003com"
544		) == 1);
545	unit_assert( dname_canonical_compare(
546		(uint8_t*)"\003com",
547		(uint8_t*)"\007example\003com"
548		) == -1);
549	unit_assert( dname_canonical_compare(
550		(uint8_t*)"\007example\003com",
551		(uint8_t*)"\000"
552		) == 1);
553	unit_assert( dname_canonical_compare(
554		(uint8_t*)"\000",
555		(uint8_t*)"\007example\003com"
556		) == -1);
557
558	/* compare rightmost label */
559	unit_assert( dname_canonical_compare(
560		(uint8_t*)"\003com",
561		(uint8_t*)"\003net"
562		) == -1);
563	unit_assert( dname_canonical_compare(
564		(uint8_t*)"\003net",
565		(uint8_t*)"\003com"
566		) == 1);
567	unit_assert( dname_canonical_compare(
568		(uint8_t*)"\003net",
569		(uint8_t*)"\003org"
570		) == -1);
571	unit_assert( dname_canonical_compare(
572		(uint8_t*)"\007example\003net",
573		(uint8_t*)"\003org"
574		) == -1);
575	unit_assert( dname_canonical_compare(
576		(uint8_t*)"\003org",
577		(uint8_t*)"\007example\003net"
578		) == 1);
579
580	/* label length makes a difference; but only if rest is equal */
581	unit_assert( dname_canonical_compare(
582		(uint8_t*)"\004neta",
583		(uint8_t*)"\003net"
584		) == 1);
585	unit_assert( dname_canonical_compare(
586		(uint8_t*)"\002ne",
587		(uint8_t*)"\004neta"
588		) == -1);
589
590	/* label content */
591	unit_assert( dname_canonical_compare(
592		(uint8_t*)"\003aag\007example\003net",
593		(uint8_t*)"\003bla\007example\003net"
594		) == -1);
595	unit_assert( dname_canonical_compare(
596		(uint8_t*)"\003bla\007example\003net",
597		(uint8_t*)"\003aag\007example\003net"
598		) == 1);
599	unit_assert( dname_canonical_compare(
600		(uint8_t*)"\003bla\003aag\007example\003net",
601		(uint8_t*)"\003aag\003bla\007example\003net"
602		) == -1);
603	unit_assert( dname_canonical_compare(
604		(uint8_t*)"\02sn\003opt\003aag\007example\003net",
605		(uint8_t*)"\02sn\003opt\003bla\007example\003net"
606		) == -1);
607
608	/* lowercase during compare */
609	unit_assert( dname_canonical_compare(
610		(uint8_t*)"\003bLa\007examPLe\003net",
611		(uint8_t*)"\003bla\007eXAmple\003nET"
612		) == 0);
613
614	/* example from 4034 */
615	/* example a.example yljkjljk.a.example Z.a.example zABC.a.EXAMPLE
616	 z.example \001.z.example *.z.example \200.z.example */
617	unit_assert( dname_canonical_compare(
618		(uint8_t*)"",
619		(uint8_t*)"\007example"
620		) == -1);
621	unit_assert( dname_canonical_compare(
622		(uint8_t*)"\007example",
623		(uint8_t*)"\001a\007example"
624		) == -1);
625	unit_assert( dname_canonical_compare(
626		(uint8_t*)"\001a\007example",
627		(uint8_t*)"\010yljkjljk\001a\007example"
628		) == -1);
629	unit_assert( dname_canonical_compare(
630		(uint8_t*)"\010yljkjljk\001a\007example",
631		(uint8_t*)"\001Z\001a\007example"
632		) == -1);
633	unit_assert( dname_canonical_compare(
634		(uint8_t*)"\001Z\001a\007example",
635		(uint8_t*)"\004zABC\001a\007EXAMPLE"
636		) == -1);
637	unit_assert( dname_canonical_compare(
638		(uint8_t*)"\004zABC\001a\007EXAMPLE",
639		(uint8_t*)"\001z\007example"
640		) == -1);
641	unit_assert( dname_canonical_compare(
642		(uint8_t*)"\001z\007example",
643		(uint8_t*)"\001\001\001z\007example"
644		) == -1);
645	unit_assert( dname_canonical_compare(
646		(uint8_t*)"\001\001\001z\007example",
647		(uint8_t*)"\001*\001z\007example"
648		) == -1);
649	unit_assert( dname_canonical_compare(
650		(uint8_t*)"\001*\001z\007example",
651		(uint8_t*)"\001\200\001z\007example"
652		) == -1);
653	/* same example in reverse */
654	unit_assert( dname_canonical_compare(
655		(uint8_t*)"\007example",
656		(uint8_t*)""
657		) == 1);
658	unit_assert( dname_canonical_compare(
659		(uint8_t*)"\001a\007example",
660		(uint8_t*)"\007example"
661		) == 1);
662	unit_assert( dname_canonical_compare(
663		(uint8_t*)"\010yljkjljk\001a\007example",
664		(uint8_t*)"\001a\007example"
665		) == 1);
666	unit_assert( dname_canonical_compare(
667		(uint8_t*)"\001Z\001a\007example",
668		(uint8_t*)"\010yljkjljk\001a\007example"
669		) == 1);
670	unit_assert( dname_canonical_compare(
671		(uint8_t*)"\004zABC\001a\007EXAMPLE",
672		(uint8_t*)"\001Z\001a\007example"
673		) == 1);
674	unit_assert( dname_canonical_compare(
675		(uint8_t*)"\001z\007example",
676		(uint8_t*)"\004zABC\001a\007EXAMPLE"
677		) == 1);
678	unit_assert( dname_canonical_compare(
679		(uint8_t*)"\001\001\001z\007example",
680		(uint8_t*)"\001z\007example"
681		) == 1);
682	unit_assert( dname_canonical_compare(
683		(uint8_t*)"\001*\001z\007example",
684		(uint8_t*)"\001\001\001z\007example"
685		) == 1);
686	unit_assert( dname_canonical_compare(
687		(uint8_t*)"\001\200\001z\007example",
688		(uint8_t*)"\001*\001z\007example"
689		) == 1);
690	/* same example for equality */
691	unit_assert( dname_canonical_compare(
692		(uint8_t*)"\007example",
693		(uint8_t*)"\007example"
694		) == 0);
695	unit_assert( dname_canonical_compare(
696		(uint8_t*)"\001a\007example",
697		(uint8_t*)"\001a\007example"
698		) == 0);
699	unit_assert( dname_canonical_compare(
700		(uint8_t*)"\010yljkjljk\001a\007example",
701		(uint8_t*)"\010yljkjljk\001a\007example"
702		) == 0);
703	unit_assert( dname_canonical_compare(
704		(uint8_t*)"\001Z\001a\007example",
705		(uint8_t*)"\001Z\001a\007example"
706		) == 0);
707	unit_assert( dname_canonical_compare(
708		(uint8_t*)"\004zABC\001a\007EXAMPLE",
709		(uint8_t*)"\004zABC\001a\007EXAMPLE"
710		) == 0);
711	unit_assert( dname_canonical_compare(
712		(uint8_t*)"\001z\007example",
713		(uint8_t*)"\001z\007example"
714		) == 0);
715	unit_assert( dname_canonical_compare(
716		(uint8_t*)"\001\001\001z\007example",
717		(uint8_t*)"\001\001\001z\007example"
718		) == 0);
719	unit_assert( dname_canonical_compare(
720		(uint8_t*)"\001*\001z\007example",
721		(uint8_t*)"\001*\001z\007example"
722		) == 0);
723	unit_assert( dname_canonical_compare(
724		(uint8_t*)"\001\200\001z\007example",
725		(uint8_t*)"\001\200\001z\007example"
726		) == 0);
727}
728
729/** Test dname_get_shared_topdomain */
730static void
731dname_test_topdomain(void)
732{
733	unit_show_func("util/data/dname.c", "dname_get_shared_topdomain");
734	unit_assert( query_dname_compare(
735		dname_get_shared_topdomain(
736			(uint8_t*)"",
737			(uint8_t*)""),
738		(uint8_t*)"") == 0);
739	unit_assert( query_dname_compare(
740		dname_get_shared_topdomain(
741			(uint8_t*)"\003www\007example\003com",
742			(uint8_t*)"\003www\007example\003com"),
743		(uint8_t*)"\003www\007example\003com") == 0);
744	unit_assert( query_dname_compare(
745		dname_get_shared_topdomain(
746			(uint8_t*)"\003www\007example\003com",
747			(uint8_t*)"\003bla\007example\003com"),
748		(uint8_t*)"\007example\003com") == 0);
749}
750
751/** Test dname_valid */
752static void
753dname_test_valid(void)
754{
755	unit_show_func("util/data/dname.c", "dname_valid");
756	unit_assert( dname_valid(
757			(uint8_t*)"\003www\007example\003com", 255) == 17);
758	unit_assert( dname_valid((uint8_t*)"", 255) == 1);
759	unit_assert( dname_valid( (uint8_t*)
760		"\020a1cdef5555544444"
761		"\020a2cdef5555544444"
762		"\020a3cdef5555544444"
763		"\020a4cdef5555544444"
764		"\020a5cdef5555544444"
765		"\020a6cdef5555544444"
766		"\020a7cdef5555544444"
767		"\020a8cdef5555544444"
768		"\020a9cdef5555544444"
769		"\020aAcdef5555544444"
770		"\020aBcdef5555544444"
771		"\020aCcdef5555544444"
772		"\020aDcdef5555544444"
773		"\020aEcdef5555544444"	/* 238 up to here */
774		"\007aabbccd"		/* 246 up to here */
775		"\007example\000"	/* 255 to here */
776		, 255) == 255);
777	unit_assert( dname_valid( (uint8_t*)
778		"\020a1cdef5555544444"
779		"\020a2cdef5555544444"
780		"\020a3cdef5555544444"
781		"\020a4cdef5555544444"
782		"\020a5cdef5555544444"
783		"\020a6cdef5555544444"
784		"\020a7cdef5555544444"
785		"\020a8cdef5555544444"
786		"\020a9cdef5555544444"
787		"\020aAcdef5555544444"
788		"\020aBcdef5555544444"
789		"\020aCcdef5555544444"
790		"\020aDcdef5555544444"
791		"\020aEcdef5555544444"	/* 238 up to here */
792		"\007aabbccd"		/* 246 up to here */
793		"\010exampleX\000"	/* 256 to here */
794		, 4096) == 0);
795}
796
797/** Test dname_has_label */
798static void
799dname_test_has_label(void)
800{
801	unit_show_func("util/data/dname.c", "dname_has_label");
802	/* label past root label */
803	unit_assert(dname_has_label((uint8_t*)"\01a\0\01c", 5, (uint8_t*)"\01c") == 0);
804	/* label not found */
805	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 6, (uint8_t*)"\01e") == 0);
806	/* buffer too short */
807	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 5, (uint8_t*)"\0") == 0);
808	unit_assert(dname_has_label((uint8_t*)"\1a\0", 2, (uint8_t*)"\0") == 0);
809	unit_assert(dname_has_label((uint8_t*)"\0", 0, (uint8_t*)"\0") == 0);
810	unit_assert(dname_has_label((uint8_t*)"\02ab\01c", 4, (uint8_t*)"\01c") == 0);
811	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 19, (uint8_t*)"\01c") == 0);
812
813	/* positive cases  */
814	unit_assert(dname_has_label((uint8_t*)"\0", 1, (uint8_t*)"\0") == 1);
815	unit_assert(dname_has_label((uint8_t*)"\1a\0", 3, (uint8_t*)"\0") == 1);
816	unit_assert(dname_has_label((uint8_t*)"\01a\0\01c", 5, (uint8_t*)"\0") == 1);
817	unit_assert(dname_has_label((uint8_t*)"\02ab\01c", 5, (uint8_t*)"\01c") == 1);
818	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 10, (uint8_t*)"\0") == 1);
819	unit_assert(dname_has_label((uint8_t*)"\02ab\01c\0", 7, (uint8_t*)"\0") == 1);
820	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\03def") == 1);
821	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\02ab") == 1);
822	unit_assert(dname_has_label((uint8_t*)"\02ab\03qwe\06oqieur\03def\01c\0", 22, (uint8_t*)"\01c") == 1);
823}
824
825/** test pkt_dname_tolower */
826static void
827dname_test_pdtl(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
828{
829	unit_show_func("util/data/dname.c", "pkt_dname_tolower");
830	pkt_dname_tolower(loopbuf, sldns_buffer_at(loopbuf, 12));
831	pkt_dname_tolower(boundbuf, sldns_buffer_at(boundbuf, 12));
832}
833
834/** setup looped dname and out-of-bounds dname ptr */
835static void
836dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
837{
838	sldns_buffer_write_u16(loopbuf, 0xd54d);  /* id */
839	sldns_buffer_write_u16(loopbuf, 0x12);    /* flags  */
840	sldns_buffer_write_u16(loopbuf, 1);       /* qdcount */
841	sldns_buffer_write_u16(loopbuf, 0);       /* ancount */
842	sldns_buffer_write_u16(loopbuf, 0);       /* nscount */
843	sldns_buffer_write_u16(loopbuf, 0);       /* arcount */
844	sldns_buffer_write_u8(loopbuf, 0xc0); /* PTR back at itself */
845	sldns_buffer_write_u8(loopbuf, 0x0c);
846	sldns_buffer_flip(loopbuf);
847
848	sldns_buffer_write_u16(boundbuf, 0xd54d);  /* id */
849	sldns_buffer_write_u16(boundbuf, 0x12);    /* flags  */
850	sldns_buffer_write_u16(boundbuf, 1);       /* qdcount */
851	sldns_buffer_write_u16(boundbuf, 0);       /* ancount */
852	sldns_buffer_write_u16(boundbuf, 0);       /* nscount */
853	sldns_buffer_write_u16(boundbuf, 0);       /* arcount */
854	sldns_buffer_write_u8(boundbuf, 0x01); /* len=1 */
855	sldns_buffer_write_u8(boundbuf, (uint8_t)'A'); /* A. label */
856	sldns_buffer_write_u8(boundbuf, 0xc0); /* PTR out of bounds */
857	sldns_buffer_write_u8(boundbuf, 0xcc);
858	sldns_buffer_flip(boundbuf);
859}
860
861void dname_test(void)
862{
863	sldns_buffer* loopbuf = sldns_buffer_new(14);
864	sldns_buffer* boundbuf = sldns_buffer_new(16);
865	sldns_buffer* buff = sldns_buffer_new(65800);
866	unit_assert(loopbuf && boundbuf && buff);
867	sldns_buffer_flip(buff);
868	dname_setup_bufs(loopbuf, boundbuf);
869	dname_test_qdl(buff);
870	dname_test_qdtl(buff);
871	dname_test_pdtl(loopbuf, boundbuf);
872	dname_test_query_dname_compare();
873	dname_test_count_labels();
874	dname_test_count_size_labels();
875	dname_test_dname_lab_cmp();
876	dname_test_pkt_dname_len(buff);
877	dname_test_strict_subdomain();
878	dname_test_subdomain();
879	dname_test_isroot();
880	dname_test_removelabel();
881	dname_test_sigcount();
882	dname_test_iswild();
883	dname_test_canoncmp();
884	dname_test_topdomain();
885	dname_test_valid();
886	dname_test_has_label();
887	sldns_buffer_free(buff);
888	sldns_buffer_free(loopbuf);
889	sldns_buffer_free(boundbuf);
890}
891