Skip to content

Commit

Permalink
siprec: avoid double unref for failed transaction
Browse files Browse the repository at this point in the history
Many thanks to Voxtronic for reporting this!

(cherry picked from commit 28ea056)
  • Loading branch information
razvancrainea committed Feb 9, 2024
1 parent b7c7a9a commit 3e1d9ed
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 18 deletions.
2 changes: 2 additions & 0 deletions modules/siprec/siprec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down
23 changes: 6 additions & 17 deletions modules/siprec/siprec_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion modules/siprec/siprec_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 3e1d9ed

Please sign in to comment.