Changeset 3745


Ignore:
Timestamp:
Sep 8, 2011 6:47:28 AM (8 years ago)
Author:
bennylp
Message:

Slightly more clever RTP transport remote address switch: transmission won't switch as long as we're receiving RTP/RTCP packets from the "correct" remote address, to avoid constantly switching to a new source address. Also when the remote peer address is in probation, RT(C)P packets from that address will be silently discarded, to avoid playback confusion. This closes #1366.

Location:
pjproject/branches/1.x/pjmedia
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/1.x/pjmedia/include/pjmedia/config.h

    r3553 r3745  
    388388 
    389389/** 
    390  * Number of packets received from different source IP address from the 
     390 * Number of RTP packets received from different source IP address from the 
    391391 * remote address required to make the stream switch transmission 
    392392 * to the source address. 
     
    394394#ifndef PJMEDIA_RTP_NAT_PROBATION_CNT    
    395395#  define PJMEDIA_RTP_NAT_PROBATION_CNT         10 
     396#endif 
     397 
     398 
     399/** 
     400 * Number of RTCP packets received from different source IP address from the 
     401 * remote address required to make the stream switch RTCP transmission 
     402 * to the source address. 
     403 */ 
     404#ifndef PJMEDIA_RTCP_NAT_PROBATION_CNT 
     405#  define PJMEDIA_RTCP_NAT_PROBATION_CNT        3 
    396406#endif 
    397407 
  • pjproject/branches/1.x/pjmedia/src/pjmedia/transport_ice.c

    r3553 r3745  
    7373    pj_sockaddr          rtcp_src_addr; /**< Actual source RTCP address.    */ 
    7474    unsigned             rtp_src_cnt;   /**< How many pkt from this addr.   */ 
     75    unsigned             rtcp_src_cnt;  /**< How many pkt from this addr.   */ 
    7576 
    7677    unsigned             tx_drop_pct;   /**< Percent of tx pkts to drop.    */ 
     
    15001501    if (tp_ice->use_ice || tp_ice->rtp_src_cnt) { 
    15011502        info->src_rtp_name  = tp_ice->rtp_src_addr; 
     1503    } 
     1504    if (tp_ice->use_ice || tp_ice->rtcp_src_cnt) { 
    15021505        info->src_rtcp_name = tp_ice->rtcp_src_addr; 
    15031506    } 
     
    15651568    tp_ice->rtcp_src_addr = tp_ice->remote_rtcp; 
    15661569    tp_ice->rtp_src_cnt = 0; 
     1570    tp_ice->rtcp_src_cnt = 0; 
    15671571 
    15681572    return PJ_SUCCESS; 
     
    16401644{ 
    16411645    struct transport_ice *tp_ice; 
     1646    pj_bool_t discard = PJ_FALSE; 
    16421647 
    16431648    tp_ice = (struct transport_ice*) pj_ice_strans_get_user_data(ice_st); 
     
    16551660        } 
    16561661 
    1657         (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size); 
    1658  
    16591662        /* See if source address of RTP packet is different than the  
    16601663         * configured address, and switch RTP remote address to  
     
    16631666         */ 
    16641667        if (!tp_ice->use_ice) { 
    1665  
    1666             /* Increment counter and avoid zero */ 
    1667             if (++tp_ice->rtp_src_cnt == 0)  
    1668                 tp_ice->rtp_src_cnt = 1; 
    1669  
    1670             if (pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) != 0) { 
     1668            pj_bool_t enable_switch = 
     1669                    ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0); 
     1670 
     1671            if (!enable_switch || 
     1672                pj_sockaddr_cmp(&tp_ice->remote_rtp, src_addr) == 0) 
     1673            { 
     1674                /* Don't switch while we're receiving from remote_rtp */ 
     1675                tp_ice->rtp_src_cnt = 0; 
     1676            } else { 
     1677 
     1678                ++tp_ice->rtp_src_cnt; 
    16711679 
    16721680                /* Check if the source address is recognized. */ 
     
    16761684                    /* Reset counter */ 
    16771685                    tp_ice->rtp_src_cnt = 0; 
     1686                    discard = PJ_TRUE; 
    16781687                } 
    16791688 
    1680                 if ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0 && 
    1681                     tp_ice->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT)  
    1682                 { 
     1689                if (tp_ice->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) { 
     1690                    discard = PJ_TRUE; 
     1691                } else { 
    16831692                    char addr_text[80]; 
    16841693 
     
    17091718 
    17101719                        PJ_LOG(4,(tp_ice->base.name, 
    1711                                   "Remote RTCP address switched to %s", 
     1720                                  "Remote RTCP address switched to predicted " 
     1721                                  "address %s", 
    17121722                                  pj_sockaddr_print(&tp_ice->remote_rtcp,  
    17131723                                                    addr_text, 
     
    17171727            } 
    17181728        } 
     1729 
     1730        if (!discard) 
     1731            (*tp_ice->rtp_cb)(tp_ice->stream, pkt, size); 
     1732 
    17191733    } else if (comp_id==2 && tp_ice->rtcp_cb) { 
    1720         (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size); 
    17211734 
    17221735        /* Check if RTCP source address is the same as the configured 
     
    17251738         */ 
    17261739        if (!tp_ice->use_ice && 
    1727             pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) != 0) 
     1740            (tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0) 
    17281741        { 
    1729             pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr); 
    1730  
    1731             if ((tp_ice->options & PJMEDIA_ICE_NO_SRC_ADDR_CHECKING)==0) { 
     1742            if (pj_sockaddr_cmp(&tp_ice->remote_rtcp, src_addr) == 0) { 
     1743                tp_ice->rtcp_src_cnt = 0; 
     1744            } else { 
    17321745                char addr_text[80]; 
    17331746 
    1734                 pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr); 
    1735  
    1736                 pj_assert(tp_ice->addr_len == pj_sockaddr_get_len(src_addr)); 
    1737  
    1738                 PJ_LOG(4,(tp_ice->base.name, 
    1739                           "Remote RTCP address switched to %s", 
    1740                           pj_sockaddr_print(&tp_ice->remote_rtcp, addr_text, 
    1741                                             sizeof(addr_text), 3))); 
     1747                ++tp_ice->rtcp_src_cnt; 
     1748                if (tp_ice->rtcp_src_cnt < PJMEDIA_RTCP_NAT_PROBATION_CNT) { 
     1749                    discard = PJ_TRUE; 
     1750                } else { 
     1751                    tp_ice->rtcp_src_cnt = 0; 
     1752                    pj_sockaddr_cp(&tp_ice->rtcp_src_addr, src_addr); 
     1753                    pj_sockaddr_cp(&tp_ice->remote_rtcp, src_addr); 
     1754 
     1755                    pj_assert(tp_ice->addr_len==pj_sockaddr_get_len(src_addr)); 
     1756 
     1757                    PJ_LOG(4,(tp_ice->base.name, 
     1758                              "Remote RTCP address switched to %s", 
     1759                              pj_sockaddr_print(&tp_ice->remote_rtcp, 
     1760                                                addr_text, sizeof(addr_text), 
     1761                                                3))); 
     1762                } 
    17421763            } 
    17431764        } 
     1765 
     1766        if (!discard) 
     1767            (*tp_ice->rtcp_cb)(tp_ice->stream, pkt, size); 
    17441768    } 
    17451769 
  • pjproject/branches/1.x/pjmedia/src/pjmedia/transport_udp.c

    r3553 r3745  
    8484    pj_sockaddr         rtcp_addr_name; /**< Published RTCP address.        */ 
    8585    pj_sockaddr         rtcp_src_addr;  /**< Actual source RTCP address.    */ 
     86    unsigned            rtcp_src_cnt;   /**< How many pkt from this addr.   */ 
    8687    int                 rtcp_addr_len;  /**< Length of RTCP src address.    */ 
    8788    pj_ioqueue_key_t   *rtcp_key;       /**< RTCP socket key in ioqueue     */ 
     
    453454        void (*cb)(void*,void*,pj_ssize_t); 
    454455        void *user_data; 
     456        pj_bool_t discard = PJ_FALSE; 
    455457 
    456458        cb = udp->rtp_cb; 
     
    463465                          "RX RTP packet dropped because of pkt lost " 
    464466                          "simulation")); 
    465                 goto read_next_packet; 
     467                discard = PJ_TRUE; 
    466468            } 
    467469        } 
    468  
    469  
    470         if (udp->attached && cb) 
    471             (*cb)(user_data, udp->rtp_pkt, bytes_read); 
    472470 
    473471        /* See if source address of RTP packet is different than the  
     
    479477            (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)  
    480478        { 
    481             if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) != 0) { 
    482  
     479            if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) == 0) { 
     480                /* We're still receiving from rem_rtp_addr. Don't switch. */ 
     481                udp->rtp_src_cnt = 0; 
     482            } else { 
    483483                udp->rtp_src_cnt++; 
    484484 
    485                 if (udp->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) { 
     485                if (udp->rtp_src_cnt < PJMEDIA_RTP_NAT_PROBATION_CNT) { 
     486                    discard = PJ_TRUE; 
     487                } else { 
    486488                 
    487489                    char addr_text[80]; 
     
    517519 
    518520                        PJ_LOG(4,(udp->base.name, 
    519                                   "Remote RTCP address switched to %s", 
     521                                  "Remote RTCP address switched to predicted" 
     522                                  " address %s", 
    520523                                  pj_sockaddr_print(&udp->rtcp_src_addr,  
    521524                                                    addr_text, 
     
    527530        } 
    528531 
    529 read_next_packet: 
     532        if (!discard && udp->attached && cb) 
     533            (*cb)(user_data, udp->rtp_pkt, bytes_read); 
     534 
    530535        bytes_read = sizeof(udp->rtp_pkt); 
    531536        udp->rtp_addrlen = sizeof(udp->rtp_src_addr); 
     
    569574         */ 
    570575        if (bytes_read>0 && 
    571             (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0 && 
    572             pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) != 0) 
     576            (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0) 
    573577        { 
    574             char addr_text[80]; 
    575  
    576             pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr, 
    577                       sizeof(pj_sockaddr)); 
    578  
    579             PJ_LOG(4,(udp->base.name, 
    580                       "Remote RTCP address switched to %s", 
    581                       pj_sockaddr_print(&udp->rtcp_src_addr, addr_text, 
    582                                         sizeof(addr_text), 3))); 
     578            if (pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) == 0) { 
     579                /* Still receiving from rem_rtcp_addr, don't switch */ 
     580                udp->rtcp_src_cnt = 0; 
     581            } else { 
     582                ++udp->rtcp_src_cnt; 
     583 
     584                if (udp->rtcp_src_cnt >= PJMEDIA_RTCP_NAT_PROBATION_CNT ) { 
     585                    char addr_text[80]; 
     586 
     587                    udp->rtcp_src_cnt = 0; 
     588                    pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr, 
     589                              sizeof(pj_sockaddr)); 
     590 
     591                    PJ_LOG(4,(udp->base.name, 
     592                              "Remote RTCP address switched to %s", 
     593                              pj_sockaddr_print(&udp->rtcp_src_addr, addr_text, 
     594                                                sizeof(addr_text), 3))); 
     595                } 
     596            } 
    583597        } 
    584598 
     
    678692    pj_bzero(&udp->rtcp_src_addr, sizeof(udp->rtcp_src_addr)); 
    679693    udp->rtp_src_cnt = 0; 
     694    udp->rtcp_src_cnt = 0; 
    680695 
    681696    /* Unlock keys */ 
Note: See TracChangeset for help on using the changeset viewer.