Changeset 5636 for pjproject


Ignore:
Timestamp:
Aug 2, 2017 2:51:59 AM (7 years ago)
Author:
ming
Message:

Fixed #2032: NAT64 support for IPv4 interoperability

Location:
pjproject/trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/include/pjlib-util/stun_simple.h

    r4224 r5636  
    211211     */ 
    212212    pj_bool_t   use_stun2; 
     213     
     214    /** 
     215     * Address family of the STUN servers. 
     216     */ 
     217    int af; 
    213218 
    214219    /** 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_simple_client.c

    r5311 r5636  
    6464    const pj_str_t *srv1, *srv2; 
    6565    int port1, port2; 
    66     pj_sockaddr_in srv_addr[2]; 
     66    pj_sockaddr srv_addr[2]; 
    6767    int i, send_cnt = 0, nfds; 
    6868    pj_pool_t *pool; 
     
    117117 
    118118    /* Resolve servers. */ 
    119     status = pj_sockaddr_in_init(&srv_addr[0], srv1, (pj_uint16_t)port1); 
     119    status = pj_sockaddr_init(opt->af, &srv_addr[0], srv1, (pj_uint16_t)port1); 
    120120    if (status != PJ_SUCCESS) 
    121121        goto on_error; 
     
    124124 
    125125    if (srv2 && port2) { 
    126         status = pj_sockaddr_in_init(&srv_addr[1], srv2, (pj_uint16_t)port2); 
     126        status = pj_sockaddr_init(opt->af, &srv_addr[1], srv2, 
     127                                  (pj_uint16_t)port2); 
    127128        if (status != PJ_SUCCESS) 
    128129            goto on_error; 
    129130 
    130         if (srv_addr[1].sin_addr.s_addr != srv_addr[0].sin_addr.s_addr && 
    131             srv_addr[1].sin_port != srv_addr[0].sin_port) 
    132         { 
     131        if (pj_sockaddr_cmp(&srv_addr[1], &srv_addr[0]) != 0) { 
    133132            srv_cnt++; 
    134133        } 
     
    182181                status = pj_sock_sendto(sock[i], out_msg, &sent_len, 0, 
    183182                                        (pj_sockaddr_t*)&srv_addr[j], 
    184                                         sizeof(pj_sockaddr_in)); 
     183                                        pj_sockaddr_get_len(&srv_addr[j])); 
    185184            } 
    186185        } 
     
    222221                pj_ssize_t len; 
    223222                pjstun_msg msg; 
    224                 pj_sockaddr_in addr; 
     223                pj_sockaddr addr; 
    225224                int addrlen = sizeof(addr); 
    226225                pjstun_mapped_addr_attr *attr; 
  • pjproject/trunk/pjlib/include/pj/sock.h

    r5444 r5636  
    934934PJ_DECL(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src); 
    935935 
     936/* 
     937 * If the source's and desired address family matches, copy the address, 
     938 * otherwise synthesize a new address with the desired address family, 
     939 * from the source address. This can be useful to generate an IPv4-mapped 
     940 * IPv6 address. 
     941 * 
     942 * @param dst_af    Desired address family. 
     943 * @param dst       Destination socket address, invalid if synthesis is 
     944 *                  required and failed. 
     945 * @param src       Source socket address. 
     946 * 
     947 * @return          PJ_SUCCESS on success, or the error status 
     948 *                  if synthesis is required and failed. 
     949 */ 
     950PJ_DECL(pj_status_t) pj_sockaddr_synthesize(int dst_af, 
     951                                            pj_sockaddr_t *dst, 
     952                                            const pj_sockaddr_t *src); 
     953 
    936954/** 
    937955 * Get the IP address of an IPv4 socket address. 
  • pjproject/trunk/pjlib/src/pj/sock_common.c

    r5627 r5636  
    414414{ 
    415415    pj_memcpy(dst, src, pj_sockaddr_get_len(src)); 
     416} 
     417 
     418/* 
     419 * Synthesize address. 
     420 */ 
     421PJ_DEF(pj_status_t) pj_sockaddr_synthesize(int dst_af, 
     422                                           pj_sockaddr_t *dst, 
     423                                           const pj_sockaddr_t *src) 
     424{ 
     425    char ip_addr_buf[PJ_INET6_ADDRSTRLEN]; 
     426    unsigned int count = 1; 
     427    pj_addrinfo ai[1]; 
     428    pj_str_t ip_addr; 
     429    pj_status_t status; 
     430 
     431    /* Validate arguments */ 
     432    PJ_ASSERT_RETURN(src && dst, PJ_EINVAL); 
     433 
     434    if (dst_af == ((const pj_sockaddr *)src)->addr.sa_family) { 
     435        pj_sockaddr_cp(dst, src); 
     436        return PJ_SUCCESS; 
     437    } 
     438 
     439    pj_sockaddr_print(src, ip_addr_buf, sizeof(ip_addr_buf), 0); 
     440    ip_addr = pj_str(ip_addr_buf); 
     441     
     442    /* Try to synthesize address using pj_getaddrinfo(). */ 
     443    status = pj_getaddrinfo(dst_af, &ip_addr, &count, ai);  
     444    if (status == PJ_SUCCESS && count > 0) { 
     445        pj_sockaddr_cp(dst, &ai[0].ai_addr); 
     446        pj_sockaddr_set_port(dst, pj_sockaddr_get_port(src)); 
     447    } 
     448     
     449    return status; 
    416450} 
    417451 
  • pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c

    r5597 r5636  
    653653    struct transport_udp *udp = (struct transport_udp*) tp; 
    654654    const pj_sockaddr *rtcp_addr; 
     655    pj_sockaddr sock_addr, remote_addr, remote_rtcp; 
     656    int rem_addr_len; 
     657    pj_status_t status; 
    655658 
    656659    /* Validate arguments */ 
     
    668671    /* "Attach" the application: */ 
    669672 
     673    rem_addr_len = sizeof(pj_sockaddr); 
     674    pj_sock_getsockname(udp->rtp_sock, &sock_addr, &rem_addr_len); 
     675 
     676    /* Synthesize address, if necessary. */ 
     677    status = pj_sockaddr_synthesize(sock_addr.addr.sa_family, 
     678                                    &remote_addr, rem_addr); 
     679    if (status != PJ_SUCCESS) { 
     680        pj_perror(3, tp->name, status, "Failed to synthesize the correct" 
     681                                       "IP address for RTP"); 
     682    } 
     683    rem_addr_len = pj_sockaddr_get_len(&remote_addr); 
     684 
    670685    /* Copy remote RTP address */ 
    671     pj_memcpy(&udp->rem_rtp_addr, rem_addr, addr_len); 
     686    pj_memcpy(&udp->rem_rtp_addr, &remote_addr, rem_addr_len); 
    672687 
    673688    /* Copy remote RTP address, if one is specified. */ 
    674689    rtcp_addr = (const pj_sockaddr*) rem_rtcp; 
    675690    if (rtcp_addr && pj_sockaddr_has_addr(rtcp_addr)) { 
    676         pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, addr_len); 
     691        pj_status_t status; 
     692 
     693        status = pj_sockaddr_synthesize(sock_addr.addr.sa_family, 
     694                                        &remote_rtcp, rem_rtcp); 
     695        if (status != PJ_SUCCESS) { 
     696            pj_perror(3, tp->name, status, "Failed to synthesize the correct" 
     697                                           "IP address for RTCP"); 
     698        } 
     699        pj_memcpy(&udp->rem_rtcp_addr, &remote_rtcp, rem_addr_len); 
    677700 
    678701    } else { 
     
    680703 
    681704        /* Otherwise guess the RTCP address from the RTP address */ 
    682         pj_memcpy(&udp->rem_rtcp_addr, rem_addr, addr_len); 
     705        pj_memcpy(&udp->rem_rtcp_addr, &udp->rem_rtp_addr, rem_addr_len); 
    683706        rtcp_port = pj_sockaddr_get_port(&udp->rem_rtp_addr) + 1; 
    684707        pj_sockaddr_set_port(&udp->rem_rtcp_addr, (pj_uint16_t)rtcp_port); 
     
    691714 
    692715    /* Save address length */ 
    693     udp->addr_len = addr_len; 
     716    udp->addr_len = rem_addr_len; 
    694717 
    695718    /* Last, mark transport as attached */ 
  • pjproject/trunk/pjnath/src/pjnath/ice_session.c

    r5534 r5636  
    21862186    pj_ice_sess_checklist *clist; 
    21872187    pj_stun_xor_mapped_addr_attr *xaddr; 
     2188    const pj_sockaddr_t *source_addr = src_addr; 
    21882189    unsigned i; 
    21892190 
     
    22872288     * Request was sent from. 
    22882289     */ 
    2289     if (pj_sockaddr_cmp(&check->rcand->addr, (const pj_sockaddr*)src_addr)!=0) 
     2290    if (check->rcand->addr.addr.sa_family == pj_AF_INET() && 
     2291        ((pj_sockaddr *)src_addr)->addr.sa_family == pj_AF_INET6()) 
    22902292    { 
     2293        /* If the address family is different, we need to check 
     2294         * whether the two addresses are equivalent (i.e. the IPv6 
     2295         * is synthesized from IPv4). 
     2296         */ 
     2297        pj_sockaddr synth_addr; 
     2298        pj_status_t status; 
     2299         
     2300        status = pj_sockaddr_synthesize(pj_AF_INET6(), &synth_addr, 
     2301                                        &check->rcand->addr); 
     2302        if (status == PJ_SUCCESS && 
     2303            pj_sockaddr_cmp(&synth_addr, src_addr) == 0) 
     2304        { 
     2305            source_addr = &check->rcand->addr; 
     2306        } 
     2307    } 
     2308 
     2309    if (pj_sockaddr_cmp(&check->rcand->addr, source_addr) != 0) { 
    22912310        status = PJNATH_EICEINSRCADDR; 
    22922311        LOG4((ice->obj_name,  
     
    24752494    pj_stun_tx_data *tdata; 
    24762495    pj_ice_rx_check *rcheck, tmp_rcheck; 
     2496    const pj_sockaddr_t *source_addr = src_addr; 
     2497    unsigned source_addr_len = src_addr_len; 
    24772498    pj_status_t status; 
    24782499 
     
    25882609    } 
    25892610 
     2611    if (((pj_sockaddr *)src_addr)->addr.sa_family == pj_AF_INET6()) { 
     2612        unsigned i; 
     2613        unsigned transport_id = ((pj_ice_msg_data*)token)->transport_id; 
     2614        pj_ice_sess_cand *lcand = NULL; 
     2615 
     2616        for (i = 0; i < ice->clist.count; ++i) { 
     2617            pj_ice_sess_check *c = &ice->clist.checks[i]; 
     2618            if (c->lcand->comp_id == sd->comp_id && 
     2619                c->lcand->transport_id == transport_id)  
     2620            { 
     2621                lcand = c->lcand; 
     2622                break; 
     2623            } 
     2624        } 
     2625 
     2626        if (lcand != NULL && lcand->addr.addr.sa_family == pj_AF_INET()) { 
     2627            /* We are behind NAT64, so src_addr is a synthesized IPv6 
     2628             * address. Instead of putting this synth IPv6 address as 
     2629             * the XOR-MAPPED-ADDRESS, we need to find its original 
     2630             * IPv4 address. 
     2631             */ 
     2632            for (i = 0; i < ice->rcand_cnt; ++i) { 
     2633                pj_status_t status; 
     2634                pj_sockaddr synth_addr; 
     2635             
     2636                if (ice->rcand[i].addr.addr.sa_family != pj_AF_INET()) 
     2637                    continue; 
     2638 
     2639                status = pj_sockaddr_synthesize(pj_AF_INET6(), &synth_addr, 
     2640                                                &ice->rcand[i].addr); 
     2641                if (status == PJ_SUCCESS && 
     2642                    pj_sockaddr_cmp(src_addr, &synth_addr) == 0) 
     2643                { 
     2644                    /* We find the original IPv4 address. */ 
     2645                    source_addr = &ice->rcand[i].addr; 
     2646                    source_addr_len = pj_sockaddr_get_len(source_addr); 
     2647                    break; 
     2648                } 
     2649            } 
     2650        } 
     2651    } 
     2652 
     2653 
    25902654    /* Add XOR-MAPPED-ADDRESS attribute */ 
    25912655    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,  
    25922656                                           PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
    2593                                            PJ_TRUE, src_addr, src_addr_len); 
     2657                                           PJ_TRUE, source_addr, 
     2658                                           source_addr_len); 
    25942659 
    25952660    /* Create a msg_data to be associated with this response */ 
     
    26202685    rcheck->comp_id = sd->comp_id; 
    26212686    rcheck->transport_id = ((pj_ice_msg_data*)token)->transport_id; 
    2622     rcheck->src_addr_len = src_addr_len; 
    2623     pj_sockaddr_cp(&rcheck->src_addr, src_addr); 
     2687    rcheck->src_addr_len = source_addr_len; 
     2688    pj_sockaddr_cp(&rcheck->src_addr, source_addr); 
    26242689    rcheck->use_candidate = (uc_attr != NULL); 
    26252690    rcheck->priority = prio_attr->value; 
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r5604 r5636  
    168168    unsigned             cand_cnt;      /**< # of candidates/aliaes.    */ 
    169169    pj_ice_sess_cand     cand_list[PJ_ICE_ST_MAX_CAND]; /**< Cand array */ 
     170 
     171    pj_bool_t            ipv4_mapped;   /**< Is IPv6 addr mapped to IPv4?*/ 
     172    pj_sockaddr          dst_addr;      /**< Destination address        */ 
     173    pj_sockaddr          synth_addr;    /**< Synthesized dest address   */ 
     174    unsigned             synth_addr_len;/**< Synthesized dest addr len  */ 
    170175 
    171176    unsigned             default_cand;  /**< Default candidate.         */ 
     
    655660             */ 
    656661            if (comp->ice_st->cfg.af != pj_AF_UNSPEC() && 
    657                 comp->cand_list[comp->default_cand].addr.addr.sa_family != 
     662                addr->addr.sa_family == comp->ice_st->cfg.af && 
     663                comp->cand_list[comp->default_cand].base_addr.addr.sa_family != 
    658664                ice_st->cfg.af) 
    659665            { 
     
    11341140            /* Must have address */ 
    11351141            pj_assert(pj_sockaddr_has_addr(&cand->addr)); 
     1142 
     1143            /* Skip if we are mapped to IPv4 address and this candidate 
     1144             * is not IPv4. 
     1145             */ 
     1146            if (comp->ipv4_mapped && 
     1147                cand->addr.addr.sa_family != pj_AF_INET()) 
     1148            { 
     1149                continue; 
     1150            } 
    11361151 
    11371152            /* Add the candidate */ 
     
    15011516                    PJ_SUCCESS : status; 
    15021517        } else { 
     1518            const pj_sockaddr_t *dest_addr; 
     1519            unsigned dest_addr_len; 
     1520 
     1521            if (comp->ipv4_mapped) { 
     1522                if (comp->synth_addr_len == 0 || 
     1523                    pj_sockaddr_cmp(&comp->dst_addr, dst_addr) != 0) 
     1524                { 
     1525                    status = pj_sockaddr_synthesize(pj_AF_INET6(), 
     1526                                                    &comp->synth_addr, 
     1527                                                    dst_addr); 
     1528                    if (status != PJ_SUCCESS) 
     1529                        return status; 
     1530 
     1531                    pj_sockaddr_cp(&comp->dst_addr, dst_addr); 
     1532                    comp->synth_addr_len = pj_sockaddr_get_len( 
     1533                                               &comp->synth_addr); 
     1534                } 
     1535                dest_addr = &comp->synth_addr; 
     1536                dest_addr_len = comp->synth_addr_len; 
     1537            } else { 
     1538                dest_addr = dst_addr; 
     1539                dest_addr_len = dst_addr_len; 
     1540            } 
     1541 
    15031542            status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data, 
    1504                                          (unsigned)data_len, 0, dst_addr, 
    1505                                          dst_addr_len); 
     1543                                         (unsigned)data_len, 0, dest_addr, 
     1544                                         dest_addr_len); 
    15061545            return (status==PJ_SUCCESS||status==PJ_EPENDING) ? 
    15071546                    PJ_SUCCESS : status; 
     
    16501689        } 
    16511690    } else if (tp_typ == TP_STUN) { 
     1691        const pj_sockaddr_t *dest_addr; 
     1692        unsigned dest_addr_len; 
     1693 
     1694        if (comp->ipv4_mapped) { 
     1695            if (comp->synth_addr_len == 0 || 
     1696                pj_sockaddr_cmp(&comp->dst_addr, dst_addr) != 0) 
     1697            { 
     1698                status = pj_sockaddr_synthesize(pj_AF_INET6(), 
     1699                                                &comp->synth_addr, dst_addr); 
     1700                if (status != PJ_SUCCESS) 
     1701                    return status; 
     1702             
     1703                pj_sockaddr_cp(&comp->dst_addr, dst_addr); 
     1704                comp->synth_addr_len = pj_sockaddr_get_len(&comp->synth_addr); 
     1705            } 
     1706            dest_addr = &comp->synth_addr; 
     1707            dest_addr_len = comp->synth_addr_len; 
     1708        } else { 
     1709            dest_addr = dst_addr; 
     1710            dest_addr_len = dst_addr_len; 
     1711        } 
     1712 
    16521713        status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, 
    16531714                                     pkt, (unsigned)size, 0, 
    1654                                      dst_addr, dst_addr_len); 
     1715                                     dest_addr, dest_addr_len); 
    16551716    } else { 
    16561717        pj_assert(!"Invalid transport ID"); 
     
    18201881                pj_bool_t dup = PJ_FALSE; 
    18211882 
     1883                if (info.mapped_addr.addr.sa_family == pj_AF_INET() && 
     1884                    cand->base_addr.addr.sa_family == pj_AF_INET6()) 
     1885                { 
     1886                    /* We get an IPv4 mapped address for our IPv6 
     1887                     * host address. 
     1888                     */               
     1889                    comp->ipv4_mapped = PJ_TRUE; 
     1890 
     1891                    /* Find other host candidates with the same (IPv6) 
     1892                     * address, and replace it with the new (IPv4) 
     1893                     * mapped address. 
     1894                     */ 
     1895                    for (i = 0; i < comp->cand_cnt; ++i) { 
     1896                        pj_sockaddr *a1, *a2; 
     1897 
     1898                        if (comp->cand_list[i].type != PJ_ICE_CAND_TYPE_HOST) 
     1899                            continue; 
     1900                         
     1901                        a1 = &comp->cand_list[i].addr; 
     1902                        a2 = &cand->base_addr; 
     1903                        if (pj_memcmp(pj_sockaddr_get_addr(a1), 
     1904                                      pj_sockaddr_get_addr(a2), 
     1905                                      pj_sockaddr_get_addr_len(a1)) == 0) 
     1906                        { 
     1907                            pj_uint16_t port = pj_sockaddr_get_port(a1); 
     1908                            pj_sockaddr_cp(a1, &info.mapped_addr); 
     1909                            if (port != pj_sockaddr_get_port(a2)) 
     1910                                pj_sockaddr_set_port(a1, port); 
     1911                            pj_sockaddr_cp(&comp->cand_list[i].base_addr, a1); 
     1912                        } 
     1913                    } 
     1914                    pj_sockaddr_cp(&cand->base_addr, &info.mapped_addr); 
     1915                    pj_sockaddr_cp(&cand->rel_addr, &info.mapped_addr); 
     1916                } 
     1917                 
    18221918                /* Eliminate the srflx candidate if the address is 
    18231919                 * equal to other (host) candidates. 
  • pjproject/trunk/pjnath/src/pjnath/nat_detect.c

    r5523 r5636  
    8989    pj_sockaddr              server; 
    9090    pj_sockaddr             *cur_server; 
     91    pj_sockaddr              cur_addr; 
    9192    pj_stun_session         *stun_sess; 
    9293 
     
    855856        goto on_error; 
    856857 
    857     /* Configure alternate address */ 
    858     if (alt_addr) 
    859         sess->cur_server = (pj_sockaddr*) alt_addr; 
    860     else 
     858    /* Configure alternate address, synthesize it if necessary */ 
     859    if (alt_addr) { 
     860        status = pj_sockaddr_synthesize(sess->server.addr.sa_family, 
     861                                        &sess->cur_addr, alt_addr); 
     862        if (status != PJ_SUCCESS) 
     863            goto on_error; 
     864 
     865        sess->cur_server = &sess->cur_addr; 
     866    } else { 
    861867        sess->cur_server = &sess->server; 
     868    } 
    862869 
    863870    PJ_LOG(5,(sess->pool->obj_name,  
  • pjproject/trunk/pjnath/src/pjnath/turn_session.c

    r5635 r5636  
    678678            pj_memcpy(addr, &ai[i].ai_addr, sizeof(pj_sockaddr)); 
    679679            addr->addr.sa_family = sess->af; 
    680             addr->ipv4.sin_port = pj_htons(sess->default_port); 
     680            pj_sockaddr_set_port(addr, sess->default_port); 
    681681        } 
    682682 
  • pjproject/trunk/pjsip-apps/src/swig/symbols.i

    r5518 r5636  
    154154typedef enum pjsua_ipv6_use {PJSUA_IPV6_DISABLED, PJSUA_IPV6_ENABLED} pjsua_ipv6_use; 
    155155 
     156typedef enum pjsua_nat64_opt {PJSUA_NAT64_DISABLED, PJSUA_NAT64_ENABLED} pjsua_nat64_opt; 
     157 
    156158typedef enum pjsua_buddy_status {PJSUA_BUDDY_STATUS_UNKNOWN, PJSUA_BUDDY_STATUS_ONLINE, PJSUA_BUDDY_STATUS_OFFLINE} pjsua_buddy_status; 
    157159 
  • pjproject/trunk/pjsip-apps/src/swig/symbols.lst

    r5518 r5636  
    3434pjsip-ua/sip_inv.h              pjsip_inv_state 
    3535 
    36 pjsua-lib/pjsua.h               pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag pjsua_snd_dev_mode 
     36pjsua-lib/pjsua.h               pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_nat64_opt pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag pjsua_snd_dev_mode 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r5597 r5636  
    15961596 
    15971597    /** 
     1598     * This specifies if the library should try to do an IPv6 resolution of 
     1599     * the STUN servers if the IPv4 resolution fails. It can be useful 
     1600     * in an IPv6-only environment, including on NAT64. 
     1601     * 
     1602     * Default: PJ_FALSE 
     1603     */ 
     1604    pj_bool_t       stun_try_ipv6; 
     1605 
     1606    /** 
    15981607     * This specifies if the library should ignore failure with the 
    15991608     * STUN servers. If this is set to PJ_FALSE, the library will refuse to 
     
    29112920 
    29122921/** 
     2922 * Specify NAT64 options to be used in account config. 
     2923 */ 
     2924typedef enum pjsua_nat64_opt 
     2925{ 
     2926    /** 
     2927     * NAT64 is not used. 
     2928     */ 
     2929    PJSUA_NAT64_DISABLED, 
     2930 
     2931    /** 
     2932     * NAT64 is enabled. 
     2933     */ 
     2934    PJSUA_NAT64_ENABLED 
     2935     
     2936} pjsua_nat64_opt; 
     2937 
     2938/** 
    29132939 * This structure describes account configuration to be specified when 
    29142940 * adding a new account with #pjsua_acc_add(). Application MUST initialize 
     
    33463372     */ 
    33473373    pjsua_transport_config rtp_cfg; 
     3374 
     3375    /** 
     3376     * Specify NAT64 options. 
     3377     * 
     3378     * Default: PJSUA_NAT64_DISABLED 
     3379     */ 
     3380    pjsua_nat64_opt             nat64_opt; 
    33483381 
    33493382    /** 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h

    r5442 r5636  
    375375    pj_sockaddr          addr;      /**< Result             */ 
    376376    pj_stun_sock        *stun_sock; /**< Testing STUN sock  */ 
     377    int                  af;        /**< Address family     */ 
    377378    pj_bool_t            async_wait;/**< Async resolution  
    378379                                         of STUN entry      */ 
  • pjproject/trunk/pjsip/include/pjsua2/account.hpp

    r5455 r5636  
    470470 
    471471    /** 
     472     * Specify NAT64 options. 
     473     * 
     474     * Default: PJSUA_NAT64_DISABLED 
     475     */ 
     476    pjsua_nat64_opt     nat64Opt; 
     477 
     478    /** 
    472479     * Enable ICE for the media transport. 
    473480     * 
  • pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp

    r5522 r5636  
    391391    StringVector        stunServer; 
    392392 
     393    /** 
     394     * This specifies if the library should try to do an IPv6 resolution of 
     395     * the STUN servers if the IPv4 resolution fails. It can be useful 
     396     * in an IPv6-only environment, including on NAT64. 
     397     * 
     398     * Default: FALSE 
     399     */ 
     400 
     401    bool                stunTryIpv6; 
    393402    /** 
    394403     * This specifies if the library startup should ignore failure with the 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c

    r5519 r5636  
    701701    pj_pool_t *pool; 
    702702    struct udp_transport *tp; 
    703     const char *format, *ipv6_quoteb, *ipv6_quotee; 
     703    const char *format, *ipv6_quoteb = "", *ipv6_quotee = ""; 
    704704    unsigned i; 
    705705    pj_status_t status; 
     
    710710    /* Object name. */ 
    711711    if (type & PJSIP_TRANSPORT_IPV6) { 
     712        pj_in6_addr dummy6; 
     713 
    712714        format = "udpv6%p"; 
    713         ipv6_quoteb = "["; 
    714         ipv6_quotee = "]"; 
     715        /* We don't need to add quote if the transport type is IPv6, but 
     716         * actually translated to IPv4. 
     717         */ 
     718        if (pj_inet_pton(pj_AF_INET6(), &a_name->host, &dummy6)==PJ_SUCCESS) { 
     719            ipv6_quoteb = "["; 
     720            ipv6_quotee = "]"; 
     721        } 
    715722    } else { 
    716723        format = "udp%p"; 
    717         ipv6_quoteb = ipv6_quotee = ""; 
    718724    } 
    719725 
  • pjproject/trunk/pjsip/src/pjsip/sip_util.c

    r5555 r5636  
    12201220         */ 
    12211221        if (tdata->via_addr.host.slen > 0 && 
    1222             (tdata->via_tp == (void *)stateless_data->cur_transport || 
     1222            (!tdata->via_tp || 
     1223             tdata->via_tp == (void *)stateless_data->cur_transport || 
    12231224             tdata->msg->line.req.method.id == PJSIP_CANCEL_METHOD)) 
    12241225        { 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r5579 r5636  
    3333 
    3434 
     35static int get_ip_addr_ver(const pj_str_t *host); 
    3536static void schedule_reregistration(pjsua_acc *acc); 
    3637static void keep_alive_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te); 
     
    548549 
    549550    /* Enclose IPv6 address in square brackets */ 
    550     if (t->type & PJSIP_TRANSPORT_IPV6) { 
     551    if (get_ip_addr_ver(&t->local_name.host) == 6) { 
    551552        beginquote = "["; 
    552553        endquote = "]"; 
     
    13261327    } 
    13271328 
     1329    acc->cfg.nat64_opt = cfg->nat64_opt; 
    13281330    acc->cfg.ipv6_media_use = cfg->ipv6_media_use; 
    13291331 
     
    16971699        /* Compare the addresses as sockaddr according to the ticket above, 
    16981700         * but only if they have the same family (ipv4 vs ipv4, or 
    1699          * ipv6 vs ipv6) 
     1701         * ipv6 vs ipv6). 
     1702         * Checking for the same address family is currently disabled, 
     1703         * since it can be useful in cases such as when on NAT64, 
     1704         * in order to get the IPv4-mapped address from IPv6. 
    17001705         */ 
    1701         matched = (contact_addr.addr.sa_family != recv_addr.addr.sa_family) || 
     1706        matched = //(contact_addr.addr.sa_family != recv_addr.addr.sa_family)|| 
    17021707                  (uri->port == rport && 
    17031708                   pj_sockaddr_cmp(&contact_addr, &recv_addr)==0); 
     
    31153120    pjsip_tpmgr *tpmgr; 
    31163121    pjsip_tpmgr_fla2_param tfla2_prm; 
     3122    pj_bool_t update_addr = PJ_TRUE; 
    31173123 
    31183124    PJ_ASSERT_RETURN(pjsua_acc_is_valid(acc_id), PJ_EINVAL); 
     
    31833189    addr->host = tfla2_prm.ret_addr; 
    31843190    addr->port = tfla2_prm.ret_port; 
     3191 
     3192    /* If we are behind NAT64, use the Contact and Via address from 
     3193     * the UDP6 transport, which should be obtained from STUN. 
     3194     */ 
     3195    if (acc->cfg.nat64_opt != PJSUA_NAT64_DISABLED) { 
     3196        pjsip_tpmgr_fla2_param tfla2_prm2 = tfla2_prm; 
     3197         
     3198        tfla2_prm2.tp_type = PJSIP_TRANSPORT_UDP6; 
     3199        tfla2_prm2.tp_sel = NULL; 
     3200        tfla2_prm2.local_if = (!pjsua_sip_acc_is_using_stun(acc_id)); 
     3201        status = pjsip_tpmgr_find_local_addr2(tpmgr, pool, &tfla2_prm2); 
     3202        if (status == PJ_SUCCESS) { 
     3203            update_addr = PJ_FALSE; 
     3204            addr->host = tfla2_prm2.ret_addr; 
     3205            pj_strdup(acc->pool, &acc->via_addr.host, &addr->host); 
     3206            acc->via_addr.port = addr->port; 
     3207            acc->via_tp = (pjsip_transport *)tfla2_prm.ret_tp; 
     3208        } 
     3209    } 
    31853210 
    31863211    /* For TCP/TLS, acc may request to specify source port */ 
     
    32773302 
    32783303        if (status == PJ_SUCCESS) { 
    3279             /* Got the local transport address */ 
    3280             pj_strdup(pool, &addr->host, &tp->local_name.host); 
     3304            /* Got the local transport address, don't update if 
     3305             * we are on NAT64 and already obtained the address 
     3306             * from STUN above. 
     3307             */ 
     3308            if (update_addr) 
     3309                pj_strdup(pool, &addr->host, &tp->local_name.host); 
    32813310            addr->port = tp->local_name.port; 
    32823311        } 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r5449 r5636  
    12981298        stun_resolve_add_ref(sess); 
    12991299 
    1300         ++sess->idx; 
    1301         if (sess->idx >= sess->count) 
    1302             sess->status = status; 
     1300        if (pjsua_var.ua_cfg.stun_try_ipv6 && sess->af == pj_AF_INET()) { 
     1301            sess->af = pj_AF_INET6(); 
     1302        } else { 
     1303            ++sess->idx; 
     1304            sess->af = pj_AF_INET(); 
     1305            if (sess->idx >= sess->count) 
     1306                sess->status = status; 
     1307        } 
    13031308 
    13041309        resolve_stun_entry(sess); 
     
    13401345 
    13411346    /* Loop while we have entry to try */ 
    1342     for (; sess->idx < sess->count; ++sess->idx) { 
     1347    for (; sess->idx < sess->count; 
     1348         (pjsua_var.ua_cfg.stun_try_ipv6 && sess->af == pj_AF_INET())? 
     1349         sess->af = pj_AF_INET6(): (++sess->idx, sess->af = pj_AF_INET())) 
     1350    { 
    13431351        int af; 
    13441352        char target[64]; 
     
    13591367            PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %s", target)); 
    13601368            continue; 
    1361         } else if (af != pj_AF_INET()) { 
    1362             /* Ignore IPv6 STUN server for now */ 
    1363             status = PJ_EAFNOTSUP; 
    1364             PJ_LOG(3,(THIS_FILE, "Ignored STUN server entry %s, currently " 
    1365                                  "only IPv4 STUN server is supported (does " 
    1366                                  "IPv6 still need a mapped address?)", 
    1367                       target)); 
    1368             continue; 
    13691369        } 
    13701370         
     
    13751375        pj_assert(sess->stun_sock == NULL); 
    13761376 
    1377         PJ_LOG(4,(THIS_FILE, "Trying STUN server %s (%d of %d)..", 
    1378                   target, sess->idx+1, sess->count)); 
     1377        PJ_LOG(4,(THIS_FILE, "Trying STUN server %s %s (%d of %d)..", 
     1378                  target, (sess->af == pj_AF_INET()? "IPv4": "IPv6"), 
     1379                  sess->idx+1, sess->count)); 
    13791380 
    13801381        /* Use STUN_sock to test this entry */ 
     
    13831384        sess->async_wait = PJ_FALSE; 
    13841385        status = pj_stun_sock_create(&pjsua_var.stun_cfg, "stunresolve", 
    1385                                      pj_AF_INET(), &stun_sock_cb, 
     1386                                     sess->af, &stun_sock_cb, 
    13861387                                     NULL, sess, &sess->stun_sock); 
    13871388        if (status != PJ_SUCCESS) { 
     
    14891490    sess->waiter = pj_thread_this(); 
    14901491    sess->status = PJ_EPENDING; 
     1492    sess->af = pj_AF_INET(); 
    14911493    sess->srv = (pj_str_t*) pj_pool_calloc(pool, count, sizeof(pj_str_t)); 
    14921494    for (i=0; i<count; ++i) { 
     
    21582160            pj_sockaddr_set_port(p_pub_addr, (pj_uint16_t)port); 
    21592161 
    2160     } else if (stun_srv.slen && af == pj_AF_INET()) { 
     2162    } else if (stun_srv.slen && 
     2163               (af == pj_AF_INET() || pjsua_var.ua_cfg.stun_try_ipv6)) 
     2164    { 
    21612165        pjstun_setting stun_opt; 
    21622166 
    21632167        /* 
    21642168         * STUN is specified, resolve the address with STUN. 
    2165          * Currently, this is available for IPv4 address only. 
     2169         * Currently, this is only to get IPv4 mapped address 
     2170         * (does IPv6 still need a mapped address?). 
    21662171         */ 
    21672172        pj_bzero(&stun_opt, sizeof(stun_opt)); 
    21682173        stun_opt.use_stun2 = pjsua_var.ua_cfg.stun_map_use_stun2; 
     2174        stun_opt.af = pjsua_var.stun_srv.addr.sa_family; 
    21692175        stun_opt.srv1  = stun_opt.srv2  = stun_srv; 
    21702176        stun_opt.port1 = stun_opt.port2 =  
    2171                          pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port); 
     2177                         pj_sockaddr_get_port(&pjsua_var.stun_srv); 
    21722178        status = pjstun_get_mapped_addr2(&pjsua_var.cp.factory, &stun_opt, 
    21732179                                         1, &sock, &p_pub_addr->ipv4); 
     
    28952901 
    28962902    /* Make sure we have STUN */ 
    2897     if (pjsua_var.stun_srv.ipv4.sin_family == 0) { 
     2903    if (pjsua_var.stun_srv.addr.sa_family == 0) { 
    28982904        pjsua_var.nat_status = PJNATH_ESTUNINSERVER; 
    28992905        return PJNATH_ESTUNINSERVER; 
    29002906    } 
    29012907 
    2902     status = pj_stun_detect_nat_type(&pjsua_var.stun_srv.ipv4,  
    2903                                      &pjsua_var.stun_cfg,  
    2904                                      NULL, &nat_detect_cb); 
     2908    status = pj_stun_detect_nat_type2(&pjsua_var.stun_srv,  
     2909                                      &pjsua_var.stun_cfg,  
     2910                                      NULL, &nat_detect_cb); 
    29052911 
    29062912    if (status != PJ_SUCCESS) { 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r5597 r5636  
    241241    }; 
    242242    int i; 
    243     pj_bool_t use_ipv6; 
     243    pj_bool_t use_ipv6, use_nat64; 
    244244    int af; 
    245245    pj_sockaddr bound_addr; 
     
    251251 
    252252    use_ipv6 = (acc->cfg.ipv6_media_use != PJSUA_IPV6_DISABLED); 
    253     af = use_ipv6 ? pj_AF_INET6() : pj_AF_INET(); 
     253    use_nat64 = (acc->cfg.nat64_opt != PJSUA_NAT64_DISABLED); 
     254    af = (use_ipv6 || use_nat64) ? pj_AF_INET6() : pj_AF_INET(); 
    254255 
    255256    /* Make sure STUN server resolution has completed */ 
    256     if (!use_ipv6 && pjsua_media_acc_is_using_stun(call_med->call->acc_id)) { 
     257    if ((!use_ipv6 || use_nat64) && 
     258        pjsua_media_acc_is_using_stun(call_med->call->acc_id)) 
     259    { 
    257260        pj_bool_t retry_stun = (acc->cfg.media_stun_use & 
    258261                                PJSUA_STUN_RETRY_ON_FAILURE) == 
     
    354357         * and make sure that the mapped RTCP port is adjacent with the RTP. 
    355358         */ 
    356         if (!use_ipv6 && 
     359        if ((!use_ipv6 || use_nat64) && 
    357360            pjsua_media_acc_is_using_stun(call_med->call->acc_id) && 
    358361            pjsua_var.stun_srv.addr.sa_family != 0) 
    359362        { 
    360             char ip_addr[32]; 
     363            char ip_addr[PJ_INET6_ADDRSTRLEN]; 
    361364            pj_str_t stun_srv; 
    362365            pj_sockaddr_in resolved_addr[2]; 
     
    368371            pj_bzero(&stun_opt, sizeof(stun_opt)); 
    369372            stun_opt.use_stun2 = pjsua_var.ua_cfg.stun_map_use_stun2; 
     373            stun_opt.af = pjsua_var.stun_srv.addr.sa_family; 
    370374            stun_opt.srv1  = stun_opt.srv2  = stun_srv; 
    371375            stun_opt.port1 = stun_opt.port2 =  
    372                              pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port); 
     376                             pj_sockaddr_get_port(&pjsua_var.stun_srv); 
    373377            status=pjstun_get_mapped_addr2(&pjsua_var.cp.factory, &stun_opt, 
    374378                                           2, sock, resolved_addr); 
     
    433437                    } 
    434438             
     439                    stun_opt.af = pjsua_var.stun_srv.addr.sa_family; 
    435440                    stun_opt.srv1  = stun_opt.srv2  = stun_srv; 
    436441                    stun_opt.port1 = stun_opt.port2 =  
    437                                 pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port); 
     442                                pj_sockaddr_get_port(&pjsua_var.stun_srv); 
    438443                    status = pjstun_get_mapped_addr2(&pjsua_var.cp.factory, 
    439444                                                     &stun_opt, 2, sock, 
     
    824829    unsigned comp_cnt; 
    825830    pj_status_t status; 
    826     pj_bool_t use_ipv6; 
     831    pj_bool_t use_ipv6, use_nat64; 
    827832 
    828833    acc_cfg = &pjsua_var.acc[call_med->call->acc_id].cfg; 
    829834    use_ipv6 = (acc_cfg->ipv6_media_use != PJSUA_IPV6_DISABLED); 
     835    use_nat64 = (acc_cfg->nat64_opt != PJSUA_NAT64_DISABLED); 
    830836 
    831837    /* Make sure STUN server resolution has completed */ 
     
    864870        if (pj_stricmp(&c->addr_type, &ID_IP6) == 0) 
    865871            ice_cfg.af = pj_AF_INET6(); 
    866     } else if (use_ipv6) { 
     872    } else if (use_ipv6 || use_nat64) { 
    867873        ice_cfg.af = pj_AF_INET6(); 
    868874    } 
     
    875881        ice_cfg.stun_tp_cnt = 1; 
    876882        pj_ice_strans_stun_cfg_default(&ice_cfg.stun_tp[0]); 
    877         if (use_ipv6 && PJ_ICE_MAX_STUN >= 2) { 
     883        if (use_nat64) { 
     884            ice_cfg.stun_tp[0].af = pj_AF_INET6(); 
     885        } else if (use_ipv6 && PJ_ICE_MAX_STUN >= 2) { 
    878886            ice_cfg.stun_tp_cnt = 2; 
    879887            pj_ice_strans_stun_cfg_default(&ice_cfg.stun_tp[1]); 
     
    886894        unsigned i; 
    887895 
    888         /* Configure STUN server (currently only for IPv4) */ 
    889         if (pj_sockaddr_has_addr(&pjsua_var.stun_srv) && 
    890             pjsua_media_acc_is_using_stun(call_med->call->acc_id)) 
    891         { 
    892             pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0); 
    893             ice_cfg.stun_tp[0].server = pj_str(stunip); 
    894             ice_cfg.stun_tp[0].port =  
    895                                     pj_sockaddr_get_port(&pjsua_var.stun_srv); 
    896         } 
    897  
    898         /* Configure max host candidates */ 
    899         if (acc_cfg->ice_cfg.ice_max_host_cands >= 0) { 
    900             for (i = 0; i < ice_cfg.stun_tp_cnt; ++i) 
     896        pj_sockaddr_print(&pjsua_var.stun_srv, stunip, sizeof(stunip), 0); 
     897 
     898        for (i = 0; i < ice_cfg.stun_tp_cnt; ++i) { 
     899            pj_str_t IN6_ADDR_ANY = {"0", 1}; 
     900 
     901            /* Configure STUN server */ 
     902            if (pj_sockaddr_has_addr(&pjsua_var.stun_srv) && 
     903                pjsua_media_acc_is_using_stun(call_med->call->acc_id)) 
     904            { 
     905                ice_cfg.stun_tp[i].server = pj_str(stunip); 
     906                ice_cfg.stun_tp[i].port = pj_sockaddr_get_port( 
     907                                              &pjsua_var.stun_srv); 
     908            } 
     909 
     910            /* Configure max host candidates */ 
     911            if (acc_cfg->ice_cfg.ice_max_host_cands >= 0) { 
    901912                ice_cfg.stun_tp[i].max_host_cands = 
    902913                                acc_cfg->ice_cfg.ice_max_host_cands; 
    903         } 
    904  
    905         /* Configure binding address */ 
    906         pj_sockaddr_init(ice_cfg.stun_tp[0].af, 
    907                          &ice_cfg.stun_tp[0].cfg.bound_addr, 
    908                          &cfg->bound_addr, (pj_uint16_t)cfg->port); 
    909         ice_cfg.stun_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range; 
    910         if (cfg->port != 0 && ice_cfg.stun_tp[0].cfg.port_range == 0) { 
    911             ice_cfg.stun_tp[0].cfg.port_range =  
     914            } 
     915 
     916            /* Configure binding address */ 
     917            pj_sockaddr_init(ice_cfg.stun_tp[i].af, 
     918                             &ice_cfg.stun_tp[i].cfg.bound_addr, 
     919                             (ice_cfg.stun_tp[i].af == pj_AF_INET()? 
     920                             &cfg->bound_addr: &IN6_ADDR_ANY), 
     921                             (pj_uint16_t)cfg->port); 
     922            ice_cfg.stun_tp[i].cfg.port_range = (pj_uint16_t)cfg->port_range; 
     923            if (cfg->port != 0 && ice_cfg.stun_tp[i].cfg.port_range == 0) { 
     924                ice_cfg.stun_tp[i].cfg.port_range =  
    912925                            (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10); 
    913         } 
    914         if (use_ipv6 && ice_cfg.stun_tp_cnt > 1) { 
    915             pj_str_t IN6_ADDR_ANY = {"0", 1}; 
    916             pj_sockaddr_init(pj_AF_INET6(), 
    917                              &ice_cfg.stun_tp[1].cfg.bound_addr, 
    918                              &IN6_ADDR_ANY, (pj_uint16_t)cfg->port); 
    919             ice_cfg.stun_tp[1].cfg.port_range = 
    920                             ice_cfg.stun_tp[0].cfg.port_range; 
    921         } 
    922  
    923         /* Configure QoS setting */ 
    924         ice_cfg.stun_tp[0].cfg.qos_type = cfg->qos_type; 
    925         pj_memcpy(&ice_cfg.stun_tp[0].cfg.qos_params, &cfg->qos_params, 
    926                   sizeof(cfg->qos_params)); 
    927         if (use_ipv6 && ice_cfg.stun_tp_cnt > 1) { 
    928             ice_cfg.stun_tp[1].cfg.qos_type = cfg->qos_type; 
    929             pj_memcpy(&ice_cfg.stun_tp[1].cfg.qos_params, &cfg->qos_params, 
     926            } 
     927 
     928            /* Configure QoS setting */ 
     929            ice_cfg.stun_tp[i].cfg.qos_type = cfg->qos_type; 
     930            pj_memcpy(&ice_cfg.stun_tp[i].cfg.qos_params, &cfg->qos_params, 
    930931                      sizeof(cfg->qos_params)); 
    931         } 
    932  
    933         /* Configure max packet size */ 
    934         ice_cfg.stun_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    935         if (use_ipv6 && ice_cfg.stun_tp_cnt > 1) 
    936             ice_cfg.stun_tp[1].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    937  
     932 
     933            /* Configure max packet size */ 
     934            ice_cfg.stun_tp[i].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
     935        } 
    938936    } 
    939937 
    940938    /* Configure TURN settings */ 
    941939    if (acc_cfg->turn_cfg.enable_turn) { 
    942         ice_cfg.turn_tp_cnt = 1; 
    943         pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[0]); 
    944         if (use_ipv6 && PJ_ICE_MAX_TURN >= 3) { 
    945             ice_cfg.turn_tp_cnt = 3; 
    946  
    947             pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[1]); 
    948             ice_cfg.turn_tp[1].af = pj_AF_INET6(); 
     940        unsigned i, idx = 0; 
     941         
     942        if (use_ipv6 && !use_nat64 && PJ_ICE_MAX_TURN >= 3) { 
     943            ice_cfg.turn_tp_cnt = 3; 
     944            idx = 1; 
     945        } else { 
     946            ice_cfg.turn_tp_cnt = 1; 
     947        } 
     948         
     949        for (i = 0; i < ice_cfg.turn_tp_cnt; i++) 
     950            pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[i]); 
     951 
     952        if (use_ipv6 || use_nat64) { 
     953            if (!use_nat64) 
     954                ice_cfg.turn_tp[idx++].af = pj_AF_INET6(); 
    949955 
    950956            /* Additional candidate: IPv4 relay via IPv6 TURN server */ 
    951             pj_ice_strans_turn_cfg_default(&ice_cfg.turn_tp[2]); 
    952             ice_cfg.turn_tp[2].af = pj_AF_INET6(); 
    953             ice_cfg.turn_tp[2].alloc_param.af = pj_AF_INET(); 
     957            ice_cfg.turn_tp[idx].af = pj_AF_INET6(); 
     958            ice_cfg.turn_tp[idx].alloc_param.af = pj_AF_INET(); 
    954959        } 
    955960 
     
    963968        } 
    964969 
    965         /* Configure TURN connection settings and credential */ 
    966970        if (ice_cfg.turn_tp[0].port == 0) 
    967971            ice_cfg.turn_tp[0].port = 3479; 
    968         ice_cfg.turn_tp[0].conn_type = acc_cfg->turn_cfg.turn_conn_type; 
    969         pj_memcpy(&ice_cfg.turn_tp[0].auth_cred,  
    970                   &acc_cfg->turn_cfg.turn_auth_cred, 
    971                   sizeof(ice_cfg.turn_tp[0].auth_cred)); 
    972  
    973         if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) { 
    974             ice_cfg.turn_tp[1].server    = ice_cfg.turn_tp[0].server; 
    975             ice_cfg.turn_tp[1].port      = ice_cfg.turn_tp[0].port; 
    976             ice_cfg.turn_tp[1].conn_type = ice_cfg.turn_tp[0].conn_type; 
    977             pj_memcpy(&ice_cfg.turn_tp[1].auth_cred,  
     972 
     973        for (i = 0; i < ice_cfg.turn_tp_cnt; i++) { 
     974            pj_str_t IN6_ADDR_ANY = {"0", 1}; 
     975 
     976            /* Configure TURN connection settings and credential */ 
     977            ice_cfg.turn_tp[i].server    = ice_cfg.turn_tp[0].server; 
     978            ice_cfg.turn_tp[i].port      = ice_cfg.turn_tp[0].port; 
     979            ice_cfg.turn_tp[i].conn_type = acc_cfg->turn_cfg.turn_conn_type; 
     980            pj_memcpy(&ice_cfg.turn_tp[i].auth_cred,  
    978981                      &acc_cfg->turn_cfg.turn_auth_cred, 
    979                       sizeof(ice_cfg.turn_tp[1].auth_cred)); 
    980  
    981             ice_cfg.turn_tp[2].server    = ice_cfg.turn_tp[0].server; 
    982             ice_cfg.turn_tp[2].port      = ice_cfg.turn_tp[0].port; 
    983             ice_cfg.turn_tp[2].conn_type = ice_cfg.turn_tp[0].conn_type; 
    984             pj_memcpy(&ice_cfg.turn_tp[2].auth_cred,  
    985                       &acc_cfg->turn_cfg.turn_auth_cred, 
    986                       sizeof(ice_cfg.turn_tp[2].auth_cred)); 
    987         } 
    988  
    989         /* Configure QoS setting */ 
    990         ice_cfg.turn_tp[0].cfg.qos_type = cfg->qos_type; 
    991         pj_memcpy(&ice_cfg.turn_tp[0].cfg.qos_params, &cfg->qos_params, 
    992                   sizeof(cfg->qos_params)); 
    993         if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) { 
    994             ice_cfg.turn_tp[1].cfg.qos_type = cfg->qos_type; 
    995             pj_memcpy(&ice_cfg.turn_tp[1].cfg.qos_params, &cfg->qos_params, 
     982                      sizeof(ice_cfg.turn_tp[i].auth_cred)); 
     983 
     984            /* Configure QoS setting */ 
     985            ice_cfg.turn_tp[i].cfg.qos_type = cfg->qos_type; 
     986            pj_memcpy(&ice_cfg.turn_tp[i].cfg.qos_params, &cfg->qos_params, 
    996987                      sizeof(cfg->qos_params)); 
    997988 
    998             ice_cfg.turn_tp[2].cfg.qos_type = cfg->qos_type; 
    999             pj_memcpy(&ice_cfg.turn_tp[2].cfg.qos_params, &cfg->qos_params, 
    1000                       sizeof(cfg->qos_params)); 
    1001         } 
    1002  
    1003         /* Configure binding address */ 
    1004         pj_sockaddr_init(ice_cfg.turn_tp[0].af, &ice_cfg.turn_tp[0].cfg.bound_addr, 
    1005                          &cfg->bound_addr, (pj_uint16_t)cfg->port); 
    1006         ice_cfg.turn_tp[0].cfg.port_range = (pj_uint16_t)cfg->port_range; 
    1007         if (cfg->port != 0 && ice_cfg.turn_tp[0].cfg.port_range == 0) 
    1008             ice_cfg.turn_tp[0].cfg.port_range =  
     989            /* Configure binding address */ 
     990            pj_sockaddr_init(ice_cfg.turn_tp[i].af, 
     991                             &ice_cfg.turn_tp[i].cfg.bound_addr, 
     992                             (ice_cfg.turn_tp[i].af == pj_AF_INET()? 
     993                             &cfg->bound_addr: &IN6_ADDR_ANY), 
     994                             (pj_uint16_t)cfg->port); 
     995            ice_cfg.turn_tp[i].cfg.port_range = (pj_uint16_t)cfg->port_range; 
     996            if (cfg->port != 0 && ice_cfg.turn_tp[i].cfg.port_range == 0) 
     997                ice_cfg.turn_tp[i].cfg.port_range =  
    1009998                                 (pj_uint16_t)(pjsua_var.ua_cfg.max_calls * 10); 
    1010999 
    1011         if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) { 
    1012             pj_str_t IN6_ADDR_ANY = {"0", 1}; 
    1013             pj_sockaddr_init(pj_AF_INET6(), 
    1014                              &ice_cfg.turn_tp[1].cfg.bound_addr, 
    1015                              &IN6_ADDR_ANY, (pj_uint16_t)cfg->port); 
    1016             ice_cfg.turn_tp[1].cfg.port_range = 
    1017                             ice_cfg.turn_tp[0].cfg.port_range; 
    1018  
    1019             pj_sockaddr_init(pj_AF_INET6(), 
    1020                              &ice_cfg.turn_tp[2].cfg.bound_addr, 
    1021                              &IN6_ADDR_ANY, (pj_uint16_t)cfg->port); 
    1022             ice_cfg.turn_tp[2].cfg.port_range = 
    1023                             ice_cfg.turn_tp[0].cfg.port_range; 
    1024         } 
    1025  
    1026         /* Configure max packet size */ 
    1027         ice_cfg.turn_tp[0].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    1028         if (use_ipv6 && ice_cfg.turn_tp_cnt > 1) { 
    1029             ice_cfg.turn_tp[1].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    1030             ice_cfg.turn_tp[2].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
     1000            /* Configure max packet size */ 
     1001            ice_cfg.turn_tp[i].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
    10311002        } 
    10321003    } 
     
    23962367            if (m->conn == NULL && sdp->conn == NULL) { 
    23972368                pj_bool_t use_ipv6; 
     2369                pj_bool_t use_nat64; 
    23982370 
    23992371                use_ipv6 = (pjsua_var.acc[call->acc_id].cfg.ipv6_media_use != 
    24002372                            PJSUA_IPV6_DISABLED); 
     2373                use_nat64 = (pjsua_var.acc[call->acc_id].cfg.nat64_opt != 
     2374                             PJSUA_NAT64_DISABLED); 
    24012375 
    24022376                m->conn = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_conn); 
    24032377                m->conn->net_type = pj_str("IN"); 
    2404                 if (use_ipv6) { 
     2378                if (use_ipv6 && !use_nat64) { 
    24052379                    m->conn->addr_type = pj_str("IP6"); 
    24062380                    m->conn->addr = pj_str("::1"); 
  • pjproject/trunk/pjsip/src/pjsua2/account.cpp

    r5466 r5636  
    185185    NODE_READ_NUM_T   ( this_node, pjsua_stun_use, sipStunUse); 
    186186    NODE_READ_NUM_T   ( this_node, pjsua_stun_use, mediaStunUse); 
     187    NODE_READ_NUM_T   ( this_node, pjsua_nat64_opt, nat64Opt); 
    187188    NODE_READ_BOOL    ( this_node, iceEnabled); 
    188189    NODE_READ_INT     ( this_node, iceMaxHostCands); 
     
    216217    NODE_WRITE_NUM_T   ( this_node, pjsua_stun_use, sipStunUse); 
    217218    NODE_WRITE_NUM_T   ( this_node, pjsua_stun_use, mediaStunUse); 
     219    NODE_WRITE_NUM_T   ( this_node, pjsua_nat64_opt, nat64Opt); 
    218220    NODE_WRITE_BOOL    ( this_node, iceEnabled); 
    219221    NODE_WRITE_INT     ( this_node, iceMaxHostCands); 
     
    392394    ret.sip_stun_use            = natConfig.sipStunUse; 
    393395    ret.media_stun_use          = natConfig.mediaStunUse; 
     396    ret.nat64_opt               = natConfig.nat64Opt; 
    394397    ret.ice_cfg_use             = PJSUA_ICE_CONFIG_USE_CUSTOM; 
    395398    ret.ice_cfg.enable_ice      = natConfig.iceEnabled; 
     
    535538    natConfig.sipStunUse        = prm.sip_stun_use; 
    536539    natConfig.mediaStunUse      = prm.media_stun_use; 
     540    natConfig.nat64Opt          = prm.nat64_opt; 
    537541    if (prm.ice_cfg_use == PJSUA_ICE_CONFIG_USE_CUSTOM) { 
    538542        natConfig.iceEnabled = PJ2BOOL(prm.ice_cfg.enable_ice); 
  • pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp

    r5635 r5636  
    149149    } 
    150150 
     151    this->stunTryIpv6 = PJ2BOOL(ua_cfg.stun_try_ipv6); 
    151152    this->stunIgnoreFailure = PJ2BOOL(ua_cfg.stun_ignore_failure); 
    152153    this->natTypeInSdp = ua_cfg.nat_type_in_sdp; 
     
    195196    NODE_READ_STRING  ( this_node, userAgent); 
    196197    NODE_READ_STRINGV ( this_node, stunServer); 
     198    NODE_READ_BOOL    ( this_node, stunTryIpv6); 
    197199    NODE_READ_BOOL    ( this_node, stunIgnoreFailure); 
    198200    NODE_READ_INT     ( this_node, natTypeInSdp); 
     
    210212    NODE_WRITE_STRING  ( this_node, userAgent); 
    211213    NODE_WRITE_STRINGV ( this_node, stunServer); 
     214    NODE_WRITE_BOOL    ( this_node, stunTryIpv6); 
    212215    NODE_WRITE_BOOL    ( this_node, stunIgnoreFailure); 
    213216    NODE_WRITE_INT     ( this_node, natTypeInSdp); 
Note: See TracChangeset for help on using the changeset viewer.