From 43a03d961cd763e7b994f95f92ca4e8c87a8ab0a Mon Sep 17 00:00:00 2001 From: Kaian Date: Fri, 16 Feb 2024 11:36:37 +0100 Subject: [PATCH] patch: avoid double unref for failed transaction --- .../patches/003_siprec_double_unref.patch | 102 ++++++++++++++++++ packaging/debian/patches/series | 1 + 2 files changed, 103 insertions(+) create mode 100644 packaging/debian/patches/003_siprec_double_unref.patch diff --git a/packaging/debian/patches/003_siprec_double_unref.patch b/packaging/debian/patches/003_siprec_double_unref.patch new file mode 100644 index 00000000000..711eb29a99f --- /dev/null +++ b/packaging/debian/patches/003_siprec_double_unref.patch @@ -0,0 +1,102 @@ +From 28ea0565cabdbd703ddaab9351628aad43e03775 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! +--- + 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 8db18a050ec..125b81b6938 100644 +--- a/modules/siprec/siprec.c ++++ b/modules/siprec/siprec.c +@@ -180,6 +180,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); + } +@@ -278,6 +279,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 d0656b83d25..58b4ddda7db 100644 +--- a/modules/siprec/siprec_logic.c ++++ b/modules/siprec/siprec_logic.c +@@ -352,15 +352,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; +@@ -384,8 +378,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); + } +@@ -519,7 +511,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; +@@ -653,14 +645,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); diff --git a/packaging/debian/patches/series b/packaging/debian/patches/series index 0310a90598d..02cee25d05a 100644 --- a/packaging/debian/patches/series +++ b/packaging/debian/patches/series @@ -1 +1,2 @@ 001_rtp_relay_get_leg_fix.patch +003_siprec_double_unref.patch