From 9846f997976a00ef835ae9ecb2de95304f4f4a13 Mon Sep 17 00:00:00 2001 From: Razvan Crainea Date: Tue, 6 Feb 2024 16:16:14 +0200 Subject: [PATCH] siprec: avoid double unref for failed transaction Many thanks to Voxtronic for reporting this! (cherry picked from commit 28ea0565cabdbd703ddaab9351628aad43e03775) --- modules/siprec/siprec.c | 2 ++ modules/siprec/siprec_logic.c | 23 ++++++----------------- modules/siprec/siprec_logic.h | 1 - 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/modules/siprec/siprec.c b/modules/siprec/siprec.c index c38ab5e38a1..f8d3f5d7788 100644 --- a/modules/siprec/siprec.c +++ b/modules/siprec/siprec.c @@ -182,6 +182,7 @@ static void mod_destroy(void) static void tm_src_unref_session(void *p) { struct src_sess *ss = (struct src_sess *)p; + srec_dlg.dlg_unref(ss->dlg, 1); /* release the dialog */ srec_hlog(ss, SREC_UNREF, "start recording unref"); SIPREC_UNREF(ss); } @@ -280,6 +281,7 @@ static int siprec_start_rec(struct sip_msg *msg, str *srs) return 1; session_cleanup: + srec_dlg.dlg_unref(dlg, 1); src_free_session(ss); return ret; } diff --git a/modules/siprec/siprec_logic.c b/modules/siprec/siprec_logic.c index 9e414427a23..2a08ef9ad51 100644 --- a/modules/siprec/siprec_logic.c +++ b/modules/siprec/siprec_logic.c @@ -339,15 +339,9 @@ static int srec_b2b_notify(struct sip_msg *msg, str *key, int type, } } - if (!(ss->flags & SIPREC_DLG_CBS)) { - if (srec_register_callbacks(ss) < 0) { - LM_ERR("cannot register callback for terminating session\n"); - goto no_recording; - } - - /* no need to keep ref on the dialog, since we rely on it from now on */ - srec_dlg.dlg_unref(ss->dlg, 1); - /* also, the b2b ref moves on the dialog - so we avoid a ref-unref */ + if (!(ss->flags & SIPREC_DLG_CBS) && srec_register_callbacks(ss) < 0) { + LM_ERR("cannot register callback for terminating session\n"); + goto no_recording; } return 0; @@ -371,8 +365,6 @@ static int srec_b2b_notify(struct sip_msg *msg, str *key, int type, /* if the dialog has already been engaged, then we need to keep the * reference until the end of the dialog, where it will be cleaned up */ srec_dlg.dlg_ctx_put_ptr(ss->dlg, srec_dlg_idx, NULL); - srec_dlg.dlg_unref(ss->dlg, 1); - ss->dlg = NULL; srec_hlog(ss, SREC_UNREF, "no recording"); SIPREC_UNREF(ss); } @@ -500,7 +492,7 @@ static int srs_send_invite(struct src_sess *sess) } /* starts the recording to the srs */ -int src_start_recording(struct sip_msg *msg, struct src_sess *sess) +static int src_start_recording(struct sip_msg *msg, struct src_sess *sess) { unsigned int flags = RTP_COPY_MODE_SIPREC|RTP_COPY_LEG_BOTH; union sockaddr_union tmp; @@ -634,14 +626,11 @@ void tm_start_recording(struct cell *t, int type, struct tmcb_params *ps) if (!is_invite(t)) return; ss = (struct src_sess *)*ps->param; - if (ps->code >= 300) { - /* unref so we can release the dialog */ - srec_dlg.dlg_unref(ss->dlg, 1); + if (ps->code >= 300) return; - } - /* engage only on successful calls */ SIPREC_LOCK(ss); + /* engage only on successful calls */ /* if session has been started, do not start it again */ if (ss->flags & SIPREC_STARTED) LM_DBG("Session %p (%s) already started!\n", ss, ss->uuid); diff --git a/modules/siprec/siprec_logic.h b/modules/siprec/siprec_logic.h index eb2b0dec732..1bc1a696d3e 100644 --- a/modules/siprec/siprec_logic.h +++ b/modules/siprec/siprec_logic.h @@ -29,7 +29,6 @@ #include "siprec_sess.h" #include "../b2b_entities/b2be_load.h" -int src_start_recording(struct sip_msg *msg, struct src_sess *sess); void tm_start_recording(struct cell *t, int type, struct tmcb_params *ps); int srec_register_callbacks(struct src_sess *sess); int srec_restore_callback(struct src_sess *sess);