From 161c541491983112365101207c43a7c828d6e770 Mon Sep 17 00:00:00 2001 From: Razvan Crainea Date: Tue, 16 Aug 2022 14:41:08 +0300 Subject: [PATCH] b2b_entities: provide dlginfo for entity_delete Each module that uses b2b_entities, should duplicate the dlginfo structure and pass it to the entity_delete API call, otherwise wrong entities might be deleted due to mismatches (cherry picked from commit ce19581557c69dafee5095fecce831e2c2d80704) --- modules/b2b_entities/b2be_load.h | 31 +++++++++++++++++++++++++ modules/b2b_sdp_demux/b2b_sdp_demux.c | 24 +++++++++++++++---- modules/media_exchange/media_exchange.c | 17 ++++++++------ modules/media_exchange/media_sessions.c | 4 +++- modules/media_exchange/media_sessions.h | 1 + modules/msrp_ua/msrp_ua.c | 11 ++++++++- modules/msrp_ua/msrp_ua.h | 1 + 7 files changed, 76 insertions(+), 13 deletions(-) diff --git a/modules/b2b_entities/b2be_load.h b/modules/b2b_entities/b2be_load.h index df0be9581c2..86abfe74066 100644 --- a/modules/b2b_entities/b2be_load.h +++ b/modules/b2b_entities/b2be_load.h @@ -194,4 +194,35 @@ static inline int load_b2b_api( struct b2b_api *b2b_api) return load_b2b( b2b_api ); } +static inline b2b_dlginfo_t *b2b_dup_dlginfo(b2b_dlginfo_t *info) +{ + b2b_dlginfo_t* dlg = NULL; + int size; + + size = sizeof(b2b_dlginfo_t) + info->callid.len; + if (info->totag.s) + size += info->totag.len; + if (info->fromtag.s) + size += info->fromtag.len; + dlg = shm_malloc(size); + if (!dlg) + return NULL; + memset(dlg, 0, size); + + dlg->callid.s = (char *)(dlg + 1); + dlg->callid.len = info->callid.len; + memcpy(dlg->callid.s, info->callid.s, dlg->callid.len); + if (info->totag.s) { + dlg->totag.len = info->totag.len; + dlg->totag.s = dlg->callid.s + dlg->callid.len; + memcpy(dlg->totag.s, info->totag.s, dlg->totag.len); + } + if (info->fromtag.s) { + dlg->fromtag.len = info->fromtag.len; + dlg->fromtag.s = dlg->callid.s + dlg->callid.len + dlg->totag.len; + memcpy(dlg->fromtag.s, info->fromtag.s, dlg->fromtag.len); + } + return dlg; +} + #endif diff --git a/modules/b2b_sdp_demux/b2b_sdp_demux.c b/modules/b2b_sdp_demux/b2b_sdp_demux.c index d722be31ed8..ef25c7bd3cb 100644 --- a/modules/b2b_sdp_demux/b2b_sdp_demux.c +++ b/modules/b2b_sdp_demux/b2b_sdp_demux.c @@ -213,6 +213,7 @@ struct b2b_sdp_client { str hdrs; str body; str b2b_key; + b2b_dlginfo_t *dlginfo; struct b2b_sdp_ctx *ctx; struct list_head streams; struct list_head list; @@ -416,7 +417,7 @@ static void b2b_sdp_client_terminate(struct b2b_sdp_client *client, str *key) b2b_api.send_request(&req_data); LM_INFO("[%.*s] client request %.*s sent\n", key->len, key->s, method.len, method.s); delete: - b2b_api.entity_delete(B2B_CLIENT, key, NULL, 1, 1); + b2b_api.entity_delete(B2B_CLIENT, key, client->dlginfo, 1, 1); } static void b2b_sdp_client_free(void *param) @@ -439,6 +440,8 @@ static void b2b_sdp_client_free(void *param) list_for_each_safe(it, safe, &client->streams) b2b_sdp_stream_free(list_entry(it, struct b2b_sdp_stream, list)); + if (client->dlginfo) + shm_free(client->dlginfo); shm_free(client); } @@ -953,7 +956,7 @@ static int b2b_sdp_client_bye(struct sip_msg *msg, struct b2b_sdp_client *client b2b_sdp_client_remove(client); b2b_sdp_reply(&client->b2b_key, B2B_CLIENT, METHOD_BYE, 200, NULL); b2b_sdp_client_release(client, 1); - b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, NULL, 1, 1); + b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, client->dlginfo, 1, 1); lock_get(&ctx->lock); switch (b2b_sdp_bye_mode) { @@ -1203,7 +1206,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien /* client was not started, thus this is a final negative reply */ b2b_sdp_client_release_streams(client); b2b_sdp_client_release(client, 0); - b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, NULL, 1, 1); + b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, client->dlginfo, 1, 1); } } body = NULL; @@ -1239,6 +1242,19 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien return ret; } +int b2b_sdp_client_dlginfo(str *logic_key, str *key, int src, b2b_dlginfo_t *info, void *param) +{ + struct b2b_sdp_client *client = (struct b2b_sdp_client *)param; + + client->dlginfo = b2b_dup_dlginfo(info); + if (!client->dlginfo) { + LM_ERR("could not duplicate b2be dialog info!\n"); + return -1; + } + + return 0; +} + static int b2b_sdp_client_notify(struct sip_msg *msg, str *key, int type, str *logic_key, void *param, int flags) { @@ -1601,7 +1617,7 @@ static int b2b_sdp_demux_start(struct sip_msg *msg, str *uri, ci.avps = clone_avp_list( *get_avp_list() ); client->flags |= B2B_SDP_CLIENT_EARLY|B2B_SDP_CLIENT_PENDING; - b2b_key = b2b_api.client_new(&ci, b2b_sdp_client_notify, NULL, + b2b_key = b2b_api.client_new(&ci, b2b_sdp_client_notify, b2b_sdp_client_dlginfo, &b2b_sdp_demux_client_cap, &ctx->callid, NULL, client, b2b_sdp_client_free); if (!b2b_key) { diff --git a/modules/media_exchange/media_exchange.c b/modules/media_exchange/media_exchange.c index 3421f8319e8..36bb112a1b2 100644 --- a/modules/media_exchange/media_exchange.c +++ b/modules/media_exchange/media_exchange.c @@ -330,7 +330,7 @@ static int handle_media_fork_to_uri(struct media_session_leg *msl, struct socket if (shm_str_dup(&msl->b2b_key, b2b_key) < 0) { LM_ERR("could not copy b2b client key\n"); /* key is not yet stored, so cannot be deleted */ - media_b2b.entity_delete(B2B_CLIENT, b2b_key, NULL, 1, 1); + media_b2b.entity_delete(B2B_CLIENT, b2b_key, msl->dlginfo, 1, 1); goto destroy; } msl->b2b_entity = B2B_CLIENT; @@ -513,7 +513,7 @@ static int media_fork_from_call(struct sip_msg *msg, str *callid, int leg, int * if (shm_str_dup(&msl->b2b_key, b2b_key) < 0) { LM_ERR("could not copy b2b server key for callid %.*s\n", callid->len, callid->s); /* key is not yet stored, so cannot be deleted */ - media_b2b.entity_delete(B2B_SERVER, b2b_key, NULL, 1, 1); + media_b2b.entity_delete(B2B_SERVER, b2b_key, msl->dlginfo, 1, 1); goto destroy; } if (!msl->ms->rtp) { @@ -617,7 +617,7 @@ static int handle_media_exchange_from_uri(struct socket_info *si, struct dlg_cel if (shm_str_dup(&msl->b2b_key, b2b_key) < 0) { LM_ERR("could not copy b2b client key\n"); /* key is not yet stored, so cannot be deleted */ - media_b2b.entity_delete(B2B_CLIENT, b2b_key, NULL, 1, 1); + media_b2b.entity_delete(B2B_CLIENT, b2b_key, msl->dlginfo, 1, 1); goto unref; } msl->b2b_entity = B2B_CLIENT; @@ -811,7 +811,7 @@ static int media_exchange_to_call(struct sip_msg *msg, str *callid, int leg, int if (shm_str_dup(&msl->b2b_key, b2b_key) < 0) { LM_ERR("could not copy b2b server key for callid %.*s\n", callid->len, callid->s); /* key is not yet stored, so cannot be deleted */ - media_b2b.entity_delete(B2B_SERVER, b2b_key, NULL, 1, 1); + media_b2b.entity_delete(B2B_SERVER, b2b_key, msl->dlginfo, 1, 1); goto destroy; } msl->b2b_entity = B2B_SERVER; @@ -1454,9 +1454,12 @@ static int b2b_media_notify(struct sip_msg *msg, str *key, int type, static int b2b_media_confirm(str* key, str* entity_key, int src, b2b_dlginfo_t* info, void *param) { - /* TODO: copy from info fromtag, totag, callid - struct media_session_leg *msl = *(struct media_session_leg **)((str *)key)->s; - */ + struct media_session_leg *msl = (struct media_session_leg *)param; + msl->dlginfo = b2b_dup_dlginfo(info); + if (!msl->dlginfo) { + LM_ERR("could not duplicate b2be dialog info!\n"); + return -1; + } return 0; } diff --git a/modules/media_exchange/media_sessions.c b/modules/media_exchange/media_sessions.c index dd463999b81..924b84ca6f2 100644 --- a/modules/media_exchange/media_sessions.c +++ b/modules/media_exchange/media_sessions.c @@ -73,7 +73,7 @@ void media_session_leg_free(struct media_session_leg *msl) msl, msl->ms); } if (msl->b2b_key.s) { - media_b2b.entity_delete(msl->b2b_entity, &msl->b2b_key, NULL, 1, 1); + media_b2b.entity_delete(msl->b2b_entity, &msl->b2b_key, msl->dlginfo, 1, 1); shm_free(msl->b2b_key.s); msl->b2b_key.s = NULL; } @@ -81,6 +81,8 @@ void media_session_leg_free(struct media_session_leg *msl) if (msl->params && msl->type == MEDIA_SESSION_TYPE_FORK) shm_free(msl->params); //media_forks_free(msl->params); + if (msl->dlginfo) + shm_free(msl->dlginfo); shm_free(msl); } diff --git a/modules/media_exchange/media_sessions.h b/modules/media_exchange/media_sessions.h index d4c73f2586b..a14084e0797 100644 --- a/modules/media_exchange/media_sessions.h +++ b/modules/media_exchange/media_sessions.h @@ -44,6 +44,7 @@ struct media_session_leg { str b2b_key; int nohold; gen_lock_t lock; + b2b_dlginfo_t *dlginfo; enum b2b_entity_type b2b_entity; struct media_session_leg *next; void *params; diff --git a/modules/msrp_ua/msrp_ua.c b/modules/msrp_ua/msrp_ua.c index 23e5dd60fb2..4ae82a40752 100644 --- a/modules/msrp_ua/msrp_ua.c +++ b/modules/msrp_ua/msrp_ua.c @@ -400,6 +400,9 @@ static void free_msrpua_session(void *val) if (sess->peer_accept_types.s) shm_free(sess->peer_accept_types.s); + if (sess->dlginfo) + shm_free(sess->dlginfo); + shm_free(sess); } @@ -408,7 +411,7 @@ static void msrpua_delete_session(struct msrpua_session *sess) LM_DBG("Deleting session [%.*s]\n", sess->session_id.len, sess->session_id.s); if (sess->b2b_key.s) - b2b_api.entity_delete(sess->b2b_type, &sess->b2b_key, NULL, 1, 1); + b2b_api.entity_delete(sess->b2b_type, &sess->b2b_key, sess->dlginfo, 1, 1); hash_remove_key(msrpua_sessions, sess->session_id); free_msrpua_session(sess); @@ -1699,6 +1702,12 @@ static int msrpua_answer(struct sip_msg *msg, str *content_types) int b2b_add_dlginfo(str* key, str* entity_key, int src, b2b_dlginfo_t* dlginfo, void *param) { + struct msrpua_session *sess = (struct msrpua_session *)param; + sess->dlginfo = b2b_dup_dlginfo(dlginfo); + if (!sess->dlginfo) { + LM_ERR("could not duplicate b2be dialog info!\n"); + return -1; + } return 0; } diff --git a/modules/msrp_ua/msrp_ua.h b/modules/msrp_ua/msrp_ua.h index b6cf2335f49..3a8f745d1d9 100644 --- a/modules/msrp_ua/msrp_ua.h +++ b/modules/msrp_ua/msrp_ua.h @@ -49,6 +49,7 @@ struct msrpua_session { int sdp_sess_id; int sdp_sess_vers; int lifetime; + b2b_dlginfo_t *dlginfo; struct msrp_ua_handler hdl; };