Skip to content

Commit

Permalink
patch: avoid double unref for failed transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaian committed Feb 16, 2024
1 parent 688db94 commit 43a03d9
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
102 changes: 102 additions & 0 deletions packaging/debian/patches/003_siprec_double_unref.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
From 28ea0565cabdbd703ddaab9351628aad43e03775 Mon Sep 17 00:00:00 2001
From: Razvan Crainea <razvan@opensips.org>
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);
1 change: 1 addition & 0 deletions packaging/debian/patches/series
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
001_rtp_relay_get_leg_fix.patch
003_siprec_double_unref.patch

0 comments on commit 43a03d9

Please sign in to comment.