summaryrefslogtreecommitdiff
path: root/pjmedia/src/pjmedia/transport_srtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjmedia/src/pjmedia/transport_srtp.c')
-rw-r--r--pjmedia/src/pjmedia/transport_srtp.c45
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);
}
}