@@ -986,7 +986,7 @@ static pj_status_t create_srtp_ctx(transport_srtp *srtp,
986986 err = srtp_set_stream_roc (ctx -> srtp_tx_ctx ,
987987 setting -> tx_roc .ssrc ,
988988 setting -> tx_roc .roc );
989- PJ_LOG (4 , (THIS_FILE , "Initializing SRTP TX ROC to SSRC %d with "
989+ PJ_LOG (4 , (THIS_FILE , "Initializing SRTP TX ROC to SSRC %u with "
990990 "ROC %d %s\n" , setting -> tx_roc .ssrc ,
991991 setting -> tx_roc .roc ,
992992 (err == srtp_err_status_ok )? "succeeded" : "failed" ));
@@ -1038,7 +1038,7 @@ static pj_status_t create_srtp_ctx(transport_srtp *srtp,
10381038 err = srtp_set_stream_roc (ctx -> srtp_rx_ctx ,
10391039 setting -> rx_roc .ssrc ,
10401040 setting -> rx_roc .roc );
1041- PJ_LOG (4 , (THIS_FILE , "Initializing SRTP RX ROC from SSRC %d with "
1041+ PJ_LOG (4 , (THIS_FILE , "Initializing SRTP RX ROC from SSRC %u with "
10421042 "ROC %d %s\n" ,
10431043 setting -> rx_roc .ssrc , setting -> rx_roc .roc ,
10441044 (err == srtp_err_status_ok )? "succeeded" : "failed" ));
@@ -1399,7 +1399,7 @@ static pj_status_t transport_send_rtp( pjmedia_transport *tp,
13991399 if (status == srtp_err_status_ok ) {
14001400 srtp -> setting .tx_roc .ssrc = srtp -> tx_ssrc ;
14011401 srtp -> setting .tx_roc .roc = (srtp -> offerer_side ? 1 : 2 );
1402- PJ_LOG (4 , (THIS_FILE , "Setting TX ROC to SSRC %d to %d" ,
1402+ PJ_LOG (4 , (THIS_FILE , "Setting TX ROC to SSRC %u to %d" ,
14031403 srtp -> tx_ssrc , srtp -> setting .tx_roc .roc ));
14041404 }
14051405 }
@@ -1549,6 +1549,8 @@ static void srtp_rtp_cb(pjmedia_tp_cb_param *param)
15491549 pj_ssize_t size = param -> size ;
15501550 int len = (int )size ;
15511551 srtp_err_status_t err ;
1552+ pj_bool_t need_restart = PJ_FALSE , need_retry = PJ_FALSE ;
1553+ pj_uint32_t rx_ssrc ;
15521554 void (* cb )(void * , void * , pj_ssize_t ) = NULL ;
15531555 void (* cb2 )(pjmedia_tp_cb_param * ) = NULL ;
15541556 void * cb_data = NULL ;
@@ -1624,7 +1626,7 @@ static void srtp_rtp_cb(pjmedia_tp_cb_param *param)
16241626 srtp -> setting .rx_roc .ssrc = srtp -> rx_ssrc ;
16251627 srtp -> setting .rx_roc .roc = (srtp -> offerer_side ? 2 : 1 );
16261628
1627- PJ_LOG (4 , (THIS_FILE , "Setting RX ROC from SSRC %d to %d" ,
1629+ PJ_LOG (4 , (THIS_FILE , "Setting RX ROC from SSRC %u to %d" ,
16281630 srtp -> rx_ssrc , srtp -> setting .rx_roc .roc ));
16291631 } else {
16301632 PJ_LOG (4 , (THIS_FILE , "Setting RX ROC %s" ,
@@ -1635,22 +1637,59 @@ static void srtp_rtp_cb(pjmedia_tp_cb_param *param)
16351637
16361638 err = srtp_unprotect (srtp -> srtp_ctx .srtp_rx_ctx , (pj_uint8_t * )pkt , & len );
16371639
1640+ rx_ssrc = ntohl (((pjmedia_rtp_hdr * )pkt )-> ssrc );
1641+
16381642#if PJMEDIA_SRTP_CHECK_RTP_SEQ_ON_RESTART
1643+ /* Handle such condition that stream is updated (RTP seq is reinited
1644+ * & SRTP is restarted), but some old packets are still coming
1645+ * so SRTP is learning wrong RTP seq. While the newly inited RTP seq
1646+ * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()
1647+ * will return err_status_replay_*. Restarting SRTP can resolve this.
1648+ */
16391649 if (srtp -> probation_cnt > 0 &&
16401650 (err == srtp_err_status_replay_old ||
16411651 err == srtp_err_status_replay_fail ))
16421652 {
1643- /* Handle such condition that stream is updated (RTP seq is reinited
1644- * & SRTP is restarted), but some old packets are still coming
1645- * so SRTP is learning wrong RTP seq. While the newly inited RTP seq
1646- * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()
1647- * will return err_status_replay_*. Restarting SRTP can resolve this.
1653+ need_restart = PJ_TRUE ;
1654+ PJ_LOG (5 , (srtp -> pool -> obj_name , "Restarting SRTP err=%s" ,
1655+ get_libsrtp_errstr (err )));
1656+ }
1657+ #endif
1658+
1659+ #if PJMEDIA_SRTP_CHECK_SSRC_ON_RESTART
1660+ /* This could happen if remote changes ssrc, such as due to media
1661+ * restart.
1662+ */
1663+ if (srtp -> probation_cnt > 0 && err == srtp_err_status_no_ctx ) {
1664+ need_restart = PJ_TRUE ;
1665+ PJ_LOG (5 , (srtp -> pool -> obj_name , "Restarting SRTP err=%s ssrc=%u" ,
1666+ get_libsrtp_errstr (err ), rx_ssrc ));
1667+ }
1668+ #endif
1669+
1670+ #if PJMEDIA_SRTP_CHECK_ROC_ON_RESTART
1671+ if (srtp -> probation_cnt > 0 && err == srtp_err_status_auth_fail &&
1672+ srtp -> setting .prev_rx_roc .ssrc != 0 &&
1673+ srtp -> setting .prev_rx_roc .ssrc == srtp -> setting .rx_roc .ssrc &&
1674+ srtp -> setting .prev_rx_roc .roc != srtp -> setting .rx_roc .roc )
1675+ {
1676+ need_retry = PJ_TRUE ;
1677+ }
1678+ #endif
1679+
1680+ if (need_restart ) {
1681+ /* Handle such condition that stream is updated and SRTP is restarted,
1682+ * but some old packets are still coming so SRTP is learning wrong SSRC
1683+ * or RTP seq. Restarting SRTP can resolve this.
16481684 */
16491685 pjmedia_srtp_crypto tx , rx ;
16501686 pj_status_t status ;
16511687
16521688 tx = srtp -> srtp_ctx .tx_policy ;
16531689 rx = srtp -> srtp_ctx .rx_policy ;
1690+ /* If SRTP cannot find the context, reset the SSRC. */
1691+ if (err == srtp_err_status_no_ctx )
1692+ srtp -> setting .rx_roc .ssrc = 0 ;
16541693
16551694 /* Stop SRTP first, otherwise srtp_start() will maintain current
16561695 * roll-over counter.
@@ -1660,24 +1699,15 @@ static void srtp_rtp_cb(pjmedia_tp_cb_param *param)
16601699 status = pjmedia_transport_srtp_start ((pjmedia_transport * )srtp ,
16611700 & tx , & rx );
16621701 if (status != PJ_SUCCESS ) {
1663- PJ_LOG (5 ,(srtp -> pool -> obj_name , "Failed to restart SRTP, err=%s" ,
1664- get_libsrtp_errstr (err )));
1702+ PJ_PERROR (4 , (srtp -> pool -> obj_name , status ,
1703+ "Failed to restart SRTP, err=%s" ,
1704+ get_libsrtp_errstr (err )));
16651705 } else if (!srtp -> bypass_srtp ) {
16661706 err = srtp_unprotect (srtp -> srtp_ctx .srtp_rx_ctx ,
16671707 (pj_uint8_t * )pkt , & len );
16681708 }
1669- }
1670- #if PJMEDIA_SRTP_CHECK_ROC_ON_RESTART
1671- else
1672- #endif
1673- #endif
16741709
1675- #if PJMEDIA_SRTP_CHECK_ROC_ON_RESTART
1676- if (srtp -> probation_cnt > 0 && err == srtp_err_status_auth_fail &&
1677- srtp -> setting .prev_rx_roc .ssrc != 0 &&
1678- srtp -> setting .prev_rx_roc .ssrc == srtp -> setting .rx_roc .ssrc &&
1679- srtp -> setting .prev_rx_roc .roc != srtp -> setting .rx_roc .roc )
1680- {
1710+ } else if (need_retry ) {
16811711 unsigned roc , new_roc ;
16821712 srtp_err_status_t status ;
16831713
@@ -1695,19 +1725,18 @@ static void srtp_rtp_cb(pjmedia_tp_cb_param *param)
16951725 & len );
16961726 }
16971727 }
1698- #endif
16991728
17001729 if (err != srtp_err_status_ok ) {
17011730 PJ_LOG (5 ,(srtp -> pool -> obj_name ,
1702- "Failed to unprotect SRTP, pkt size=%ld, err=%s" ,
1703- size , get_libsrtp_errstr (err )));
1731+ "Failed to unprotect SRTP, pkt size=%ld, SSRC=%u, err=%s" ,
1732+ size , rx_ssrc , get_libsrtp_errstr (err )));
17041733 } else {
17051734 cb = srtp -> rtp_cb ;
17061735 cb2 = srtp -> rtp_cb2 ;
17071736 cb_data = srtp -> user_data ;
17081737
17091738 /* Save SSRC after successful SRTP unprotect */
1710- srtp -> rx_ssrc = ntohl ((( pjmedia_rtp_hdr * ) pkt ) -> ssrc ) ;
1739+ srtp -> rx_ssrc = rx_ssrc ;
17111740 }
17121741
17131742 pj_lock_release (srtp -> mutex );
0 commit comments