- Timestamp:
- Dec 28, 2016 3:40:07 AM (8 years ago)
- Location:
- pjproject/branches/projects/uwp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/uwp
- Property svn:mergeinfo changed
/pjproject/trunk (added) merged: 5209,5212-5234,5237-5253,5255,5257-5292,5294-5297,5299-5332,5334-5394,5396-5438,5440-5469,5471-5496,5498-5510
- Property svn:mergeinfo changed
-
pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_resolve.c
r5055 r5513 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 … … 169 176 pj_in6_addr dummy6; 170 177 171 /* First check with inet_aton()*/172 if (pj_inet_ aton(host, &dummy) > 0)178 /* First check if this is an IPv4 address */ 179 if (pj_inet_pton(pj_AF_INET(), host, &dummy) == PJ_SUCCESS) 173 180 return 4; 174 181 … … 196 203 struct query *query; 197 204 pjsip_transport_type_e type = target->type; 205 int af = pj_AF_UNSPEC(); 198 206 199 207 /* If an external implementation has been provided use it instead */ … … 205 213 /* Is it IP address or hostname? And if it's an IP, which version? */ 206 214 ip_addr_ver = get_ip_addr_ver(&target->addr.host); 215 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 */ 220 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6==1 221 if ((ip_addr_ver == 6) || (type & PJSIP_TRANSPORT_IPV6)) 222 af = pj_AF_INET6(); 223 else if (ip_addr_ver == 4) 224 af = pj_AF_INET(); 225 #else 226 /* IPv6 is disabled, will resolving IPv6 address be useful? */ 227 af = pj_AF_INET(); 228 #endif 207 229 208 230 /* Set the transport type if not explicitly specified. … … 242 264 } 243 265 } 244 245 /* Add IPv6 flag for IPv6 address */246 if (ip_addr_ver == 6)247 type = (pjsip_transport_type_e)((int)type + PJSIP_TRANSPORT_IPV6);248 266 } 249 267 … … 259 277 /* Target is an IP address, no need to resolve */ 260 278 if (ip_addr_ver == 4) { 261 pj_sockaddr_init(pj_AF_INET(), &svr_addr.entry[0].addr, 262 NULL, 0); 263 pj_inet_aton(&target->addr.host, 264 &svr_addr.entry[0].addr.ipv4.sin_addr); 279 if (af == pj_AF_INET6()) { 280 /* Generate a synthesized IPv6 address, if possible. */ 281 unsigned int count = 1; 282 pj_addrinfo ai[1]; 283 pj_status_t status; 284 285 status = pj_getaddrinfo(pj_AF_INET6(), 286 &target->addr.host, &count, ai); 287 if (status == PJ_SUCCESS && count > 0 && 288 ai[0].ai_addr.addr.sa_family == pj_AF_INET6()) 289 { 290 pj_sockaddr_init(pj_AF_INET6(), 291 &svr_addr.entry[0].addr, 292 NULL, 0); 293 svr_addr.entry[0].addr.ipv6.sin6_addr = 294 ai[0].ai_addr.ipv6.sin6_addr; 295 } else { 296 pj_sockaddr_init(pj_AF_INET(), 297 &svr_addr.entry[0].addr, NULL, 0); 298 pj_inet_pton(pj_AF_INET(), &target->addr.host, 299 &svr_addr.entry[0].addr.ipv4.sin_addr); 300 } 301 } else { 302 pj_sockaddr_init(pj_AF_INET(), &svr_addr.entry[0].addr, 303 NULL, 0); 304 pj_inet_pton(pj_AF_INET(), &target->addr.host, 305 &svr_addr.entry[0].addr.ipv4.sin_addr); 306 } 265 307 } else { 266 308 pj_sockaddr_init(pj_AF_INET6(), &svr_addr.entry[0].addr, … … 272 314 pj_addrinfo ai; 273 315 unsigned count; 274 int af;275 316 276 317 PJ_LOG(5,(THIS_FILE, … … 281 322 target->addr.port, 282 323 pjsip_transport_get_type_name(target->type))); 283 284 if (type & PJSIP_TRANSPORT_IPV6) {285 af = pj_AF_INET6();286 } else {287 af = pj_AF_INET();288 }289 324 290 325 /* Resolve */ … … 300 335 } 301 336 302 svr_addr.entry[0].addr.addr.sa_family = (pj_uint16_t)af; 303 pj_memcpy(&svr_addr.entry[0].addr, &ai.ai_addr, 304 sizeof(pj_sockaddr)); 305 } 337 pj_sockaddr_cp(&svr_addr.entry[0].addr, &ai.ai_addr); 338 if (af == pj_AF_UNSPEC()) 339 af = ai.ai_addr.addr.sa_family; 340 } 341 342 /* After address resolution, update IPv6 bitflag in transport type. */ 343 if (af == pj_AF_INET6()) 344 type |= PJSIP_TRANSPORT_IPV6; 306 345 307 346 /* Set the port number */ … … 330 369 svr_addr.entry[0].weight = 0; 331 370 svr_addr.entry[0].type = type; 332 svr_addr.entry[0].addr_len = pj_sockaddr_get_len(&svr_addr.entry[0].addr); 371 svr_addr.entry[0].addr_len = 372 pj_sockaddr_get_len(&svr_addr.entry[0].addr); 333 373 (*cb)(status, token, &svr_addr); 334 374 … … 368 408 query->req.def_port = 5060; 369 409 370 if (type == PJSIP_TRANSPORT_TLS ) {410 if (type == PJSIP_TRANSPORT_TLS || type == PJSIP_TRANSPORT_TLS6) { 371 411 query->naptr[0].res_type = pj_str("_sips._tcp."); 372 412 query->req.def_port = 5061; 373 } else if (type == PJSIP_TRANSPORT_TCP )413 } else if (type == PJSIP_TRANSPORT_TCP || type == PJSIP_TRANSPORT_TCP6) 374 414 query->naptr[0].res_type = pj_str("_sip._tcp."); 375 else if (type == PJSIP_TRANSPORT_UDP )415 else if (type == PJSIP_TRANSPORT_UDP || type == PJSIP_TRANSPORT_UDP6) 376 416 query->naptr[0].res_type = pj_str("_sip._udp."); 377 417 else { … … 402 442 403 443 if (query->query_type == PJ_DNS_TYPE_SRV) { 444 int opt = 0; 445 446 if (af == pj_AF_UNSPEC()) 447 opt = PJ_DNS_SRV_FALLBACK_A | PJ_DNS_SRV_FALLBACK_AAAA | 448 PJ_DNS_SRV_RESOLVE_AAAA; 449 else if (af == pj_AF_INET6()) 450 opt = PJ_DNS_SRV_FALLBACK_AAAA | PJ_DNS_SRV_RESOLVE_AAAA_ONLY; 451 else /* af == pj_AF_INET() */ 452 opt = PJ_DNS_SRV_FALLBACK_A; 404 453 405 454 status = pj_dns_srv_resolve(&query->naptr[0].name, 406 455 &query->naptr[0].res_type, 407 456 query->req.def_port, pool, resolver->res, 408 PJ_TRUE, query, &srv_resolver_cb, NULL);457 opt, query, &srv_resolver_cb, NULL); 409 458 410 459 } else if (query->query_type == PJ_DNS_TYPE_A) { 411 460 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); 461 /* Resolve DNS A record if address family is not fixed to IPv6 */ 462 if (af != pj_AF_INET6()) { 463 464 /* If there will be DNS AAAA query too, let's setup a dummy one 465 * here, otherwise app callback may be called immediately (before 466 * DNS AAAA query is sent) when DNS A record is available in the 467 * cache. 468 */ 469 if (af == pj_AF_UNSPEC()) 470 query->object6 = (pj_dns_async_query*)0x1; 471 472 status = pj_dns_resolver_start_query(resolver->res, 473 &query->naptr[0].name, 474 PJ_DNS_TYPE_A, 0, 475 &dns_a_callback, 476 query, &query->object); 477 } 478 479 /* Resolve DNS AAAA record if address family is not fixed to IPv4 */ 480 if (af != pj_AF_INET() && status == PJ_SUCCESS) { 481 status = pj_dns_resolver_start_query(resolver->res, 482 &query->naptr[0].name, 483 PJ_DNS_TYPE_AAAA, 0, 484 &dns_aaaa_callback, 485 query, &query->object6); 486 } 417 487 418 488 } else { … … 455 525 { 456 526 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 */ 527 pjsip_server_addresses *srv = &query->server; 528 529 /* Reset outstanding job */ 530 query->object = NULL; 531 464 532 if (status == PJ_SUCCESS) { 465 status = pj_dns_parse_a_response(pkt, &rec); 466 } 467 533 pj_dns_addr_record rec; 534 unsigned i; 535 536 /* Parse the response */ 537 rec.addr_count = 0; 538 status = pj_dns_parse_addr_response(pkt, &rec); 539 540 /* Build server addresses and call callback */ 541 for (i = 0; i < rec.addr_count && 542 srv->count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i) 543 { 544 /* Should not happen, just in case */ 545 if (rec.addr[i].af != pj_AF_INET()) 546 continue; 547 548 srv->entry[srv->count].type = query->naptr[0].type; 549 srv->entry[srv->count].priority = 0; 550 srv->entry[srv->count].weight = 0; 551 srv->entry[srv->count].addr_len = sizeof(pj_sockaddr_in); 552 pj_sockaddr_in_init(&srv->entry[srv->count].addr.ipv4, 553 0, (pj_uint16_t)query->req.def_port); 554 srv->entry[srv->count].addr.ipv4.sin_addr = rec.addr[i].ip.v4; 555 556 ++srv->count; 557 } 558 } 559 468 560 if (status != PJ_SUCCESS) { 469 561 char errmsg[PJ_ERR_MSG_SIZE]; … … 474 566 errmsg)); 475 567 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); 568 query->last_error = status; 569 } 570 571 /* Call the callback if all DNS queries have been completed */ 572 if (query->object == NULL && query->object6 == NULL) { 573 if (srv->count > 0) 574 (*query->cb)(PJ_SUCCESS, query->token, &query->server); 575 else 576 (*query->cb)(query->last_error, query->token, NULL); 577 } 578 } 579 580 581 /* 582 * This callback is called when target is resolved with DNS AAAA query. 583 */ 584 static void dns_aaaa_callback(void *user_data, 585 pj_status_t status, 586 pj_dns_parsed_packet *pkt) 587 { 588 struct query *query = (struct query*) user_data; 589 pjsip_server_addresses *srv = &query->server; 590 591 /* Reset outstanding job */ 592 query->object6 = NULL; 593 594 if (status == PJ_SUCCESS) { 595 pj_dns_addr_record rec; 596 unsigned i; 597 598 /* Parse the response */ 599 rec.addr_count = 0; 600 status = pj_dns_parse_addr_response(pkt, &rec); 601 602 /* Build server addresses and call callback */ 603 for (i = 0; i < rec.addr_count && 604 srv->count < PJSIP_MAX_RESOLVED_ADDRESSES; ++i) 605 { 606 /* Should not happen, just in case */ 607 if (rec.addr[i].af != pj_AF_INET6()) 608 continue; 609 610 srv->entry[srv->count].type = query->naptr[0].type | 611 PJSIP_TRANSPORT_IPV6; 612 srv->entry[srv->count].priority = 0; 613 srv->entry[srv->count].weight = 0; 614 srv->entry[srv->count].addr_len = sizeof(pj_sockaddr_in6); 615 pj_sockaddr_init(pj_AF_INET6(), &srv->entry[srv->count].addr, 616 0, (pj_uint16_t)query->req.def_port); 617 srv->entry[srv->count].addr.ipv6.sin6_addr = rec.addr[i].ip.v6; 618 619 ++srv->count; 620 } 621 } 622 623 if (status != PJ_SUCCESS) { 624 char errmsg[PJ_ERR_MSG_SIZE]; 625 626 /* Log error */ 627 pj_strerror(status, errmsg, sizeof(errmsg)); 628 PJ_LOG(4,(query->objname, "DNS AAAA record resolution failed: %s", 629 errmsg)); 630 631 query->last_error = status; 632 } 633 634 /* Call the callback if all DNS queries have been completed */ 635 if (query->object == NULL && query->object6 == NULL) { 636 if (srv->count > 0) 637 (*query->cb)(PJ_SUCCESS, query->token, &query->server); 638 else 639 (*query->cb)(query->last_error, query->token, NULL); 640 } 500 641 } 501 642 … … 515 656 /* Log error */ 516 657 pj_strerror(status, errmsg, sizeof(errmsg)); 517 PJ_LOG(4,(query->objname, "DNS A record resolution failed: %s",658 PJ_LOG(4,(query->objname, "DNS A/AAAA record resolution failed: %s", 518 659 errmsg)); 519 660 … … 526 667 srv.count = 0; 527 668 for (i=0; i<rec->count; ++i) { 669 const pj_dns_addr_record *s = &rec->entry[i].server; 528 670 unsigned j; 529 671 530 for (j = 0; j < rec->entry[i].server.addr_count &&672 for (j = 0; j < s->addr_count && 531 673 srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++j) 532 674 { … … 534 676 srv.entry[srv.count].priority = rec->entry[i].priority; 535 677 srv.entry[srv.count].weight = rec->entry[i].weight; 536 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; 678 pj_sockaddr_init(s->addr[j].af, 679 &srv.entry[srv.count].addr, 680 0, (pj_uint16_t)rec->entry[i].port); 681 if (s->addr[j].af == pj_AF_INET6()) 682 srv.entry[srv.count].addr.ipv6.sin6_addr = s->addr[j].ip.v6; 683 else 684 srv.entry[srv.count].addr.ipv4.sin_addr = s->addr[j].ip.v4; 685 srv.entry[srv.count].addr_len = 686 pj_sockaddr_get_len(&srv.entry[srv.count].addr); 687 688 /* Update transport type if this is IPv6 */ 689 if (s->addr[j].af == pj_AF_INET6()) 690 srv.entry[srv.count].type |= PJSIP_TRANSPORT_IPV6; 541 691 542 692 ++srv.count;
Note: See TracChangeset
for help on using the changeset viewer.