diff options
Diffstat (limited to 'pjmedia/src/pjmedia/transport_srtp.c')
-rw-r--r-- | pjmedia/src/pjmedia/transport_srtp.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/pjmedia/src/pjmedia/transport_srtp.c b/pjmedia/src/pjmedia/transport_srtp.c index 85ee70e9..76bd1518 100644 --- a/pjmedia/src/pjmedia/transport_srtp.c +++ b/pjmedia/src/pjmedia/transport_srtp.c @@ -270,9 +270,9 @@ const char* get_libsrtp_errstr(int err) } static pj_bool_t libsrtp_initialized; -static void pjmedia_srtp_deinit_lib(void); +static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt); -PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) +PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt) { if (libsrtp_initialized == PJ_FALSE) { err_status_t err; @@ -284,7 +284,8 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) return PJMEDIA_ERRNO_FROM_LIBSRTP(err); } - if (pj_atexit(pjmedia_srtp_deinit_lib) != PJ_SUCCESS) { + if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS) + { /* There will be memory leak when it fails to schedule libsrtp * deinitialization, however the memory leak could be harmless, * since in modern OS's memory used by an application is released @@ -299,10 +300,19 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(void) return PJ_SUCCESS; } -static void pjmedia_srtp_deinit_lib(void) +static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt) { err_status_t err; + /* Note that currently this SRTP init/deinit is not equipped with + * reference counter, it should be safe as normally there is only + * one single instance of media endpoint and even if it isn't, the + * pjmedia_transport_srtp_create() will invoke SRTP init (the only + * drawback should be the delay described by #788). + */ + + PJ_UNUSED_ARG(endpt); + err = srtp_deinit(); if (err != err_status_ok) { PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s", @@ -410,7 +420,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create( } /* Init libsrtp. */ - status = pjmedia_srtp_init_lib(); + status = pjmedia_srtp_init_lib(endpt); if (status != PJ_SUCCESS) return status; @@ -907,19 +917,22 @@ static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size) (err == err_status_replay_old || err == err_status_replay_fail)) { /* Handle such condition that stream is updated (RTP seq is reinited - * & SRTP is restarted), but some old packets are still coming - * so SRTP is learning wrong RTP seq. While the newly inited RTP seq - * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect() - * will returning err_status_replay_*. Restarting SRTP can resolve - * this. - */ - if (pjmedia_transport_srtp_start((pjmedia_transport*)srtp, - &srtp->tx_policy, &srtp->rx_policy) - != PJ_SUCCESS) - { + * & SRTP is restarted), but some old packets are still coming + * so SRTP is learning wrong RTP seq. While the newly inited RTP seq + * comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect() + * will return err_status_replay_*. Restarting SRTP can resolve this. + */ + pjmedia_srtp_crypto tx, rx; + pj_status_t status; + + tx = srtp->tx_policy; + rx = srtp->rx_policy; + status = pjmedia_transport_srtp_start((pjmedia_transport*)srtp, + &tx, &rx); + if (status != PJ_SUCCESS) { PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s", get_libsrtp_errstr(err))); - } else { + } else if (!srtp->bypass_srtp) { err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len); } } |