Changeset 1359
- Timestamp:
- Jun 11, 2007 4:56:26 PM (17 years ago)
- Location:
- pjproject/trunk/pjlib-util/src/pjlib-util-test
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/src/pjlib-util-test/resolver_test.c
r1347 r1359 24 24 #define THIS_FILE "srv_resolver_test.c" 25 25 26 //////////////////////////////////////////////////////////////////////////// 27 /* 28 * TODO: create various invalid DNS packets. 29 */ 30 31 32 //////////////////////////////////////////////////////////////////////////// 33 34 26 35 #define ACTION_REPLY 0 27 36 #define ACTION_IGNORE -1 … … 58 67 static pj_dns_settings set; 59 68 60 static int print_label(char *start, const pj_str_t *name) 61 { 62 char *p = (char*) start; 63 const char *startlabel, *endlabel; 64 char *endname; 65 66 /* Tokenize name */ 67 startlabel = endlabel = name->ptr; 69 #define MAX_LABEL 32 70 71 struct label_tab 72 { 73 unsigned count; 74 75 struct { 76 unsigned pos; 77 pj_str_t label; 78 } a[MAX_LABEL]; 79 }; 80 81 static void write16(pj_uint8_t *p, pj_uint16_t val) 82 { 83 p[0] = (pj_uint8_t)(val >> 8); 84 p[1] = (pj_uint8_t)(val & 0xFF); 85 } 86 87 static void write32(pj_uint8_t *p, pj_uint32_t val) 88 { 89 val = pj_htonl(val); 90 pj_memcpy(p, &val, 4); 91 } 92 93 static int print_name(pj_uint8_t *pkt, int size, 94 pj_uint8_t *pos, const pj_str_t *name, 95 struct label_tab *tab) 96 { 97 pj_uint8_t *p = pos; 98 const char *endlabel, *endname; 99 unsigned i; 100 pj_str_t label; 101 102 /* Check if name is in the table */ 103 for (i=0; i<tab->count; ++i) { 104 if (pj_strcmp(&tab->a[i].label, name)==0) 105 break; 106 } 107 108 if (i != tab->count) { 109 write16(p, (pj_uint16_t)(tab->a[i].pos | (0xc0 << 8))); 110 return 2; 111 } else { 112 if (tab->count < MAX_LABEL) { 113 tab->a[tab->count].pos = (p-pkt); 114 tab->a[tab->count].label.ptr = (char*)(p+1); 115 tab->a[tab->count].label.slen = name->slen; 116 ++tab->count; 117 } 118 } 119 120 endlabel = name->ptr; 68 121 endname = name->ptr + name->slen; 122 123 label.ptr = (char*)name->ptr; 124 69 125 while (endlabel != endname) { 126 70 127 while (endlabel != endname && *endlabel != '.') 71 128 ++endlabel; 72 *p++ = (char)(endlabel - startlabel); 73 pj_memcpy(p, startlabel, endlabel-startlabel); 74 p += (endlabel-startlabel); 129 130 label.slen = (endlabel - label.ptr); 131 132 if (size < label.slen+1) 133 return -1; 134 135 *p = (pj_uint8_t)label.slen; 136 pj_memcpy(p+1, label.ptr, label.slen); 137 138 size -= (label.slen+1); 139 p += (label.slen+1); 140 75 141 if (endlabel != endname && *endlabel == '.') 76 142 ++endlabel; 77 startlabel = endlabel; 78 } 143 label.ptr = (char*)endlabel; 144 } 145 146 if (size == 0) 147 return -1; 148 79 149 *p++ = '\0'; 80 150 81 return p-start; 82 } 83 84 static int print_packet(const pj_dns_parsed_packet *rec, char *packet) 85 { 86 pj_dns_hdr *hdr; 87 char *p; 151 return p-pos; 152 } 153 154 static int print_rr(pj_uint8_t *pkt, int size, pj_uint8_t *pos, 155 const pj_dns_parsed_rr *rr, struct label_tab *tab) 156 { 157 pj_uint8_t *p = pos; 158 int len; 159 160 len = print_name(pkt, size, pos, &rr->name, tab); 161 if (len < 0) 162 return -1; 163 164 p += len; 165 size -= len; 166 167 if (size < 8) 168 return -1; 169 170 pj_assert(rr->dnsclass == 1); 171 172 write16(p+0, (pj_uint16_t)rr->type); /* type */ 173 write16(p+2, (pj_uint16_t)rr->dnsclass); /* class */ 174 write32(p+4, rr->ttl); /* TTL */ 175 176 p += 8; 177 size -= 8; 178 179 if (rr->type == PJ_DNS_TYPE_A) { 180 181 if (size < 6) 182 return -1; 183 184 /* RDLEN is 4 */ 185 write16(p, 4); 186 187 /* Address */ 188 pj_memcpy(p+2, &rr->rdata.a.ip_addr, 4); 189 190 p += 6; 191 size -= 6; 192 193 } else if (rr->type == PJ_DNS_TYPE_CNAME || 194 rr->type == PJ_DNS_TYPE_NS || 195 rr->type == PJ_DNS_TYPE_PTR) { 196 197 if (size < 4) 198 return -1; 199 200 len = print_name(pkt, size-2, p+2, &rr->rdata.cname.name, tab); 201 if (len < 0) 202 return -1; 203 204 write16(p, (pj_uint16_t)len); 205 206 p += (len + 2); 207 size -= (len + 2); 208 209 } else if (rr->type == PJ_DNS_TYPE_SRV) { 210 211 if (size < 10) 212 return -1; 213 214 write16(p+2, rr->rdata.srv.prio); /* Priority */ 215 write16(p+4, rr->rdata.srv.weight); /* Weight */ 216 write16(p+6, rr->rdata.srv.port); /* Port */ 217 218 /* Target */ 219 len = print_name(pkt, size-8, p+8, &rr->rdata.srv.target, tab); 220 if (len < 0) 221 return -1; 222 223 /* RDLEN */ 224 write16(p, (pj_uint16_t)(len + 6)); 225 226 p += (len + 8); 227 size -= (len + 8); 228 229 } else { 230 pj_assert(!"Not supported"); 231 return -1; 232 } 233 234 return p-pos; 235 } 236 237 static int print_packet(const pj_dns_parsed_packet *rec, pj_uint8_t *pkt, 238 int size) 239 { 240 pj_uint8_t *p = pkt; 241 struct label_tab tab; 88 242 int i, len; 89 243 244 tab.count = 0; 245 246 #if 0 247 pj_enter_critical_section(); 248 PJ_LOG(3,(THIS_FILE, "Sending response:")); 249 pj_dns_dump_packet(rec); 250 pj_leave_critical_section(); 251 #endif 252 253 pj_assert(sizeof(pj_dns_hdr)==12); 254 if (size < sizeof(pj_dns_hdr)) 255 return -1; 256 90 257 /* Initialize header */ 91 hdr = (pj_dns_hdr*) packet; 92 pj_bzero(hdr, sizeof(pj_dns_hdr)); 93 hdr->id = pj_htons(rec->hdr.id); 94 hdr->flags = pj_htons(rec->hdr.flags); 95 hdr->qdcount = pj_htons(rec->hdr.qdcount); 96 hdr->anscount = pj_htons(rec->hdr.anscount); 97 hdr->nscount = pj_htons(rec->hdr.nscount); 98 hdr->arcount = pj_htons(rec->hdr.arcount); 99 100 p = packet + sizeof(pj_dns_hdr); 258 write16(p+0, rec->hdr.id); 259 write16(p+2, rec->hdr.flags); 260 write16(p+4, rec->hdr.qdcount); 261 write16(p+6, rec->hdr.anscount); 262 write16(p+8, rec->hdr.nscount); 263 write16(p+10, rec->hdr.arcount); 264 265 p = pkt + sizeof(pj_dns_hdr); 266 size -= sizeof(pj_dns_hdr); 101 267 102 268 /* Print queries */ 103 269 for (i=0; i<rec->hdr.qdcount; ++i) { 104 pj_uint16_t tmp; 105 106 len = print_label(p, &rec->q[i].name); 270 271 len = print_name(pkt, size, p, &rec->q[i].name, &tab); 272 if (len < 0) 273 return -1; 274 107 275 p += len; 276 size -= len; 277 278 if (size < 4) 279 return -1; 108 280 109 281 /* Set type */ 110 tmp = pj_htons((pj_uint16_t)rec->q[i].type); 111 pj_memcpy(p, &tmp, 2); 112 p += 2; 282 write16(p+0, (pj_uint16_t)rec->q[i].type); 113 283 114 284 /* Set class (IN=1) */ 115 tmp = pj_htons(rec->q[i].dnsclass); 116 pj_memcpy(p, &tmp, 2); 117 p += 2; 285 pj_assert(rec->q[i].dnsclass == 1); 286 write16(p+2, rec->q[i].dnsclass); 287 288 p += 4; 118 289 } 119 290 120 291 /* Print answers */ 121 292 for (i=0; i<rec->hdr.anscount; ++i) { 122 const pj_dns_parsed_rr *rr = &rec->ans[i]; 123 pj_uint16_t tmp; 124 pj_uint32_t ttl; 125 126 len = print_label(p, &rr->name); 293 len = print_rr(pkt, size, p, &rec->ans[i], &tab); 294 if (len < 0) 295 return -1; 296 127 297 p += len; 128 129 /* Set type */ 130 tmp = pj_htons((pj_uint16_t)rr->type); 131 pj_memcpy(p, &tmp, 2); 132 p += 2; 133 134 /* Set class */ 135 tmp = pj_htons((pj_uint16_t)rr->dnsclass); 136 pj_memcpy(p, &tmp, 2); 137 p += 2; 138 139 /* Set TTL */ 140 ttl = pj_htonl(rr->ttl); 141 pj_memcpy(p, &ttl, 4); 142 p += 4; 143 144 if (rr->type == PJ_DNS_TYPE_A) { 145 146 /* RDLEN is 4 */ 147 tmp = pj_htons(4); 148 pj_memcpy(p, &tmp, 2); 149 p += 2; 150 151 /* Address */ 152 pj_memcpy(p, &rr->rdata.a.ip_addr, 4); 153 p += 4; 154 155 } else if (rr->type == PJ_DNS_TYPE_CNAME || 156 rr->type == PJ_DNS_TYPE_NS) { 157 158 len = print_label(p+2, &rr->rdata.cname.name); 159 160 tmp = pj_htons((pj_uint16_t)len); 161 pj_memcpy(p, &tmp, 2); 162 163 p += (len + 2); 164 165 } else if (rr->type == PJ_DNS_TYPE_SRV) { 166 167 /* Skip RDLEN (will write later) */ 168 char *p_rdlen = p; 169 170 p += 2; 171 172 /* Priority */ 173 tmp = pj_htons(rr->rdata.srv.prio); 174 pj_memcpy(p, &tmp, 2); 175 p += 2; 176 177 /* Weight */ 178 tmp = pj_htons(rr->rdata.srv.weight); 179 pj_memcpy(p, &tmp, 2); 180 p += 2; 181 182 /* Port */ 183 tmp = pj_htons(rr->rdata.srv.port); 184 pj_memcpy(p, &tmp, 2); 185 p += 2; 186 187 /* Target */ 188 len = print_label(p, &rr->rdata.srv.target); 189 190 /* Now print RDLEN */ 191 tmp = pj_htons((pj_uint16_t)(len + 6)); 192 pj_memcpy(p_rdlen, &tmp, 2); 193 194 p += len; 195 196 } else { 197 pj_assert(!"Not supported"); 198 } 199 } 200 201 return p - packet; 298 size -= len; 299 } 300 301 /* Print NS records */ 302 for (i=0; i<rec->hdr.nscount; ++i) { 303 len = print_rr(pkt, size, p, &rec->ns[i], &tab); 304 if (len < 0) 305 return -1; 306 307 p += len; 308 size -= len; 309 } 310 311 /* Print additional records */ 312 for (i=0; i<rec->hdr.arcount; ++i) { 313 len = print_rr(pkt, size, p, &rec->arr[i], &tab); 314 if (len < 0) 315 return -1; 316 317 p += len; 318 size -= len; 319 } 320 321 return p - pkt; 202 322 } 203 323 … … 241 361 } 242 362 363 /* Verify packet */ 364 pj_assert(req->hdr.qdcount == 1); 365 pj_assert(req->q[0].dnsclass == 1); 366 243 367 /* Simulate network RTT */ 244 368 pj_thread_sleep(50); … … 248 372 } else if (srv->action == ACTION_REPLY) { 249 373 srv->resp.hdr.id = req->hdr.id; 250 pkt_len = print_packet(&srv->resp, pkt);374 pkt_len = print_packet(&srv->resp, (pj_uint8_t*)pkt, sizeof(pkt)); 251 375 pj_sock_sendto(srv->sock, pkt, &pkt_len, 0, &src_addr, src_len); 252 376 } else if (srv->action == ACTION_CB) { … … 254 378 (*srv->action_cb)(req, &resp); 255 379 resp->hdr.id = req->hdr.id; 256 pkt_len = print_packet(resp, pkt);380 pkt_len = print_packet(resp, (pj_uint8_t*)pkt, sizeof(pkt)); 257 381 pj_sock_sendto(srv->sock, pkt, &pkt_len, 0, &src_addr, src_len); 258 382 } else if (srv->action > 0) { 259 383 req->hdr.flags |= PJ_DNS_SET_RCODE(srv->action); 260 pkt_len = print_packet(req, pkt);384 pkt_len = print_packet(req, (pj_uint8_t*)pkt, sizeof(pkt)); 261 385 pj_sock_sendto(srv->sock, pkt, &pkt_len, 0, &src_addr, src_len); 262 386 } … … 364 488 pj_sem_destroy(sem); 365 489 pj_pool_release(pool); 490 } 491 492 493 //////////////////////////////////////////////////////////////////////////// 494 /* DNS A parser tests */ 495 static int a_parser_test(void) 496 { 497 pj_dns_parsed_packet pkt; 498 pj_dns_a_record rec; 499 pj_status_t rc; 500 501 PJ_LOG(3,(THIS_FILE, " DNS A record parser tests")); 502 503 pkt.q = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_query); 504 pkt.ans = (pj_dns_parsed_rr*) 505 pj_pool_calloc(pool, 32, sizeof(pj_dns_parsed_rr)); 506 507 /* Simple answer with direct A record, but with addition of 508 * a CNAME and another A to confuse the parser. 509 */ 510 PJ_LOG(3,(THIS_FILE, " A RR with duplicate CNAME/A")); 511 pkt.hdr.flags = 0; 512 pkt.hdr.qdcount = 1; 513 pkt.q[0].type = PJ_DNS_TYPE_A; 514 pkt.q[0].dnsclass = 1; 515 pkt.q[0].name = pj_str("ahost"); 516 pkt.hdr.anscount = 3; 517 518 /* This is the RR corresponding to the query */ 519 pkt.ans[0].name = pj_str("ahost"); 520 pkt.ans[0].type = PJ_DNS_TYPE_A; 521 pkt.ans[0].dnsclass = 1; 522 pkt.ans[0].ttl = 1; 523 pkt.ans[0].rdata.a.ip_addr.s_addr = 0x01020304; 524 525 /* CNAME to confuse the parser */ 526 pkt.ans[1].name = pj_str("ahost"); 527 pkt.ans[1].type = PJ_DNS_TYPE_CNAME; 528 pkt.ans[1].dnsclass = 1; 529 pkt.ans[1].ttl = 1; 530 pkt.ans[1].rdata.cname.name = pj_str("bhost"); 531 532 /* DNS A RR to confuse the parser */ 533 pkt.ans[2].name = pj_str("bhost"); 534 pkt.ans[2].type = PJ_DNS_TYPE_A; 535 pkt.ans[2].dnsclass = 1; 536 pkt.ans[2].ttl = 1; 537 pkt.ans[2].rdata.a.ip_addr.s_addr = 0x0203; 538 539 540 rc = pj_dns_parse_a_response(&pkt, &rec); 541 pj_assert(rc == PJ_SUCCESS); 542 pj_assert(pj_strcmp2(&rec.name, "ahost")==0); 543 pj_assert(rec.alias.slen == 0); 544 pj_assert(rec.addr_count == 1); 545 pj_assert(rec.addr[0].s_addr == 0x01020304); 546 547 /* Answer with the target corresponds to a CNAME entry, but not 548 * as the first record, and with additions of some CNAME and A 549 * entries to confuse the parser. 550 */ 551 PJ_LOG(3,(THIS_FILE, " CNAME RR with duplicate CNAME/A")); 552 pkt.hdr.flags = 0; 553 pkt.hdr.qdcount = 1; 554 pkt.q[0].type = PJ_DNS_TYPE_A; 555 pkt.q[0].dnsclass = 1; 556 pkt.q[0].name = pj_str("ahost"); 557 pkt.hdr.anscount = 4; 558 559 /* This is the DNS A record for the alias */ 560 pkt.ans[0].name = pj_str("ahostalias"); 561 pkt.ans[0].type = PJ_DNS_TYPE_A; 562 pkt.ans[0].dnsclass = 1; 563 pkt.ans[0].ttl = 1; 564 pkt.ans[0].rdata.a.ip_addr.s_addr = 0x02020202; 565 566 /* CNAME entry corresponding to the query */ 567 pkt.ans[1].name = pj_str("ahost"); 568 pkt.ans[1].type = PJ_DNS_TYPE_CNAME; 569 pkt.ans[1].dnsclass = 1; 570 pkt.ans[1].ttl = 1; 571 pkt.ans[1].rdata.cname.name = pj_str("ahostalias"); 572 573 /* Another CNAME to confuse the parser */ 574 pkt.ans[2].name = pj_str("ahost"); 575 pkt.ans[2].type = PJ_DNS_TYPE_CNAME; 576 pkt.ans[2].dnsclass = 1; 577 pkt.ans[2].ttl = 1; 578 pkt.ans[2].rdata.cname.name = pj_str("ahostalias2"); 579 580 /* Another DNS A to confuse the parser */ 581 pkt.ans[3].name = pj_str("ahostalias2"); 582 pkt.ans[3].type = PJ_DNS_TYPE_A; 583 pkt.ans[3].dnsclass = 1; 584 pkt.ans[3].ttl = 1; 585 pkt.ans[3].rdata.a.ip_addr.s_addr = 0x03030303; 586 587 rc = pj_dns_parse_a_response(&pkt, &rec); 588 pj_assert(rc == PJ_SUCCESS); 589 pj_assert(pj_strcmp2(&rec.name, "ahost")==0); 590 pj_assert(pj_strcmp2(&rec.alias, "ahostalias")==0); 591 pj_assert(rec.addr_count == 1); 592 pj_assert(rec.addr[0].s_addr == 0x02020202); 593 594 /* 595 * No query section. 596 */ 597 PJ_LOG(3,(THIS_FILE, " No query section")); 598 pkt.hdr.qdcount = 0; 599 pkt.hdr.anscount = 0; 600 601 rc = pj_dns_parse_a_response(&pkt, &rec); 602 pj_assert(rc == PJLIB_UTIL_EDNSINANSWER); 603 604 /* 605 * No answer section. 606 */ 607 PJ_LOG(3,(THIS_FILE, " No answer section")); 608 pkt.hdr.flags = 0; 609 pkt.hdr.qdcount = 1; 610 pkt.q[0].type = PJ_DNS_TYPE_A; 611 pkt.q[0].dnsclass = 1; 612 pkt.q[0].name = pj_str("ahost"); 613 pkt.hdr.anscount = 0; 614 615 rc = pj_dns_parse_a_response(&pkt, &rec); 616 pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC); 617 618 /* 619 * Answer doesn't match query. 620 */ 621 PJ_LOG(3,(THIS_FILE, " Answer doesn't match query")); 622 pkt.hdr.flags = 0; 623 pkt.hdr.qdcount = 1; 624 pkt.q[0].type = PJ_DNS_TYPE_A; 625 pkt.q[0].dnsclass = 1; 626 pkt.q[0].name = pj_str("ahost"); 627 pkt.hdr.anscount = 1; 628 629 /* An answer that doesn't match the query */ 630 pkt.ans[0].name = pj_str("ahostalias"); 631 pkt.ans[0].type = PJ_DNS_TYPE_A; 632 pkt.ans[0].dnsclass = 1; 633 pkt.ans[0].ttl = 1; 634 pkt.ans[0].rdata.a.ip_addr.s_addr = 0x02020202; 635 636 rc = pj_dns_parse_a_response(&pkt, &rec); 637 pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC); 638 639 640 /* 641 * DNS CNAME that doesn't have corresponding DNS A. 642 */ 643 PJ_LOG(3,(THIS_FILE, " CNAME with no matching DNS A RR (1)")); 644 pkt.hdr.flags = 0; 645 pkt.hdr.qdcount = 1; 646 pkt.q[0].type = PJ_DNS_TYPE_A; 647 pkt.q[0].dnsclass = 1; 648 pkt.q[0].name = pj_str("ahost"); 649 pkt.hdr.anscount = 1; 650 651 /* The CNAME */ 652 pkt.ans[0].name = pj_str("ahost"); 653 pkt.ans[0].type = PJ_DNS_TYPE_CNAME; 654 pkt.ans[0].dnsclass = 1; 655 pkt.ans[0].ttl = 1; 656 pkt.ans[0].rdata.cname.name = pj_str("ahostalias"); 657 658 rc = pj_dns_parse_a_response(&pkt, &rec); 659 pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC); 660 661 662 /* 663 * DNS CNAME that doesn't have corresponding DNS A. 664 */ 665 PJ_LOG(3,(THIS_FILE, " CNAME with no matching DNS A RR (2)")); 666 pkt.hdr.flags = 0; 667 pkt.hdr.qdcount = 1; 668 pkt.q[0].type = PJ_DNS_TYPE_A; 669 pkt.q[0].dnsclass = 1; 670 pkt.q[0].name = pj_str("ahost"); 671 pkt.hdr.anscount = 2; 672 673 /* The CNAME */ 674 pkt.ans[0].name = pj_str("ahost"); 675 pkt.ans[0].type = PJ_DNS_TYPE_CNAME; 676 pkt.ans[0].dnsclass = 1; 677 pkt.ans[0].ttl = 1; 678 pkt.ans[0].rdata.cname.name = pj_str("ahostalias"); 679 680 /* DNS A record, but the name doesn't match */ 681 pkt.ans[1].name = pj_str("ahost"); 682 pkt.ans[1].type = PJ_DNS_TYPE_A; 683 pkt.ans[1].dnsclass = 1; 684 pkt.ans[1].ttl = 1; 685 pkt.ans[1].rdata.a.ip_addr.s_addr = 0x01020304; 686 687 rc = pj_dns_parse_a_response(&pkt, &rec); 688 pj_assert(rc == PJLIB_UTIL_EDNSNOANSWERREC); 689 690 return 0; 366 691 } 367 692 … … 393 718 pj_status_t status; 394 719 395 PJ_LOG(3,(THIS_FILE, " 720 PJ_LOG(3,(THIS_FILE, " simple successful test")); 396 721 397 722 g_server[0].pkt_count = 0; … … 467 792 pj_status_t status; 468 793 469 PJ_LOG(3,(THIS_FILE, " 794 PJ_LOG(3,(THIS_FILE, " simple error response test")); 470 795 471 796 g_server[0].pkt_count = 0; … … 490 815 491 816 /* Wait to allow probing period to complete */ 492 PJ_LOG(3,(THIS_FILE, " 817 PJ_LOG(3,(THIS_FILE, " waiting for active NS to expire (%d sec)", 493 818 set.good_ns_ttl)); 494 819 pj_thread_sleep(set.good_ns_ttl * 1000); … … 497 822 * Fail-over test 498 823 */ 499 PJ_LOG(3,(THIS_FILE, " 824 PJ_LOG(3,(THIS_FILE, " failing server0")); 500 825 g_server[0].action = ACTION_IGNORE; 501 826 g_server[1].action = PJ_DNS_RCODE_NXDOMAIN; … … 516 841 * in probing state. 517 842 */ 518 PJ_LOG(3,(THIS_FILE, " 843 PJ_LOG(3,(THIS_FILE, " checking both NS during probing period")); 519 844 g_server[0].action = ACTION_IGNORE; 520 845 g_server[1].action = PJ_DNS_RCODE_NXDOMAIN; … … 537 862 538 863 /* Wait to allow probing period to complete */ 539 PJ_LOG(3,(THIS_FILE, " 864 PJ_LOG(3,(THIS_FILE, " waiting for probing state to end (%d sec)", 540 865 set.qretr_delay * 541 866 (set.qretr_count+2) / 1000)); … … 546 871 * Now only server 1 should get requests. 547 872 */ 548 PJ_LOG(3,(THIS_FILE, " 873 PJ_LOG(3,(THIS_FILE, " verifying only good NS is used")); 549 874 g_server[0].action = PJ_DNS_RCODE_NXDOMAIN; 550 875 g_server[1].action = PJ_DNS_RCODE_NXDOMAIN; … … 567 892 568 893 /* Wait to allow probing period to complete */ 569 PJ_LOG(3,(THIS_FILE, " 894 PJ_LOG(3,(THIS_FILE, " waiting for active NS to expire (%d sec)", 570 895 set.good_ns_ttl)); 571 896 pj_thread_sleep(set.good_ns_ttl * 1000); … … 589 914 590 915 /* Wait to allow probing period to complete */ 591 PJ_LOG(3,(THIS_FILE, " 916 PJ_LOG(3,(THIS_FILE, " waiting for probing state (%d sec)", 592 917 set.qretr_delay * (set.qretr_count+2) / 1000)); 593 918 pj_thread_sleep(set.qretr_delay * (set.qretr_count + 2)); … … 596 921 * Now only server 0 should get requests. 597 922 */ 598 PJ_LOG(3,(THIS_FILE, " 923 PJ_LOG(3,(THIS_FILE, " verifying good NS")); 599 924 g_server[0].action = PJ_DNS_RCODE_NXDOMAIN; 600 925 g_server[1].action = ACTION_IGNORE; … … 612 937 pj_thread_sleep(1000); 613 938 614 /* Both servers must get requests*/939 /* Only good NS should get request */ 615 940 pj_assert(g_server[0].pkt_count == 1); 616 941 pj_assert(g_server[1].pkt_count == 0); … … 624 949 /* Resolver test, normal, with CNAME */ 625 950 #define IP_ADDR1 0x02030405 951 #define PORT1 50061 626 952 627 953 static void action1_1(const pj_dns_parsed_packet *pkt, … … 657 983 res->ans[0].rdata.srv.prio = 1; 658 984 res->ans[0].rdata.srv.weight = 2; 659 res->ans[0].rdata.srv.port = 5061;985 res->ans[0].rdata.srv.port = PORT1; 660 986 res->ans[0].rdata.srv.target = pj_str(target); 661 987 … … 692 1018 pj_assert(rec->entry[0].priority == 1); 693 1019 pj_assert(rec->entry[0].weight == 2); 694 pj_assert(rec->entry[0].addr.ipv4.sin_addr.s_addr == IP_ADDR1); 695 pj_assert(pj_ntohs(rec->entry[0].addr.ipv4.sin_port) == 5061); 1020 pj_assert(pj_strcmp2(&rec->entry[0].server.name, "sip.somedomain.com")==0); 1021 pj_assert(pj_strcmp2(&rec->entry[0].server.alias, "sipalias.somedomain.com")==0); 1022 pj_assert(rec->entry[0].server.addr[0].s_addr == IP_ADDR1); 1023 pj_assert(rec->entry[0].port == PORT1); 696 1024 697 1025 pj_sem_post(sem); … … 717 1045 718 1046 /* Successful scenario */ 719 PJ_LOG(3,(THIS_FILE, " 1047 PJ_LOG(3,(THIS_FILE, " srv_resolve(): success scenario")); 720 1048 721 1049 g_server[0].action = ACTION_CB; … … 728 1056 729 1057 status = pj_dns_srv_resolve(&domain, &res_name, 5061, pool, resolver, PJ_TRUE, 730 NULL, &srv_cb_1 );1058 NULL, &srv_cb_1, NULL); 731 1059 pj_assert(status == PJ_SUCCESS); 732 1060 733 1061 pj_sem_wait(sem); 734 1062 735 /* B oth servers should receive requests since state should be probing*/1063 /* Because of previous tests, only NS 1 should get the request */ 736 1064 pj_assert(g_server[0].pkt_count == 2); /* 2 because of SRV and A resolution */ 737 1065 pj_assert(g_server[1].pkt_count == 0); … … 739 1067 740 1068 /* Wait until cache expires and nameserver state moves out from STATE_PROBING */ 741 PJ_LOG(3,(THIS_FILE, " 1069 PJ_LOG(3,(THIS_FILE, " waiting for cache to expire (~15 secs)..")); 742 1070 pj_thread_sleep(1000 + 743 1071 ((set.qretr_count + 2) * set.qretr_delay)); 744 1072 745 1073 /* Successful scenario */ 746 PJ_LOG(3,(THIS_FILE, " 1074 PJ_LOG(3,(THIS_FILE, " srv_resolve(): parallel queries")); 747 1075 g_server[0].pkt_count = 0; 748 1076 g_server[1].pkt_count = 0; 749 1077 750 1078 status = pj_dns_srv_resolve(&domain, &res_name, 5061, pool, resolver, PJ_TRUE, 751 NULL, &srv_cb_1 );1079 NULL, &srv_cb_1, NULL); 752 1080 pj_assert(status == PJ_SUCCESS); 753 1081 754 1082 755 1083 status = pj_dns_srv_resolve(&domain, &res_name, 5061, pool, resolver, PJ_TRUE, 756 NULL, &srv_cb_1 );1084 NULL, &srv_cb_1, NULL); 757 1085 pj_assert(status == PJ_SUCCESS); 758 1086 … … 765 1093 766 1094 /* Since TTL is one, subsequent queries should fail */ 767 PJ_LOG(3,(THIS_FILE, " 1095 PJ_LOG(3,(THIS_FILE, " srv_resolve(): cache expires scenario")); 768 1096 769 1097 … … 774 1102 775 1103 status = pj_dns_srv_resolve(&domain, &res_name, 5061, pool, resolver, PJ_TRUE, 776 NULL, &srv_cb_1b );1104 NULL, &srv_cb_1b, NULL); 777 1105 pj_assert(status == PJ_SUCCESS); 778 1106 … … 787 1115 #define TARGET "domain2.com" 788 1116 #define IP_ADDR2 0x02030405 1117 #define PORT2 50062 789 1118 790 1119 static void action2_1(const pj_dns_parsed_packet *pkt, 791 1120 pj_dns_parsed_packet **p_res) 792 1121 { 793 static pj_dns_parsed_packet res; 794 795 if (res.q == NULL) { 796 res.q = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_query); 797 } 798 if (res.ans == NULL) { 799 res.ans = (pj_dns_parsed_rr*) 800 pj_pool_calloc(pool, 4, sizeof(pj_dns_parsed_rr)); 801 } 802 803 res.hdr.qdcount = 1; 804 res.q[0].type = pkt->q[0].type; 805 res.q[0].dnsclass = pkt->q[0].dnsclass; 806 res.q[0].name = pkt->q[0].name; 1122 pj_dns_parsed_packet *res; 1123 1124 res = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_packet); 1125 1126 res->q = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_query); 1127 res->ans = (pj_dns_parsed_rr*) 1128 pj_pool_calloc(pool, 4, sizeof(pj_dns_parsed_rr)); 1129 1130 res->hdr.qdcount = 1; 1131 res->q[0].type = pkt->q[0].type; 1132 res->q[0].dnsclass = pkt->q[0].dnsclass; 1133 res->q[0].name = pkt->q[0].name; 807 1134 808 1135 if (pkt->q[0].type == PJ_DNS_TYPE_SRV) { … … 810 1137 pj_assert(pj_strcmp2(&pkt->q[0].name, "_sip._udp." TARGET)==0); 811 1138 812 res .hdr.anscount = 1;813 res .ans[0].type = PJ_DNS_TYPE_A; // <-- this will cause the fallback814 res .ans[0].dnsclass = 1;815 res .ans[0].name = res.q[0].name;816 res .ans[0].ttl = 1;817 res .ans[0].rdata.srv.prio = 1;818 res .ans[0].rdata.srv.weight = 2;819 res .ans[0].rdata.srv.port = 5062;820 res .ans[0].rdata.srv.target = pj_str("sip01." TARGET);1139 res->hdr.anscount = 1; 1140 res->ans[0].type = PJ_DNS_TYPE_A; // <-- this will cause the fallback 1141 res->ans[0].dnsclass = 1; 1142 res->ans[0].name = res->q[0].name; 1143 res->ans[0].ttl = 1; 1144 res->ans[0].rdata.srv.prio = 1; 1145 res->ans[0].rdata.srv.weight = 2; 1146 res->ans[0].rdata.srv.port = PORT2; 1147 res->ans[0].rdata.srv.target = pj_str("sip01." TARGET); 821 1148 822 1149 } else if (pkt->q[0].type == PJ_DNS_TYPE_A) { 823 char *alias = "sipalias .somedomain.com";824 825 pj_assert(pj_strcmp2(&res .q[0].name, TARGET)==0);826 827 res .hdr.anscount = 2;828 res .ans[0].type = PJ_DNS_TYPE_CNAME;829 res .ans[0].dnsclass = 1;830 res .ans[0].name = res.q[0].name;831 res .ans[0].ttl = 1;832 res .ans[0].rdata.cname.name = pj_str(alias);833 834 res .ans[1].type = PJ_DNS_TYPE_A;835 res .ans[1].dnsclass = 1;836 res .ans[1].name = pj_str(alias);837 res .ans[1].ttl = 1;838 res .ans[1].rdata.a.ip_addr.s_addr = IP_ADDR2;839 } 840 841 *p_res = &res;1150 char *alias = "sipalias01." TARGET; 1151 1152 pj_assert(pj_strcmp2(&res->q[0].name, TARGET)==0); 1153 1154 res->hdr.anscount = 2; 1155 res->ans[0].type = PJ_DNS_TYPE_CNAME; 1156 res->ans[0].dnsclass = 1; 1157 res->ans[0].name = res->q[0].name; 1158 res->ans[0].ttl = 1; 1159 res->ans[0].rdata.cname.name = pj_str(alias); 1160 1161 res->ans[1].type = PJ_DNS_TYPE_A; 1162 res->ans[1].dnsclass = 1; 1163 res->ans[1].name = pj_str(alias); 1164 res->ans[1].ttl = 1; 1165 res->ans[1].rdata.a.ip_addr.s_addr = IP_ADDR2; 1166 } 1167 1168 *p_res = res; 842 1169 } 843 1170 … … 852 1179 pj_assert(rec->entry[0].priority == 0); 853 1180 pj_assert(rec->entry[0].weight == 0); 854 pj_assert(rec->entry[0].addr.ipv4.sin_addr.s_addr == IP_ADDR2); 855 pj_assert(pj_ntohs(rec->entry[0].addr.ipv4.sin_port) == 5062); 1181 pj_assert(pj_strcmp2(&rec->entry[0].server.name, TARGET)==0); 1182 pj_assert(pj_strcmp2(&rec->entry[0].server.alias, "sipalias01." TARGET)==0); 1183 pj_assert(rec->entry[0].server.addr[0].s_addr == IP_ADDR2); 1184 pj_assert(rec->entry[0].port == PORT2); 856 1185 857 1186 pj_sem_post(sem); … … 864 1193 pj_str_t res_name = pj_str("_sip._udp."); 865 1194 866 PJ_LOG(3,(THIS_FILE, " 1195 PJ_LOG(3,(THIS_FILE, " srv_resolve(): fallback test")); 867 1196 868 1197 g_server[0].action = ACTION_CB; … … 871 1200 g_server[1].action_cb = &action2_1; 872 1201 873 status = pj_dns_srv_resolve(&domain, &res_name, 5062, pool, resolver, PJ_TRUE,874 NULL, &srv_cb_2 );1202 status = pj_dns_srv_resolve(&domain, &res_name, PORT2, pool, resolver, PJ_TRUE, 1203 NULL, &srv_cb_2, NULL); 875 1204 if (status != PJ_SUCCESS) { 876 app_perror(" 1205 app_perror(" srv_resolve error", status); 877 1206 pj_assert(status == PJ_SUCCESS); 878 1207 } … … 881 1210 882 1211 /* Subsequent query should just get the response from the cache */ 883 PJ_LOG(3,(THIS_FILE, " 1212 PJ_LOG(3,(THIS_FILE, " srv_resolve(): cache test")); 884 1213 g_server[0].pkt_count = 0; 885 1214 g_server[1].pkt_count = 0; 886 1215 887 status = pj_dns_srv_resolve(&domain, &res_name, 5062, pool, resolver, PJ_TRUE,888 NULL, &srv_cb_2 );1216 status = pj_dns_srv_resolve(&domain, &res_name, PORT2, pool, resolver, PJ_TRUE, 1217 NULL, &srv_cb_2, NULL); 889 1218 if (status != PJ_SUCCESS) { 890 app_perror(" 1219 app_perror(" srv_resolve error", status); 891 1220 pj_assert(status == PJ_SUCCESS); 892 1221 } … … 896 1225 pj_assert(g_server[0].pkt_count == 0); 897 1226 pj_assert(g_server[1].pkt_count == 0); 1227 1228 return 0; 1229 } 1230 1231 1232 //////////////////////////////////////////////////////////////////////////// 1233 /* Too many SRV or A entries */ 1234 #define DOMAIN3 "d3" 1235 #define SRV_COUNT3 (PJ_DNS_SRV_MAX_ADDR+1) 1236 #define A_COUNT3 (PJ_DNS_MAX_IP_IN_A_REC+1) 1237 #define PORT3 50063 1238 #define IP_ADDR3 0x03030303 1239 1240 static void action3_1(const pj_dns_parsed_packet *pkt, 1241 pj_dns_parsed_packet **p_res) 1242 { 1243 pj_dns_parsed_packet *res; 1244 unsigned i; 1245 1246 res = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_packet); 1247 1248 if (res->q == NULL) { 1249 res->q = PJ_POOL_ZALLOC_T(pool, pj_dns_parsed_query); 1250 } 1251 1252 res->hdr.qdcount = 1; 1253 res->q[0].type = pkt->q[0].type; 1254 res->q[0].dnsclass = pkt->q[0].dnsclass; 1255 res->q[0].name = pkt->q[0].name; 1256 1257 if (pkt->q[0].type == PJ_DNS_TYPE_SRV) { 1258 1259 pj_assert(pj_strcmp2(&pkt->q[0].name, "_sip._udp." DOMAIN3)==0); 1260 1261 res->hdr.anscount = SRV_COUNT3; 1262 res->ans = (pj_dns_parsed_rr*) 1263 pj_pool_calloc(pool, SRV_COUNT3, sizeof(pj_dns_parsed_rr)); 1264 1265 for (i=0; i<SRV_COUNT3; ++i) { 1266 char *target; 1267 1268 res->ans[i].type = PJ_DNS_TYPE_SRV; 1269 res->ans[i].dnsclass = 1; 1270 res->ans[i].name = res->q[0].name; 1271 res->ans[i].ttl = 1; 1272 res->ans[i].rdata.srv.prio = (pj_uint16_t)i; 1273 res->ans[i].rdata.srv.weight = 2; 1274 res->ans[i].rdata.srv.port = (pj_uint16_t)(PORT3+i); 1275 1276 target = (char*)pj_pool_alloc(pool, 16); 1277 sprintf(target, "sip%02d." DOMAIN3, i); 1278 res->ans[i].rdata.srv.target = pj_str(target); 1279 } 1280 1281 } else if (pkt->q[0].type == PJ_DNS_TYPE_A) { 1282 1283 //pj_assert(pj_strcmp2(&res->q[0].name, "sip." DOMAIN3)==0); 1284 1285 res->hdr.anscount = A_COUNT3; 1286 res->ans = (pj_dns_parsed_rr*) 1287 pj_pool_calloc(pool, A_COUNT3, sizeof(pj_dns_parsed_rr)); 1288 1289 for (i=0; i<A_COUNT3; ++i) { 1290 res->ans[i].type = PJ_DNS_TYPE_A; 1291 res->ans[i].dnsclass = 1; 1292 res->ans[i].ttl = 1; 1293 res->ans[i].name = res->q[0].name; 1294 res->ans[i].rdata.a.ip_addr.s_addr = IP_ADDR3+i; 1295 } 1296 } 1297 1298 *p_res = res; 1299 } 1300 1301 static void srv_cb_3(void *user_data, 1302 pj_status_t status, 1303 const pj_dns_srv_record *rec) 1304 { 1305 unsigned i; 1306 1307 PJ_UNUSED_ARG(user_data); 1308 1309 pj_assert(status == PJ_SUCCESS); 1310 pj_assert(rec->count == PJ_DNS_SRV_MAX_ADDR); 1311 for (i=0; i<PJ_DNS_SRV_MAX_ADDR; ++i) { 1312 unsigned j; 1313 1314 pj_assert(rec->entry[i].priority == i); 1315 pj_assert(rec->entry[i].weight == 2); 1316 //pj_assert(pj_strcmp2(&rec->entry[i].server.name, "sip." DOMAIN3)==0); 1317 pj_assert(rec->entry[i].server.alias.slen == 0); 1318 pj_assert(rec->entry[i].port == PORT3+i); 1319 1320 pj_assert(rec->entry[i].server.addr_count == PJ_DNS_MAX_IP_IN_A_REC); 1321 1322 for (j=0; j<PJ_DNS_MAX_IP_IN_A_REC; ++j) { 1323 pj_assert(rec->entry[i].server.addr[j].s_addr == IP_ADDR3+j); 1324 } 1325 } 1326 1327 pj_sem_post(sem); 1328 } 1329 1330 static int srv_resolver_many_test(void) 1331 { 1332 pj_status_t status; 1333 pj_str_t domain = pj_str(DOMAIN3); 1334 pj_str_t res_name = pj_str("_sip._udp."); 1335 1336 /* Successful scenario */ 1337 PJ_LOG(3,(THIS_FILE, " srv_resolve(): too many entries test")); 1338 1339 g_server[0].action = ACTION_CB; 1340 g_server[0].action_cb = &action3_1; 1341 g_server[1].action = ACTION_CB; 1342 g_server[1].action_cb = &action3_1; 1343 1344 g_server[0].pkt_count = 0; 1345 g_server[1].pkt_count = 0; 1346 1347 status = pj_dns_srv_resolve(&domain, &res_name, 1, pool, resolver, PJ_TRUE, 1348 NULL, &srv_cb_3, NULL); 1349 pj_assert(status == PJ_SUCCESS); 1350 1351 pj_sem_wait(sem); 898 1352 899 1353 return 0; … … 909 1363 910 1364 #ifdef NDEBUG 911 PJ_LOG(3,(THIS_FILE, " 1365 PJ_LOG(3,(THIS_FILE, " error: NDEBUG is declared")); 912 1366 return -1; 913 1367 #endif 914 1368 915 1369 rc = init(); 1370 1371 rc = a_parser_test(); 1372 if (rc != 0) 1373 goto on_error; 916 1374 917 1375 rc = simple_test(); … … 925 1383 srv_resolver_test(); 926 1384 srv_resolver_fallback_test(); 1385 srv_resolver_many_test(); 927 1386 928 1387 destroy(); -
pjproject/trunk/pjlib-util/src/pjlib-util-test/test.c
r1347 r1359 51 51 mem = &caching_pool.factory; 52 52 53 pj_log_set_level( 5);53 pj_log_set_level(3); 54 54 pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME | 55 55 PJ_LOG_HAS_MICRO_SEC);
Note: See TracChangeset
for help on using the changeset viewer.