Ticket #600: ticket600.patch
File ticket600.patch, 3.2 KB (added by nanang, 16 years ago) |
---|
-
pjmedia/src/pjmedia/transport_srtp.c
36 36 #define MAX_RTP_BUFFER_LEN 1500 37 37 #define MAX_RTCP_BUFFER_LEN 1500 38 38 #define MAX_KEY_LEN 32 39 40 /* Initial value of probation counter. When probation counter > 0, 41 * it means SRTP is in probation mode, and it may restart when 42 * srtp_unprotect() returns err_status_replay_* 43 */ 44 #define PROBATION_CNT_INIT 100 45 39 46 #define DEACTIVATE_MEDIA(pool, m) pjmedia_sdp_media_deactivate(pool, m) 40 47 41 48 static const pj_str_t ID_RTP_AVP = { "RTP/AVP", 7 }; … … 76 83 77 84 typedef struct transport_srtp 78 85 { 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.*/ 82 89 char rtp_tx_buffer[MAX_RTP_BUFFER_LEN]; 83 90 char rtcp_tx_buffer[MAX_RTCP_BUFFER_LEN]; 84 91 pjmedia_srtp_setting setting; … … 120 127 */ 121 128 pjmedia_srtp_use peer_use; 122 129 130 /* When probation counter > 0, it means SRTP is in probation mode, 131 * and it may restart when srtp_unprotect() returns err_status_replay_* 132 */ 133 unsigned probation_cnt; 123 134 } transport_srtp; 124 135 125 136 … … 349 360 srtp->pool = pool; 350 361 srtp->session_inited = PJ_FALSE; 351 362 srtp->bypass_srtp = PJ_FALSE; 363 srtp->probation_cnt = PROBATION_CNT_INIT; 352 364 srtp->peer_use = opt->use; 353 365 354 366 if (opt) { … … 775 787 /* Make sure buffer is 32bit aligned */ 776 788 PJ_ASSERT_ON_FAIL( (((long)pkt) & 0x03)==0, return ); 777 789 790 if (srtp->probation_cnt > 0) 791 --srtp->probation_cnt; 792 778 793 pj_lock_acquire(srtp->mutex); 779 794 780 795 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 782 818 if (err == err_status_ok) { 783 819 srtp->rtp_cb(srtp->user_data, pkt, len); 784 820 } else { … … 1378 1414 /* At this point, we get valid rx_policy_neg & tx_policy_neg. */ 1379 1415 } 1380 1416 1417 /* Reset probation counts */ 1418 srtp->probation_cnt = PROBATION_CNT_INIT; 1419 1381 1420 /* Got policy_local & policy_remote, let's initalize the SRTP */ 1382 1421 status = pjmedia_transport_srtp_start(tp, &srtp->tx_policy_neg, &srtp->rx_policy_neg); 1383 1422 if (status != PJ_SUCCESS)