Ignore:
Timestamp:
Dec 28, 2016 3:40:07 AM (7 years ago)
Author:
nanang
Message:

Re #1900: More merged from trunk (r5512 mistakenly contains merged changes in third-party dir only).

Location:
pjproject/branches/projects/uwp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/uwp

  • pjproject/branches/projects/uwp/pjsip/src/pjsip/sip_resolve.c

    r5055 r5513  
    5454    pjsip_resolver_callback *cb; 
    5555    pj_dns_async_query      *object; 
     56    pj_dns_async_query      *object6; 
    5657    pj_status_t              last_error; 
    5758 
     
    6566    unsigned                 naptr_cnt; 
    6667    struct naptr_target      naptr[8]; 
     68 
     69    /* Query result */ 
     70    pjsip_server_addresses   server; 
    6771}; 
    6872 
     
    8185                           pj_status_t status, 
    8286                           pj_dns_parsed_packet *response); 
     87static void dns_aaaa_callback(void *user_data, 
     88                              pj_status_t status, 
     89                              pj_dns_parsed_packet *response); 
    8390 
    8491 
     
    169176    pj_in6_addr dummy6; 
    170177 
    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) 
    173180        return 4; 
    174181 
     
    196203    struct query *query; 
    197204    pjsip_transport_type_e type = target->type; 
     205    int af = pj_AF_UNSPEC(); 
    198206 
    199207    /* If an external implementation has been provided use it instead */ 
     
    205213    /* Is it IP address or hostname? And if it's an IP, which version? */ 
    206214    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 
    207229 
    208230    /* Set the transport type if not explicitly specified.  
     
    242264            } 
    243265        } 
    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); 
    248266    } 
    249267 
     
    259277            /* Target is an IP address, no need to resolve */ 
    260278            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                } 
    265307            } else { 
    266308                pj_sockaddr_init(pj_AF_INET6(), &svr_addr.entry[0].addr,  
     
    272314            pj_addrinfo ai; 
    273315            unsigned count; 
    274             int af; 
    275316 
    276317            PJ_LOG(5,(THIS_FILE, 
     
    281322                      target->addr.port, 
    282323                      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             } 
    289324 
    290325            /* Resolve */ 
     
    300335            } 
    301336 
    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; 
    306345 
    307346        /* Set the port number */ 
     
    330369        svr_addr.entry[0].weight = 0; 
    331370        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); 
    333373        (*cb)(status, token, &svr_addr); 
    334374 
     
    368408        query->req.def_port = 5060; 
    369409 
    370         if (type == PJSIP_TRANSPORT_TLS) { 
     410        if (type == PJSIP_TRANSPORT_TLS || type == PJSIP_TRANSPORT_TLS6) { 
    371411            query->naptr[0].res_type = pj_str("_sips._tcp."); 
    372412            query->req.def_port = 5061; 
    373         } else if (type == PJSIP_TRANSPORT_TCP) 
     413        } else if (type == PJSIP_TRANSPORT_TCP || type == PJSIP_TRANSPORT_TCP6) 
    374414            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) 
    376416            query->naptr[0].res_type = pj_str("_sip._udp."); 
    377417        else { 
     
    402442 
    403443    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; 
    404453 
    405454        status = pj_dns_srv_resolve(&query->naptr[0].name, 
    406455                                    &query->naptr[0].res_type, 
    407456                                    query->req.def_port, pool, resolver->res, 
    408                                     PJ_TRUE, query, &srv_resolver_cb, NULL); 
     457                                    opt, query, &srv_resolver_cb, NULL); 
    409458 
    410459    } else if (query->query_type == PJ_DNS_TYPE_A) { 
    411460 
    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        } 
    417487 
    418488    } else { 
     
    455525{ 
    456526    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 
    464532    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     
    468560    if (status != PJ_SUCCESS) { 
    469561        char errmsg[PJ_ERR_MSG_SIZE]; 
     
    474566                  errmsg)); 
    475567 
    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 */ 
     584static 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    } 
    500641} 
    501642 
     
    515656        /* Log error */ 
    516657        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", 
    518659                  errmsg)); 
    519660 
     
    526667    srv.count = 0; 
    527668    for (i=0; i<rec->count; ++i) { 
     669        const pj_dns_addr_record *s = &rec->entry[i].server; 
    528670        unsigned j; 
    529671 
    530         for (j = 0; j < rec->entry[i].server.addr_count && 
     672        for (j = 0; j < s->addr_count && 
    531673                    srv.count < PJSIP_MAX_RESOLVED_ADDRESSES; ++j) 
    532674        { 
     
    534676            srv.entry[srv.count].priority = rec->entry[i].priority; 
    535677            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; 
    541691 
    542692            ++srv.count; 
Note: See TracChangeset for help on using the changeset viewer.