Ticket #616: Ticket616.patch

File Ticket616.patch, 7.6 KB (added by nanang, 16 years ago)

Enable symmetric RTP & RTCP for ICE transport.

  • pjmedia/include/pjmedia/transport_ice.h

     
    6262 
    6363 
    6464/** 
     65 * Options that can be specified when creating ICE transport. 
     66 */ 
     67enum pjmedia_transport_ice_options 
     68{ 
     69    /** 
     70     * Normally the ICE transport will continuously check the source address 
     71     * of incoming packets to see if it is different than the configured 
     72     * remote address, and switch the remote address to the source address 
     73     * of the packet if they are different after several packets are 
     74     * received. 
     75     * Specifying this option will disable this feature. 
     76     */ 
     77    PJMEDIA_ICE_NO_SRC_ADDR_CHECKING = 1 
     78}; 
     79 
     80 
     81/** 
    6582 * Create the Interactive Connectivity Establishment (ICE) media transport 
    6683 * using the specified configuration. When STUN or TURN (or both) is used, 
    6784 * the creation operation will complete asynchronously, when STUN resolution 
     
    94111                                        const pjmedia_ice_cb *cb, 
    95112                                        pjmedia_transport **p_tp); 
    96113 
     114 
     115/** 
     116 * The same as @pjmedia_ice_create with additional \a options param. 
     117 * 
     118 * @param endpt         The media endpoint. 
     119 * @param name          Optional name to identify this ICE media transport 
     120 *                      for logging purposes. 
     121 * @param comp_cnt      Number of components to be created. 
     122 * @param cfg           Pointer to configuration settings. 
     123 * @param cb            Optional structure containing ICE specific callbacks. 
     124 * @param options       Options, see #pjmedia_transport_ice_options. 
     125 * @param p_tp          Pointer to receive the media transport instance. 
     126 * 
     127 * @return              PJ_SUCCESS on success, or the appropriate error code. 
     128 */ 
     129PJ_DECL(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt, 
     130                                         const char *name, 
     131                                         unsigned comp_cnt, 
     132                                         const pj_ice_strans_cfg *cfg, 
     133                                         const pjmedia_ice_cb *cb, 
     134                                         unsigned options, 
     135                                         pjmedia_transport **p_tp); 
     136 
    97137PJ_END_DECL 
    98138 
    99139 
  • pjmedia/src/pjmedia/transport_ice.c

     
    4949    pjmedia_transport    base; 
    5050    pj_pool_t           *pool; 
    5151    int                  af; 
     52    unsigned             options;       /**< Transport options.             */ 
    5253 
    5354    unsigned             comp_cnt; 
    5455    pj_ice_strans       *ice_st; 
     
    5859 
    5960    pj_bool_t            initial_sdp; 
    6061    enum oa_role         oa_role;       /**< Last role in SDP offer/answer  */ 
    61     struct sdp_state     rem_offer_state;/**< Describes the remote offer            */ 
     62    struct sdp_state     rem_offer_state;/**< Describes the remote offer    */ 
    6263 
    6364    void                *stream; 
    64     pj_sockaddr_in       remote_rtp; 
    65     pj_sockaddr_in       remote_rtcp; 
     65    pj_sockaddr          remote_rtp; 
     66    pj_sockaddr          remote_rtcp; 
     67    unsigned             addr_len;      /**< Length of addresses.           */ 
    6668 
     69    pj_bool_t            ice_inited; 
     70    pj_sockaddr          rtp_src_addr;  /**< Actual source RTP address.     */ 
     71    pj_sockaddr          rtcp_src_addr; /**< Actual source RTCP address.    */ 
     72    unsigned             rtp_src_cnt;   /**< How many pkt from this addr.   */ 
     73 
    6774    unsigned             tx_drop_pct;   /**< Percent of tx pkts to drop.    */ 
    6875    unsigned             rx_drop_pct;   /**< Percent of rx pkts to drop.    */ 
    6976 
     
    181188                                       const pjmedia_ice_cb *cb, 
    182189                                       pjmedia_transport **p_tp) 
    183190{ 
     191    return pjmedia_ice_create2(endpt, name, comp_cnt, cfg, cb, 0, p_tp); 
     192} 
     193 
     194/* 
     195 * Create ICE media transport. 
     196 */ 
     197PJ_DEF(pj_status_t) pjmedia_ice_create2(pjmedia_endpt *endpt, 
     198                                        const char *name, 
     199                                        unsigned comp_cnt, 
     200                                        const pj_ice_strans_cfg *cfg, 
     201                                        const pjmedia_ice_cb *cb, 
     202                                        unsigned options, 
     203                                        pjmedia_transport **p_tp) 
     204{ 
    184205    pj_pool_t *pool; 
    185206    pj_ice_strans_cb ice_st_cb; 
    186207    struct transport_ice *tp_ice; 
     
    193214    tp_ice = PJ_POOL_ZALLOC_T(pool, struct transport_ice); 
    194215    tp_ice->pool = pool; 
    195216    tp_ice->af = cfg->af; 
     217    tp_ice->options = options; 
    196218    tp_ice->comp_cnt = comp_cnt; 
    197219    pj_ansi_strcpy(tp_ice->base.name, pool->obj_name); 
    198220    tp_ice->base.op = &transport_ice_op; 
    199221    tp_ice->base.type = PJMEDIA_TRANSPORT_TYPE_ICE; 
    200222    tp_ice->initial_sdp = PJ_TRUE; 
    201223    tp_ice->oa_role = ROLE_NONE; 
     224    tp_ice->ice_inited = PJ_FALSE; 
    202225 
    203226    if (cb) 
    204227        pj_memcpy(&tp_ice->cb, cb, sizeof(pjmedia_ice_cb)); 
     
    241264    } 
    242265 
    243266    pj_ice_strans_stop_ice(tp_ice->ice_st); 
     267 
     268    tp_ice->ice_inited = PJ_FALSE; 
    244269} 
    245270 
    246271 
     
    13571382    } 
    13581383 
    13591384    /* Done */ 
     1385    tp_ice->ice_inited = PJ_TRUE; 
    13601386 
    13611387    return PJ_SUCCESS; 
    13621388} 
     
    14221448 
    14231449    pj_memcpy(&tp_ice->remote_rtp, rem_addr, addr_len); 
    14241450    pj_memcpy(&tp_ice->remote_rtcp, rem_rtcp, addr_len); 
     1451    tp_ice->addr_len = addr_len; 
    14251452 
    14261453    return PJ_SUCCESS; 
    14271454} 
     
    14601487 
    14611488    return pj_ice_strans_sendto(tp_ice->ice_st, 1,  
    14621489                                pkt, size, &tp_ice->remote_rtp, 
    1463                                 sizeof(pj_sockaddr_in)); 
     1490                                tp_ice->addr_len); 
    14641491} 
    14651492 
    14661493 
     
    15141541 
    15151542        (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size); 
    15161543 
    1517     } else if (comp_id==2 && tp_ice->rtcp_cb) 
     1544        /* See if source address of RTP packet is different than the  
     1545         * configured address, and switch RTP remote address to  
     1546         * source packet address after several consecutive packets 
     1547         * have been received. 
     1548         */ 
     1549        if (!tp_ice->ice_inited && 
     1550            (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING) == 0 && 
     1551            pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) != 0 ) 
     1552        { 
     1553            /* Check if the source address is recognized. */ 
     1554            if (pj_sockaddr_cmp(src_addr, &tp_ice->rtp_src_addr) != 0) { 
     1555                /* Remember the new source address. */ 
     1556                pj_sockaddr_cp(&tp_ice->rtp_src_addr, src_addr); 
     1557 
     1558                /* Reset counter */ 
     1559                tp_ice->rtp_src_cnt = 0; 
     1560            } 
     1561 
     1562            tp_ice->rtp_src_cnt++; 
     1563 
     1564            if (tp_ice->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) { 
     1565         
     1566                char addr_text[80]; 
     1567 
     1568                /* Set remote RTP address to source address */ 
     1569                pj_sockaddr_cp(&tp_ice->remote_rtp, &tp_ice->rtp_src_addr); 
     1570                tp_ice->addr_len = pj_sockaddr_get_len(&tp_ice->remote_rtp); 
     1571 
     1572                /* Reset counter */ 
     1573                tp_ice->rtp_src_cnt = 0; 
     1574 
     1575                PJ_LOG(4,(tp_ice->base.name, 
     1576                          "Remote RTP address switched to %s", 
     1577                          pj_sockaddr_print(&tp_ice->remote_rtp, addr_text, 
     1578                                            sizeof(addr_text), 3))); 
     1579 
     1580                /* Also update remote RTCP address if actual RTCP source 
     1581                 * address is not heard yet. 
     1582                 */ 
     1583                if (!pj_sockaddr_has_addr(&tp_ice->rtcp_src_addr)) { 
     1584                    pj_uint16_t port; 
     1585 
     1586                    pj_sockaddr_cp(&tp_ice->remote_rtcp, &tp_ice->remote_rtp); 
     1587 
     1588                    port = (pj_uint16_t) 
     1589                           (pj_sockaddr_get_port(&tp_ice->remote_rtp)+1); 
     1590                    pj_sockaddr_set_port(&tp_ice->remote_rtcp, port); 
     1591 
     1592                    PJ_LOG(4,(tp_ice->base.name, 
     1593                              "Remote RTCP address switched to %s", 
     1594                              pj_sockaddr_print(&tp_ice->remote_rtcp, addr_text, 
     1595                                                sizeof(addr_text), 3))); 
     1596 
     1597                } 
     1598            } 
     1599        } 
     1600    } else if (comp_id==2 && tp_ice->rtcp_cb) { 
    15181601        (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size); 
    15191602 
    1520     PJ_UNUSED_ARG(src_addr); 
     1603        /* Check if RTCP source address is the same as the configured 
     1604         * remote address, and switch the address when they are 
     1605         * different. 
     1606         */ 
     1607        if (!tp_ice->ice_inited && 
     1608            (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0 && 
     1609            pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) != 0) 
     1610        { 
     1611            char addr_text[80]; 
     1612 
     1613            pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr); 
     1614            pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr); 
     1615 
     1616            pj_assert(tp_ice->addr_len == pj_sockaddr_get_len(src_addr)); 
     1617 
     1618            PJ_LOG(4,(tp_ice->base.name, 
     1619                      "Remote RTCP address switched to %s", 
     1620                      pj_sockaddr_print(&tp_ice->remote_rtcp, addr_text, 
     1621                                        sizeof(addr_text), 3))); 
     1622        } 
     1623    } 
     1624 
    15211625    PJ_UNUSED_ARG(src_addr_len); 
    15221626} 
    15231627