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