- Timestamp:
- Jun 11, 2007 4:51:18 PM (17 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/include/pjlib-util/srv_resolver.h
r1102 r1357 76 76 77 77 /** 78 * Maximum server address entries per one SRV record 79 */ 80 #ifndef PJ_DNS_SRV_MAX_ADDR 81 # define PJ_DNS_SRV_MAX_ADDR 8 82 #endif 83 84 85 /** 86 * The server addresses returned by the resolver. 78 * This structure represents DNS SRV records as the result of DNS SRV 79 * resolution using #pj_dns_srv_resolve(). 87 80 */ 88 81 typedef struct pj_dns_srv_record … … 93 86 /** Address records. */ 94 87 struct 95 {88 v { 96 89 /** Server priority (the lower the higher the priority). */ 97 90 unsigned priority; … … 100 93 unsigned weight; 101 94 102 /** The server's address. */103 pj_ sockaddr addr;95 /** Port number. */ 96 pj_uint16_t port; 104 97 105 /** Address length. */106 int addr_len;98 /** The host address. */ 99 pj_dns_a_record server; 107 100 108 101 } entry[PJ_DNS_SRV_MAX_ADDR]; … … 139 132 * @param cb Pointer to callback function to receive the 140 133 * notification when the resolution process completes. 134 * @param p_query Optional pointer to receive the query object, if one 135 * was started. If this pointer is specified, a NULL may 136 * be returned if response cache is available immediately. 141 137 * 142 138 * @return PJ_SUCCESS on success, or the appropriate error code. … … 149 145 pj_bool_t fallback_a, 150 146 void *token, 151 pj_dns_srv_resolver_cb *cb); 147 pj_dns_srv_resolver_cb *cb, 148 pj_dns_async_query **p_query); 152 149 153 150 -
pjproject/trunk/pjlib-util/src/pjlib-util/srv_resolver.c
r1346 r1357 29 29 #define THIS_FILE "srv_resolver.c" 30 30 31 #define ADDR_MAX_COUNT 831 #define ADDR_MAX_COUNT PJ_DNS_MAX_IP_IN_A_REC 32 32 33 33 struct srv_target … … 53 53 void *token; 54 54 pj_dns_srv_resolver_cb *cb; 55 pj_dns_async_query *qobject;56 55 pj_status_t last_error; 57 56 … … 89 88 pj_bool_t fallback_a, 90 89 void *token, 91 pj_dns_srv_resolver_cb *cb) 90 pj_dns_srv_resolver_cb *cb, 91 pj_dns_async_query **p_query) 92 92 { 93 93 int len; … … 128 128 129 129 PJ_LOG(5, (query_job->objname, 130 "Starting async DNS %s query_job: target=%.*s ",130 "Starting async DNS %s query_job: target=%.*s:%d", 131 131 pj_dns_get_type_name(query_job->dns_state), 132 (int)target_name.slen, target_name.ptr)); 132 (int)target_name.slen, target_name.ptr, 133 def_port)); 133 134 134 135 status = pj_dns_resolver_start_query(resolver, &target_name, 135 136 query_job->dns_state, 0, 136 137 &dns_callback, 137 query_job, &query_job->qobject);138 query_job, p_query); 138 139 return status; 139 140 } … … 466 467 /* Check that we really have answer */ 467 468 if (status==PJ_SUCCESS && pkt->hdr.anscount != 0) { 468 int ans_idx = -1; 469 470 /* Find the first DNS A record in the answer while processing 471 * the CNAME info found in the response. 472 */ 473 for (i=0; i < pkt->hdr.anscount; ++i) { 474 475 pj_dns_parsed_rr *rr = &pkt->ans[i]; 476 477 if (rr->type == PJ_DNS_TYPE_A) { 478 479 if (ans_idx == -1) 480 ans_idx = i; 481 482 } else if (rr->type == PJ_DNS_TYPE_CNAME) { 483 /* Find which server entry to be updated with 484 * the CNAME information. 485 */ 486 unsigned j; 487 pj_str_t cname = rr->rdata.cname.name; 488 489 for (j=0; j<query_job->srv_cnt; ++j) 490 { 491 struct srv_target *srv = &query_job->srv[j]; 492 if (pj_stricmp(&rr->name, &srv->target_name)==0) 493 { 494 /* Update CNAME info for this server entry */ 495 srv->cname.ptr = srv->cname_buf; 496 pj_strncpy(&srv->cname, &cname, 497 sizeof(srv->cname_buf)); 498 break; 499 } 500 } 501 } 502 } 503 504 if (ans_idx == -1) { 505 /* There's no DNS A answer! */ 506 PJ_LOG(5,(query_job->objname, 507 "No DNS A record in response!")); 508 status = PJLIB_UTIL_EDNSNOANSWERREC; 469 unsigned srv_idx; 470 struct srv_target *srv = NULL; 471 pj_dns_a_record rec; 472 473 /* Parse response */ 474 status = pj_dns_parse_a_response(pkt, &rec); 475 if (status != PJ_SUCCESS) 509 476 goto on_error; 510 } 511 512 /* Update IP address of the corresponding hostname or CNAME */ 513 for (i=0; i<query_job->srv_cnt; ++i) { 514 pj_dns_parsed_rr *rr = &pkt->ans[ans_idx]; 515 struct srv_target *srv = &query_job->srv[i]; 516 517 if (pj_stricmp(&rr->name, &srv->target_name)==0 || 518 pj_stricmp(&rr->name, &srv->cname)==0) 519 { 477 478 pj_assert(rec.addr_count != 0); 479 480 /* Find which server entry to be updated. */ 481 for (srv_idx=0; srv_idx<query_job->srv_cnt; ++srv_idx) { 482 srv = &query_job->srv[srv_idx]; 483 if (pj_stricmp(&rec.name, &srv->target_name)==0) { 520 484 break; 521 485 } 522 486 } 523 487 524 if (i == query_job->srv_cnt) { 525 PJ_LOG(4,(query_job->objname, 526 "Received answer to DNS A request with no matching " 527 "SRV record! The unknown name is %.*s", 528 (int)pkt->ans[ans_idx].name.slen, 529 pkt->ans[ans_idx].name.ptr)); 488 if (srv_idx==query_job->srv_cnt) { 489 /* The DNS A response doesn't match any server names 490 * we're querying! 491 */ 492 status = PJLIB_UTIL_EDNSINANSWER; 493 goto on_error; 494 } 495 496 srv = &query_job->srv[srv_idx]; 497 498 /* Update CNAME alias, if present. */ 499 if (rec.alias.slen) { 500 pj_assert(rec.alias.slen <= sizeof(srv->cname_buf)); 501 srv->cname.ptr = srv->cname_buf; 502 pj_strcpy(&srv->cname, &rec.alias); 530 503 } else { 531 unsigned j; 532 533 query_job->srv[i].addr[query_job->srv[i].addr_cnt++].s_addr = 534 pkt->ans[ans_idx].rdata.a.ip_addr.s_addr; 504 srv->cname.slen = 0; 505 } 506 507 /* Update IP address of the corresponding hostname or CNAME */ 508 if (srv->addr_cnt < ADDR_MAX_COUNT) { 509 srv->addr[srv->addr_cnt++].s_addr = rec.addr[0].s_addr; 535 510 536 511 PJ_LOG(5,(query_job->objname, 537 512 "DNS A for %.*s: %s", 538 (int)query_job->srv[i].target_name.slen, 539 query_job->srv[i].target_name.ptr, 540 pj_inet_ntoa(pkt->ans[ans_idx].rdata.a.ip_addr))); 541 542 /* Check for multiple IP addresses */ 543 for (j=ans_idx+1; j<pkt->hdr.anscount && 544 query_job->srv[i].addr_cnt < ADDR_MAX_COUNT; ++j) 545 { 546 query_job->srv[i].addr[query_job->srv[i].addr_cnt++].s_addr = 547 pkt->ans[j].rdata.a.ip_addr.s_addr; 548 549 PJ_LOG(5,(query_job->objname, 550 "Additional DNS A for %.*s: %s", 551 (int)query_job->srv[i].target_name.slen, 552 query_job->srv[i].target_name.ptr, 553 pj_inet_ntoa(pkt->ans[j].rdata.a.ip_addr))); 554 } 513 (int)srv->target_name.slen, 514 srv->target_name.ptr, 515 pj_inet_ntoa(rec.addr[0]))); 516 } 517 518 /* Check for multiple IP addresses */ 519 for (i=1; i<rec.addr_count && srv->addr_cnt < ADDR_MAX_COUNT; ++i) 520 { 521 srv->addr[srv->addr_cnt++].s_addr = rec.addr[i].s_addr; 522 523 PJ_LOG(5,(query_job->objname, 524 "Additional DNS A for %.*s: %s", 525 (int)srv->target_name.slen, 526 srv->target_name.ptr, 527 pj_inet_ntoa(rec.addr[i]))); 555 528 } 556 529 … … 578 551 if (query_job->host_resolved == query_job->srv_cnt) { 579 552 /* Got all answers, build server addresses */ 580 pj_dns_srv_record s vr_addr;581 582 s vr_addr.count = 0;553 pj_dns_srv_record srv_rec; 554 555 srv_rec.count = 0; 583 556 for (i=0; i<query_job->srv_cnt; ++i) { 584 557 unsigned j; 585 586 /* Do we have IP address for this server? */ 587 /* This log is redundant really. 588 if (query_job->srv[i].addr_cnt == 0) { 589 PJ_LOG(5,(query_job->objname, 590 " SRV target %.*s:%d does not have IP address!", 591 (int)query_job->srv[i].target_name.slen, 592 query_job->srv[i].target_name.ptr, 593 query_job->srv[i].port)); 594 continue; 595 } 596 */ 597 598 for (j=0; j<query_job->srv[i].addr_cnt; ++j) { 599 unsigned idx = svr_addr.count; 600 pj_sockaddr_in *addr; 601 602 svr_addr.entry[idx].priority = query_job->srv[i].priority; 603 svr_addr.entry[idx].weight = query_job->srv[i].weight; 604 svr_addr.entry[idx].addr_len = sizeof(pj_sockaddr_in); 605 606 addr = (pj_sockaddr_in*)&svr_addr.entry[idx].addr; 607 pj_bzero(addr, sizeof(pj_sockaddr_in)); 608 addr->sin_family = PJ_AF_INET; 609 addr->sin_addr = query_job->srv[i].addr[j]; 610 addr->sin_port = pj_htons((pj_uint16_t)query_job->srv[i].port); 611 612 ++svr_addr.count; 558 struct srv_target *srv = &query_job->srv[i]; 559 560 srv_rec.entry[srv_rec.count].priority = srv->priority; 561 srv_rec.entry[srv_rec.count].weight = srv->weight; 562 srv_rec.entry[srv_rec.count].port = (pj_uint16_t)srv->port ; 563 564 srv_rec.entry[srv_rec.count].server.name = srv->target_name; 565 srv_rec.entry[srv_rec.count].server.alias = srv->cname; 566 srv_rec.entry[srv_rec.count].server.addr_count = 0; 567 568 pj_assert(srv->addr_cnt <= PJ_DNS_MAX_IP_IN_A_REC); 569 570 for (j=0; j<srv->addr_cnt; ++j) { 571 srv_rec.entry[srv_rec.count].server.addr[j].s_addr = 572 srv->addr[j].s_addr; 573 ++srv_rec.entry[srv_rec.count].server.addr_count; 574 } 575 576 if (srv->addr_cnt > 0) { 577 ++srv_rec.count; 578 if (srv_rec.count == PJ_DNS_SRV_MAX_ADDR) 579 break; 613 580 } 614 581 } … … 616 583 PJ_LOG(5,(query_job->objname, 617 584 "Server resolution complete, %d server entry(s) found", 618 s vr_addr.count));619 620 621 if (s vr_addr.count > 0)585 srv_rec.count)); 586 587 588 if (srv_rec.count > 0) 622 589 status = PJ_SUCCESS; 623 590 else { … … 628 595 629 596 /* Call the callback */ 630 (*query_job->cb)(query_job->token, status, &s vr_addr);597 (*query_job->cb)(query_job->token, status, &srv_rec); 631 598 } 632 599 -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r1317 r1357 743 743 } 744 744 745 pj_memcpy(&pjsua_var.stun_srv, &rec->entry[0].addr, 746 rec->entry[0].addr_len); 745 pj_assert(rec->count != 0 && rec->entry[0].server.addr_count != 0); 746 pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 747 rec->entry[0].port); 748 pjsua_var.stun_srv.ipv4.sin_addr.s_addr = 749 rec->entry[0].server.addr[0].s_addr; 747 750 748 751 PJ_LOG(3,(THIS_FILE, "_stun._udp.%.*s resolved, found %d entry(s):", … … 755 758 " %d: prio=%d, weight=%d %s:%d", 756 759 i, rec->entry[i].priority, rec->entry[i].weight, 757 pj_inet_ntoa(rec->entry[i]. addr.ipv4.sin_addr),758 (int) pj_ntohs(rec->entry[i].addr.ipv4.sin_port)));760 pj_inet_ntoa(rec->entry[i].server.addr[0]), 761 (int)rec->entry[i].port)); 759 762 } 760 763 … … 794 797 pj_dns_srv_resolve(&pjsua_var.ua_cfg.stun_domain, &res_type, 795 798 3478, pjsua_var.pool, pjsua_var.resolver, 796 0, NULL, &stun_dns_srv_resolver_cb );799 0, NULL, &stun_dns_srv_resolver_cb, NULL); 797 800 if (status != PJ_SUCCESS) { 798 801 pjsua_perror(THIS_FILE, "Error starting DNS SRV resolution",
Note: See TracChangeset
for help on using the changeset viewer.