diff --git a/modules/rtp_relay/rtp_relay.h b/modules/rtp_relay/rtp_relay.h index 662dc576929..c7ce07650e6 100644 --- a/modules/rtp_relay/rtp_relay.h +++ b/modules/rtp_relay/rtp_relay.h @@ -65,6 +65,7 @@ struct rtp_relay_funcs { struct rtp_relay_server *server, void *ctx, str *flags); int (*copy_serialize)(void *ctx, bin_packet_t *packet); int (*copy_deserialize)(void **ctx, bin_packet_t *packet); + void (*copy_release)(void **ctx); }; struct rtp_relay_hooks { diff --git a/modules/rtp_relay/rtp_relay_ctx.c b/modules/rtp_relay/rtp_relay_ctx.c index 0f9f1b3edd1..2a78be35836 100644 --- a/modules/rtp_relay/rtp_relay_ctx.c +++ b/modules/rtp_relay/rtp_relay_ctx.c @@ -82,6 +82,14 @@ static struct { { str_init("disabled"), RTP_RELAY_FLAGS_DISABLED }, }; +typedef struct rtp_copy_ctx { + str id; + void *ctx; + struct rtp_relay *relay; + struct list_head list; +} rtp_copy_ctx; + + static int rtp_relay_offer(struct rtp_relay_session *info, struct rtp_relay_ctx *ctx, struct rtp_relay_sess *sess, int leg, str *body); @@ -226,6 +234,16 @@ static void rtp_relay_ctx_release_leg(struct rtp_relay_leg *leg) rtp_relay_ctx_free_leg(leg); } +static void rtp_copy_ctx_free(struct rtp_copy_ctx *copy_ctx) +{ + if (!copy_ctx) + return; + if (copy_ctx->ctx) + copy_ctx->relay->funcs.copy_release(©_ctx->ctx); + list_del(©_ctx->list); + shm_free(copy_ctx); +}; + static void rtp_relay_ctx_free_sess(struct rtp_relay_ctx *ctx, struct rtp_relay_sess *s) { if (ctx->established == s) @@ -261,6 +279,8 @@ static void rtp_relay_ctx_free(struct rtp_relay_ctx *ctx) list_for_each_safe(it, safe, &ctx->sessions) rtp_relay_ctx_free_sess(ctx, list_entry(it, struct rtp_relay_sess, list)); + list_for_each_safe(it, safe, &ctx->copy_contexts) + rtp_copy_ctx_free(list_entry(it, struct rtp_copy_ctx, list)); lock_start_write(rtp_relay_contexts_lock); if (list_is_valid(&ctx->list)) @@ -752,12 +772,6 @@ static void rtp_relay_b2b_new_local(struct cell* t, int type, struct tmcb_params } \ } while (0) -typedef struct rtp_copy_ctx { - str id; - void *ctx; - struct list_head list; -} rtp_copy_ctx; - rtp_copy_ctx *rtp_copy_ctx_get(struct rtp_relay_ctx *ctx, str *id) { struct list_head *it; @@ -771,7 +785,7 @@ rtp_copy_ctx *rtp_copy_ctx_get(struct rtp_relay_ctx *ctx, str *id) return NULL; } -rtp_copy_ctx *rtp_copy_ctx_new(struct rtp_relay_ctx *ctx, str *id) +rtp_copy_ctx *rtp_copy_ctx_new(struct rtp_relay_ctx *ctx, struct rtp_relay *relay, str *id) { rtp_copy_ctx *copy_ctx = shm_malloc(sizeof(*copy_ctx) + id->len); @@ -781,6 +795,7 @@ rtp_copy_ctx *rtp_copy_ctx_new(struct rtp_relay_ctx *ctx, str *id) copy_ctx->id.s = (char *)(copy_ctx + 1); copy_ctx->id.len = id->len; memcpy(copy_ctx->id.s, id->s, id->len); + copy_ctx->relay = relay; list_add(©_ctx->list, &ctx->copy_contexts); return copy_ctx; }; @@ -942,12 +957,10 @@ static void rtp_relay_loaded_callback(struct dlg_cell *dlg, int type, RTP_RELAY_BIN_POP(int, &index); while (index-- > 0) { RTP_RELAY_BIN_POP(str, &tmp); - copy_ctx = rtp_copy_ctx_new(ctx, &tmp); + copy_ctx = rtp_copy_ctx_new(ctx, relay, &tmp); if (copy_ctx && - !relay->funcs.copy_deserialize(©_ctx->ctx, &packet)) { - list_del(©_ctx->list); - shm_free(copy_ctx); - } + !relay->funcs.copy_deserialize(©_ctx->ctx, &packet)) + rtp_copy_ctx_free(copy_ctx); } RTP_RELAY_BIN_POP(str, &tmp); @@ -2714,7 +2727,7 @@ int rtp_relay_copy_offer(rtp_ctx _ctx, str *id, str *flags, } rtp_copy = rtp_copy_ctx_get(ctx, id); if (!rtp_copy) { - rtp_copy = rtp_copy_ctx_new(ctx, id); + rtp_copy = rtp_copy_ctx_new(ctx, sess->relay, id); if (!rtp_copy) { LM_ERR("oom for rtp copy context!\n"); return -1; @@ -2820,8 +2833,7 @@ int rtp_relay_copy_delete(rtp_ctx _ctx, str *id, str *flags) ret = sess->relay->funcs.copy_delete( &info, &sess->server, copy_ctx->ctx, flags); - list_del(©_ctx->list); - shm_free(copy_ctx); + rtp_copy_ctx_free(copy_ctx); return ret; } diff --git a/modules/rtpengine/rtpengine.c b/modules/rtpengine/rtpengine.c index 033cc2ba3f9..21bbd08ce3e 100644 --- a/modules/rtpengine/rtpengine.c +++ b/modules/rtpengine/rtpengine.c @@ -305,6 +305,7 @@ static int rtpengine_api_copy_delete(struct rtp_relay_session *sess, struct rtp_relay_server *server, void *_ctx, str *flags); static int rtpengine_api_copy_serialize(void *_ctx, bin_packet_t *packet); static int rtpengine_api_copy_deserialize(void **_ctx, bin_packet_t *packet); +static void rtpengine_api_copy_release(void **_ctx); static int parse_flags(struct ng_flags_parse *, struct sip_msg *, enum rtpe_operation *, const char *); @@ -1487,6 +1488,7 @@ static int mod_preinit(void) .copy_delete = rtpengine_api_copy_delete, .copy_serialize = rtpengine_api_copy_serialize, .copy_deserialize = rtpengine_api_copy_deserialize, + .copy_release = rtpengine_api_copy_release, }; if (!pv_parse_spec(&rtpengine_relay_pvar_str, &media_pvar)) return -1; @@ -4439,8 +4441,6 @@ static int rtpengine_api_copy_delete(struct rtp_relay_session *sess, bencode_item_t *ret; ret = rtpengine_api_copy_op(sess, OP_UNSUBSCRIBE, server, subs, flags, 0, NULL); - if (subs) - shm_free(subs); if (!ret) return -1; bencode_buffer_free(bencode_item_buffer(ret)); @@ -4469,6 +4469,14 @@ static int rtpengine_api_copy_deserialize(void **_ctx, bin_packet_t *packet) return 1; } +static void rtpengine_api_copy_release(void **ctx) +{ + if (*ctx) { + shm_free(*ctx); + *ctx = NULL; + } +} + static inline void raise_rtpengine_status_event(struct rtpe_node *node) { static str status_connected = str_init("active"); diff --git a/modules/rtpproxy/rtpproxy.c b/modules/rtpproxy/rtpproxy.c index 371a345a4d6..6843272cf66 100644 --- a/modules/rtpproxy/rtpproxy.c +++ b/modules/rtpproxy/rtpproxy.c @@ -329,6 +329,7 @@ static int rtpproxy_api_copy_delete(struct rtp_relay_session *sess, struct rtp_relay_server *server, void *_ctx, str *flags); static int rtpproxy_api_copy_serialize(void *_ctx, bin_packet_t *packet); static int rtpproxy_api_copy_deserialize(void **_ctx, bin_packet_t *packet); +static void rtpproxy_api_copy_release(void **_ctx); int connect_rtpproxies(struct rtpp_set *filter); int update_rtpp_proxies(struct rtpp_set *filter); @@ -1106,6 +1107,7 @@ static int mod_preinit(void) .copy_delete = rtpproxy_api_copy_delete, .copy_serialize = rtpproxy_api_copy_serialize, .copy_deserialize = rtpproxy_api_copy_deserialize, + .copy_release = rtpproxy_api_copy_release, }; if (!pv_parse_spec(&rtpproxy_relay_pvar_str, &media_pvar)) return -1; @@ -5902,7 +5904,6 @@ static int rtpproxy_api_copy_delete(struct rtp_relay_session *sess, if (nh_lock) lock_stop_read(nh_lock); rtpproxy_free_call_args(&args); - rtpproxy_copy_ctx_free(_ctx); return ret <= 0?-1:1; } @@ -5997,3 +5998,9 @@ static int rtpproxy_api_copy_deserialize(void **_ctx, bin_packet_t *packet) *_ctx = ctx; return -1; } + +static void rtpproxy_api_copy_release(void **_ctx) +{ + rtpproxy_copy_ctx_free(*_ctx); + *_ctx = NULL; +}