Changeset 2242


Ignore:
Timestamp:
Aug 26, 2008 4:59:10 PM (11 years ago)
Author:
nanang
Message:

Ticket #600: Added probation state in media transport SRTP and also capability to auto-restart when packets received in probation state are 'invalid'.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_srtp.c

    r2144 r2242  
    3737#define MAX_RTCP_BUFFER_LEN         1500 
    3838#define MAX_KEY_LEN                 32 
     39 
     40/* Initial value of probation counter. When probation counter > 0,  
     41 * it means SRTP is in probation state, and it may restart when 
     42 * srtp_unprotect() returns err_status_replay_* 
     43 */ 
     44#define PROBATION_CNT_INIT          100 
     45 
    3946#define DEACTIVATE_MEDIA(pool, m)   pjmedia_sdp_media_deactivate(pool, m) 
    4047 
     
    7784typedef struct transport_srtp 
    7885{ 
    79     pjmedia_transport    base;      /**< Base transport interface. */ 
    80     pj_pool_t           *pool; 
    81     pj_lock_t           *mutex; 
     86    pjmedia_transport    base;              /**< Base transport interface. */ 
     87    pj_pool_t           *pool;              /**< Pool for transport SRTP.   */ 
     88    pj_lock_t           *mutex;             /**< Mutex for libsrtp contexts.*/ 
    8289    char                 rtp_tx_buffer[MAX_RTP_BUFFER_LEN]; 
    8390    char                 rtcp_tx_buffer[MAX_RTCP_BUFFER_LEN]; 
     
    121128    pjmedia_srtp_use     peer_use; 
    122129 
     130    /* When probation counter > 0, it means SRTP is in probation state,  
     131     * and it may restart when srtp_unprotect() returns err_status_replay_* 
     132     */ 
     133    unsigned             probation_cnt; 
    123134} transport_srtp; 
    124135 
     
    350361    srtp->session_inited = PJ_FALSE; 
    351362    srtp->bypass_srtp = PJ_FALSE; 
     363    srtp->probation_cnt = PROBATION_CNT_INIT; 
    352364    srtp->peer_use = opt->use; 
    353365 
     
    776788    PJ_ASSERT_ON_FAIL( (((long)pkt) & 0x03)==0, return ); 
    777789 
     790    if (srtp->probation_cnt > 0) 
     791        --srtp->probation_cnt; 
     792 
    778793    pj_lock_acquire(srtp->mutex); 
    779794 
    780795    err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 
    781      
     796 
     797    if (srtp->probation_cnt > 0 &&  
     798        (err == err_status_replay_old || err == err_status_replay_fail))  
     799    { 
     800        /* Handle such condition that stream is updated (RTP seq is reinited 
     801        * & SRTP is restarted), but some old packets are still coming  
     802        * so SRTP is learning wrong RTP seq. While the newly inited RTP seq 
     803        * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()  
     804        * will returning err_status_replay_*. Restarting SRTP can resolve  
     805        * this. 
     806        */ 
     807        if (pjmedia_transport_srtp_start((pjmedia_transport*)srtp,  
     808                                         &srtp->tx_policy, &srtp->rx_policy)  
     809                                         != PJ_SUCCESS) 
     810        { 
     811            PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s",  
     812                      get_libsrtp_errstr(err))); 
     813        } else { 
     814            err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); 
     815        } 
     816    } 
     817 
    782818    if (err == err_status_ok) { 
    783819        srtp->rtp_cb(srtp->user_data, pkt, len); 
     
    13791415    } 
    13801416 
     1417    /* Reset probation counts */ 
     1418    srtp->probation_cnt = PROBATION_CNT_INIT; 
     1419 
    13811420    /* Got policy_local & policy_remote, let's initalize the SRTP */ 
    13821421    status = pjmedia_transport_srtp_start(tp, &srtp->tx_policy_neg, &srtp->rx_policy_neg); 
Note: See TracChangeset for help on using the changeset viewer.