@@ -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+
859876int 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 ;
12821313internal_error :
0 commit comments