Skip to content

Commit 30c5fdf

Browse files
committed
cgrates: make sure ctx is released on backup node
when cgrates ctx is being replicated, we need to release it when the dialog is destroyed, otherwise it will leak. Many thanks for @NicoFrLy on GitHub for reporting it. Close #3656
1 parent 5d599a8 commit 30c5fdf

1 file changed

Lines changed: 41 additions & 10 deletions

File tree

modules/cgrates/cgrates_acc.c

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,24 @@ static inline struct cgr_acc_ctx *cgr_get_acc_ctx(void)
111111
return ctx->acc;
112112
}
113113

114-
struct cgr_acc_ctx *cgr_tryget_acc_ctx(void)
114+
static struct cgr_acc_ctx *cgr_fetch_acc_ctx(struct dlg_cell *dlg)
115115
{
116-
struct cgr_acc_ctx *acc_ctx;
117116
int_str ctxstr;
118117
int val_type;
118+
119+
/* search for the accounting ctx */
120+
if (cgr_dlgb.fetch_dlg_value(dlg, &cgr_ctx_str, &val_type, &ctxstr, 0) < 0)
121+
return NULL;
122+
if (ctxstr.s.len != sizeof(struct cgr_acc_ctx *)) {
123+
LM_BUG("Invalid ctx pointer size %d\n", ctxstr.s.len);
124+
return NULL;
125+
}
126+
return *(struct cgr_acc_ctx **)ctxstr.s.s;
127+
}
128+
129+
struct cgr_acc_ctx *cgr_tryget_acc_ctx(void)
130+
{
131+
struct cgr_acc_ctx *acc_ctx;
119132
struct cgr_kv *kv;
120133
struct list_head *l, *sl;
121134
struct list_head *t, *st;
@@ -132,14 +145,8 @@ struct cgr_acc_ctx *cgr_tryget_acc_ctx(void)
132145
dlg = cgr_dlgb.get_dlg();
133146
if (!dlg) /* dialog not found yet, moving later */
134147
return NULL;
135-
/* search for the accounting ctx */
136-
if (cgr_dlgb.fetch_dlg_value(dlg, &cgr_ctx_str, &val_type, &ctxstr, 0) < 0)
137-
return NULL;
138-
if (ctxstr.s.len != sizeof(struct cgr_acc_ctx *)) {
139-
LM_BUG("Invalid ctx pointer size %d\n", ctxstr.s.len);
140-
return NULL;
141-
}
142-
acc_ctx = *(struct cgr_acc_ctx **)ctxstr.s.s;
148+
149+
acc_ctx = cgr_fetch_acc_ctx(dlg);
143150
if (!acc_ctx) /* nothing to do now */
144151
return NULL;
145152

@@ -856,6 +863,16 @@ static void cgr_dlg_onwrite(struct dlg_cell *dlg, int type,
856863
pkg_free(sessions_kvs);
857864
}
858865

866+
static void cgr_dlg_destroy(struct dlg_cell *dlg, int type,
867+
struct dlg_cb_params *_params)
868+
{
869+
struct cgr_acc_ctx *ctx = cgr_fetch_acc_ctx(dlg);
870+
if (ctx)
871+
cgr_ref_acc_ctx(ctx, -1, "destroy");
872+
else
873+
LM_DBG("context already released\n");
874+
}
875+
859876
int w_cgr_acc(struct sip_msg* msg, void *flag_c, str* acc_c, str *dst_c,
860877
str *tag_c)
861878
{
@@ -962,6 +979,10 @@ int w_cgr_acc(struct sip_msg* msg, void *flag_c, str* acc_c, str *dst_c,
962979
LM_ERR("cannot register callback for context serialization!\n");
963980
return -1;
964981
}
982+
983+
if (cgr_dlgb.register_dlgcb(dlg, DLGCB_DESTROY,
984+
cgr_dlg_destroy, NULL, NULL) != 0)
985+
LM_ERR("cannot register callback for context release! context might leak!\n");
965986
ctx->engaged = 1;
966987
}
967988

@@ -1277,6 +1298,16 @@ void cgr_loaded_callback(struct dlg_cell *dlg, int type,
12771298
LM_ERR("cannot register callback for database accounting\n");
12781299
goto internal_error;
12791300
}
1301+
if (cgr_dlgb.register_dlgcb(dlg, DLGCB_WRITE_VP,
1302+
cgr_dlg_onwrite, ctx, NULL) != 0) {
1303+
LM_ERR("cannot register callback for context serialization!\n");
1304+
goto internal_error;
1305+
}
1306+
1307+
if (cgr_dlgb.register_dlgcb(dlg, DLGCB_DESTROY,
1308+
cgr_dlg_destroy, NULL, NULL) != 0)
1309+
LM_ERR("cannot register callback for context release! context might leak!\n");
1310+
ctx->engaged = 1;
12801311
LM_DBG("successfully loaded acc ctx=%p\n", ctx);
12811312
return;
12821313
internal_error:

0 commit comments

Comments
 (0)