Changeset 5349 for pjproject/trunk/pjsip/src/pjsip/sip_resolve.c
- Timestamp:
- Jun 20, 2016 10:10:42 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_resolve.c
r5337 r5349 54 54 pjsip_resolver_callback *cb; 55 55 pj_dns_async_query *object; 56 pj_dns_async_query *object6; 56 57 pj_status_t last_error; 57 58 … … 65 66 unsigned naptr_cnt; 66 67 struct naptr_target naptr[8]; 68 69 /* Query result */ 70 pjsip_server_addresses server; 67 71 }; 68 72 … … 81 85 pj_status_t status, 82 86 pj_dns_parsed_packet *response); 87 static void dns_aaaa_callback(void *user_data, 88 pj_status_t status, 89 pj_dns_parsed_packet *response); 83 90 84 91 … … 207 214 ip_addr_ver = get_ip_addr_ver(&target->addr.host); 208 215 209 /* Initialize address family type */ 216 /* Initialize address family type. Unfortunately, target type doesn't 217 * really tell the address family type, except when IPv6 flag is 218 * explicitly set. 219 */ 210 220 if ((ip_addr_ver == 6) || (type & PJSIP_TRANSPORT_IPV6)) 211 221 af = pj_AF_INET6(); … … 402 412 403 413 if (query->query_type == PJ_DNS_TYPE_SRV) { 414 int opt = 0; 415 416 if (af == pj_AF_UNSPEC()) 417 opt = PJ_DNS_SRV_FALLBACK_A | PJ_DNS_SRV_FALLBACK_AAAA | 418 PJ_DNS_SRV_RESOLVE_AAAA; 419 else if (af == pj_AF_INET6()) 420 opt = PJ_DNS_SRV_FALLBACK_AAAA | PJ_DNS_SRV_RESOLVE_AAAA_ONLY; 421 else /* af == pj_AF_INET() */ 422 opt = PJ_DNS_SRV_FALLBACK_A; 404 423 405 424 status = pj_dns_srv_resolve(&query->naptr[0].name, 406 425 &query->naptr[0].res_type, 407 426 query->req.def_port, pool, resolver->res, 408 PJ_TRUE, query, &srv_resolver_cb, NULL);427 opt, query, &srv_resolver_cb, NULL); 409 428 410 429 } else if (query->query_type == PJ_DNS_TYPE_A) { 411 430 412 status = pj_dns_resolver_start_query(resolver->res, 413 &query->naptr[0].name, 414 PJ_DNS_TYPE_A, 0, 415 &dns_a_callback, 416 query, &query->object); 431 /* Resolve DNS A record if address family is not fixed to IPv6 */ 432 if (af != pj_AF_INET6()) { 433 status = pj_dns_resolver_start_query(resolver->res, 434 &query->naptr[0].name, 435 PJ_DNS_TYPE_A, 0, 436 &dns_a_callback, 437 query, &query->object); 438 } 439 440 /* Resolve DNS AAAA record if address family is not fixed to IPv4 */ 441 if (af != pj_AF_INET()) { 442 status = pj_dns_resolver_start_query(resolver->res, 443 &query->naptr[0].name, 444 PJ_DNS_TYPE_AAAA, 0, 445 &dns_aaaa_callback, 446 query, &query->object6); 447 } 417 448 418 449 } else { … … 455 486 { 456 487 struct query *query = (struct query*) user_data; 457 pjsip_server_addresses srv; 458 pj_dns_a_record rec; 459 unsigned i; 460 461 rec.addr_count = 0; 462 463 /* Parse the response */ 488 pjsip_server_addresses *srv = &query->server; 489 490 /* Reset outstanding job */ 491 query->object = NULL; 492 464 493 if (status == PJ_SUCCESS) { 465 status = pj_dns_parse_a_response(pkt, &rec); 466 } 467 468 if (status != PJ_SUCCESS) { 494 pj_dns_addr_record rec; 495 unsigned i; 496 497 /* Parse the response */ 498 rec.addr_count = 0; 499 status = pj_dns_parse_addr_response(pkt, &rec); 500 501 /* Build server addresses and call callback */ 502 for (i = 0; i < rec.addr_count && 503 srv->count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i) 504 { 505 /* Should not happen, just in case */ 506 if (rec.addr[i].af != pj_AF_INET()) 507 continue; 508 509 srv->entry[srv->count].type = query->naptr[0].type; 510 srv->entry[srv->count].priority = 0; 511 srv->entry[srv->count].weight = 0; 512 srv->entry[srv->count].addr_len = sizeof(pj_sockaddr_in); 513 pj_sockaddr_in_init(&srv->entry[srv->count].addr.ipv4, 514 0, (pj_uint16_t)query->req.def_port); 515 srv->entry[srv->count].addr.ipv4.sin_addr = rec.addr[i].ip.v4; 516 517 ++srv->count; 518 } 519 520 } else { 521 469 522 char errmsg[PJ_ERR_MSG_SIZE]; 470 523 … … 474 527 errmsg)); 475 528 476 /* Call the callback */ 477 (*query->cb)(status, query->token, NULL); 478 return; 479 } 480 481 /* Build server addresses and call callback */ 482 srv.count = 0; 483 for (i = 0; i < rec.addr_count && 484 srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i) 485 { 486 srv.entry[srv.count].type = query->naptr[0].type; 487 srv.entry[srv.count].priority = 0; 488 srv.entry[srv.count].weight = 0; 489 srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in); 490 pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4, 491 0, (pj_uint16_t)query->req.def_port); 492 srv.entry[srv.count].addr.ipv4.sin_addr.s_addr = 493 rec.addr[i].s_addr; 494 495 ++srv.count; 496 } 497 498 /* Call the callback */ 499 (*query->cb)(PJ_SUCCESS, query->token, &srv); 529 query->last_error = status; 530 } 531 532 /* Call the callback if all DNS queries have been completed */ 533 if (query->object == NULL && query->object6 == NULL) { 534 if (srv->count > 0) 535 (*query->cb)(PJ_SUCCESS, query->token, &query->server); 536 else 537 (*query->cb)(query->last_error, query->token, NULL); 538 } 539 } 540 541 542 /* 543 * This callback is called when target is resolved with DNS AAAA query. 544 */ 545 static void dns_aaaa_callback(void *user_data, 546 pj_status_t status, 547 pj_dns_parsed_packet *pkt) 548 { 549 struct query *query = (struct query*) user_data; 550 pjsip_server_addresses *srv = &query->server; 551 552 /* Reset outstanding job */ 553 query->object6 = NULL; 554 555 if (status == PJ_SUCCESS) { 556 pj_dns_addr_record rec; 557 unsigned i; 558 559 /* Parse the response */ 560 rec.addr_count = 0; 561 status = pj_dns_parse_addr_response(pkt, &rec); 562 563 /* Build server addresses and call callback */ 564 for (i = 0; i < rec.addr_count && 565 srv->count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i) 566 { 567 /* Should not happen, just in case */ 568 if (rec.addr[i].af != pj_AF_INET6()) 569 continue; 570 571 srv->entry[srv->count].type = query->naptr[0].type | 572 PJSIP_TRANSPORT_IPV6; 573 srv->entry[srv->count].priority = 0; 574 srv->entry[srv->count].weight = 0; 575 srv->entry[srv->count].addr_len = sizeof(pj_sockaddr_in); 576 pj_sockaddr_init(pj_AF_INET6(), &srv->entry[srv->count].addr, 577 0, (pj_uint16_t)query->req.def_port); 578 srv->entry[srv->count].addr.ipv6.sin6_addr = rec.addr[i].ip.v6; 579 580 ++srv->count; 581 } 582 583 } else { 584 585 char errmsg[PJ_ERR_MSG_SIZE]; 586 587 /* Log error */ 588 pj_strerror(status, errmsg, sizeof(errmsg)); 589 PJ_LOG(4,(query->objname, "DNS AAAA record resolution failed: %s", 590 errmsg)); 591 592 query->last_error = status; 593 } 594 595 /* Call the callback if all DNS queries have been completed */ 596 if (query->object == NULL && query->object6 == NULL) { 597 if (srv->count > 0) 598 (*query->cb)(PJ_SUCCESS, query->token, &query->server); 599 else 600 (*query->cb)(query->last_error, query->token, NULL); 601 } 500 602 } 501 603 … … 515 617 /* Log error */ 516 618 pj_strerror(status, errmsg, sizeof(errmsg)); 517 PJ_LOG(4,(query->objname, "DNS A record resolution failed: %s",619 PJ_LOG(4,(query->objname, "DNS A/AAAA record resolution failed: %s", 518 620 errmsg)); 519 621 … … 526 628 srv.count = 0; 527 629 for (i=0; i<rec->count; ++i) { 630 const pj_dns_addr_record *s = &rec->entry[i].server; 528 631 unsigned j; 529 632 530 for (j = 0; j < rec->entry[i].server.addr_count &&633 for (j = 0; j < s->addr_count && 531 634 srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++j) 532 635 { … … 535 638 srv.entry[srv.count].weight = rec->entry[i].weight; 536 639 srv.entry[srv.count].addr_len = sizeof(pj_sockaddr_in); 537 pj_sockaddr_in_init(&srv.entry[srv.count].addr.ipv4, 538 0, (pj_uint16_t)rec->entry[i].port); 539 srv.entry[srv.count].addr.ipv4.sin_addr.s_addr = 540 rec->entry[i].server.addr[j].s_addr; 640 pj_sockaddr_init(s->addr[j].af, 641 &srv.entry[srv.count].addr, 642 0, (pj_uint16_t)rec->entry[i].port); 643 if (s->addr[j].af == pj_AF_INET6()) 644 srv.entry[srv.count].addr.ipv6.sin6_addr = s->addr[j].ip.v6; 645 else 646 srv.entry[srv.count].addr.ipv4.sin_addr = s->addr[j].ip.v4; 647 648 /* Update transport type if this is IPv6 */ 649 if (s->addr[j].af == pj_AF_INET6()) 650 srv.entry[srv.count].type |= PJSIP_TRANSPORT_IPV6; 541 651 542 652 ++srv.count;
Note: See TracChangeset
for help on using the changeset viewer.