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

Fixed #2032: NAT64 support for IPv4 interoperability

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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. 
Note: See TracChangeset for help on using the changeset viewer.