Skip to content

Commit

Permalink
b2b_logic: fix issues when new entities are unused
Browse files Browse the repository at this point in the history
New entities created with b2b_server_new() or b2b_client_new() functions would
leak if they were not eventually used by a b2b_init_request() call. This would
lead to pkg memory leaks and bogus errors from successive calls to
b2b_init_request().

(cherry picked from commit c84fe37)
(cherry picked from commit d914720b0bbf620a30e5c16ff9548733783295ec)
  • Loading branch information
rvlad-patrascu committed Jun 9, 2023
1 parent ed0f04c commit 312056a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 77 deletions.
6 changes: 6 additions & 0 deletions modules/b2b_logic/b2b_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "../../timer.h"
#include "../../pt.h"
#include "../../lib/csv.h"
#include "../../context.h"

#include "records.h"
#include "b2b_logic.h"
Expand Down Expand Up @@ -166,6 +167,8 @@ str b2bl_mod_name = str_init("b2b_logic");
str top_hiding_scen_s;
str internal_scen_s;

int new_ent_1_ctx_idx, new_ent_2_ctx_idx;

/* used to identify the current tuple in local_route, in the context of a request
* that is not triggerd by a received message from an ongoing b2b dialog */
b2bl_tuple_t *local_ctx_tuple;
Expand Down Expand Up @@ -586,6 +589,9 @@ static int mod_init(void)
return -1;
}

new_ent_1_ctx_idx = context_register_ptr(CONTEXT_GLOBAL, new_ent_ctx_destroy);
new_ent_2_ctx_idx = context_register_ptr(CONTEXT_GLOBAL, new_ent_ctx_destroy);

return 0;
}

Expand Down
6 changes: 6 additions & 0 deletions modules/b2b_logic/b2b_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ extern int global_reply_rtid;
extern str top_hiding_scen_s;
extern str internal_scen_s;

extern int new_ent_1_ctx_idx, new_ent_2_ctx_idx;

extern struct b2bl_route_ctx cur_route_ctx;

extern str requestTerminated;
Expand Down Expand Up @@ -180,4 +182,8 @@ int b2b_client_notify(struct sip_msg* msg, str* key, int type, void* param,
int flags);
void b2bl_db_init(void);

int b2b_get_local_contact(struct sip_msg *msg, str *from_uri, str *local_contact);

void new_ent_ctx_destroy(void *e);

#endif
164 changes: 87 additions & 77 deletions modules/b2b_logic/logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ extern struct b2b_ctx_val *local_ctx_vals;
extern int req_routeid;
extern int reply_routeid;

struct b2bl_new_entity *new_entities[MAX_BRIDGE_ENT-1];
int new_entities_no;

struct b2bl_route_ctx cur_route_ctx;

struct to_body* get_b2bl_from(struct sip_msg* msg);
Expand All @@ -97,6 +94,29 @@ str requestTerminated = str_init("Request Terminated");
#define get_tracer(_tuple) \
( (_tuple)->tracer.f ? &((_tuple)->tracer) : NULL )

int get_new_entities(struct b2bl_new_entity **entity1,
struct b2bl_new_entity **entity2)
{
if (!current_processing_ctx) {
LM_ERR("no current processing ctx!\n");
*entity1 = NULL;
*entity2 = NULL;
return -1;
}

*entity1 = context_get_ptr(CONTEXT_GLOBAL, current_processing_ctx,
new_ent_1_ctx_idx);
*entity2 = context_get_ptr(CONTEXT_GLOBAL, current_processing_ctx,
new_ent_2_ctx_idx);

return 0;
}

void new_ent_ctx_destroy(void *e)
{
pkg_free(e);
}

int entity_add_dlginfo(b2bl_entity_id_t* entity, b2b_dlginfo_t* dlginfo)
{
b2b_dlginfo_t* new_dlginfo= NULL;
Expand Down Expand Up @@ -1367,13 +1387,8 @@ int retry_init_bridge(struct sip_msg *msg, b2bl_tuple_t* tuple,
tuple->bridge_entities[0]->peer = tuple->bridge_entities[1];
tuple->bridge_entities[1]->peer = tuple->bridge_entities[0];

pkg_free(new_entities[0]);
new_entities[0] = NULL;

return 0;
error:
pkg_free(new_entities[0]);
new_entities[0] = NULL;
return -1;
}

Expand Down Expand Up @@ -2419,7 +2434,7 @@ int b2b_pass_request(struct sip_msg *msg)
static struct b2bl_new_entity *get_ent_to_bridge(b2bl_tuple_t *tuple,
b2bl_entity_id_t *cur_entity, str *ent_str, b2bl_entity_id_t **old_ent)
{
struct b2bl_new_entity *new_br_ent = NULL;
struct b2bl_new_entity *new_br_ent = NULL, *e1, *e2;
b2bl_entity_id_t** entity_head = NULL;
b2bl_entity_id_t *e;
int i;
Expand Down Expand Up @@ -2468,13 +2483,16 @@ static struct b2bl_new_entity *get_ent_to_bridge(b2bl_tuple_t *tuple,
}
}
if (!*old_ent) {
if (get_new_entities(&e1, &e2) < 0) {
LM_ERR("Failed to get new bridging entities from context\n");
return NULL;
}

/* must be a new entity created with b2b_client_new() */
if (new_entities[0] && new_entities[0]->type == B2B_CLIENT &&
!str_strcmp(ent_str, &new_entities[0]->id))
new_br_ent = new_entities[0];
else if (new_entities[1] && new_entities[1]->type == B2B_CLIENT &&
!str_strcmp(ent_str, &new_entities[1]->id))
new_br_ent = new_entities[1];
if (e1 && e1->type == B2B_CLIENT && !str_strcmp(ent_str, &e1->id))
new_br_ent = e1;
else if (e2 && e2->type == B2B_CLIENT && !str_strcmp(ent_str, &e2->id))
new_br_ent = e2;
else
LM_ERR("Unknown bridge entity: %.*s\n", ent_str->len, ent_str->s);
}
Expand Down Expand Up @@ -2523,7 +2541,11 @@ int b2b_scenario_bridge(struct sip_msg *msg, str *br_ent1_str, str *br_ent2_str,
}
}

if (new_entities_no == 0) {
if (get_new_entities(&new_br_ent[0], &new_br_ent[1]) < 0) {
LM_ERR("Failed to get new bridging entities from context\n");
goto done;
}
if (!new_br_ent[0] && !new_br_ent[1]) {
LM_ERR("At least one new client entity required for bridging\n");
goto done;
}
Expand Down Expand Up @@ -2572,16 +2594,6 @@ int b2b_scenario_bridge(struct sip_msg *msg, str *br_ent1_str, str *br_ent2_str,
done:
lock_release(&b2bl_htable[cur_route_ctx.hash_index].lock);

if (new_entities[0]) {
pkg_free(new_entities[0]);
new_entities[0] = NULL;
}
if (new_entities[1]) {
pkg_free(new_entities[1]);
new_entities[1] = NULL;
}
new_entities_no = 0;

return rc;
}

Expand Down Expand Up @@ -3672,6 +3684,7 @@ str* b2b_process_scenario_init(struct sip_msg* msg, b2bl_cback_f cbf,
str *hdrs;
struct b2bl_new_entity *new_entity;
struct sip_uri ct_uri;
struct b2bl_new_entity *e1, *e2;
int maxfwd;

if(msg == NULL)
Expand Down Expand Up @@ -3738,15 +3751,20 @@ str* b2b_process_scenario_init(struct sip_msg* msg, b2bl_cback_f cbf,
ctx->hash_index = hash_index;
ctx->local_index = tuple->id;

if (new_entities_no != MAX_BRIDGE_ENT-1) {
if (get_new_entities(&e1, &e2) < 0) {
LM_ERR("Failed to get new bridging entities from context\n");
return NULL;
}

if (!e1 && !e2) {
LM_ERR("Two bridge entities required!\n");
goto error;
}

if (new_entities[0]->type == B2B_SERVER)
new_entity = new_entities[0];
else if (new_entities[1]->type == B2B_SERVER)
new_entity = new_entities[1];
if (e1->type == B2B_SERVER)
new_entity = e1;
else if (e2->type == B2B_SERVER)
new_entity = e2;
else {
LM_ERR("Server entity required\n");
goto error;
Expand Down Expand Up @@ -3778,10 +3796,10 @@ str* b2b_process_scenario_init(struct sip_msg* msg, b2bl_cback_f cbf,

new_entity = NULL;

if (new_entities[0]->type == B2B_CLIENT)
new_entity = new_entities[0];
else if (new_entities[1]->type == B2B_CLIENT)
new_entity = new_entities[1];
if (e1->type == B2B_CLIENT)
new_entity = e1;
else if (e2->type == B2B_CLIENT)
new_entity = e2;
else {
LM_ERR("Client entity required\n");
goto error;
Expand Down Expand Up @@ -3863,12 +3881,6 @@ str* b2b_process_scenario_init(struct sip_msg* msg, b2bl_cback_f cbf,
tuple->bridge_entities[0]->peer = tuple->bridge_entities[1];
tuple->bridge_entities[1]->peer = tuple->bridge_entities[0];

pkg_free(new_entities[0]);
pkg_free(new_entities[1]);
new_entities[0] = NULL;
new_entities[1] = NULL;
new_entities_no = 0;

tuple->cbf = cbf;
tuple->cb_mask = cb_mask;
tuple->cb_param = cb_param;
Expand All @@ -3893,16 +3905,6 @@ str* b2b_process_scenario_init(struct sip_msg* msg, b2bl_cback_f cbf,
if(to_uri.s)
pkg_free(to_uri.s);

if (new_entities[0]) {
pkg_free(new_entities[0]);
new_entities[0] = NULL;
}
if (new_entities[1]) {
pkg_free(new_entities[1]);
new_entities[1] = NULL;
}
new_entities_no = 0;

local_ctx_tuple = NULL;

return NULL;
Expand Down Expand Up @@ -4022,6 +4024,7 @@ str* internal_init_scenario(struct sip_msg* msg, str *scen_name,
unsigned int cb_mask, str* custom_hdrs)
{
struct b2b_params init_params;
struct b2bl_new_entity *new_ent;

if (b2bl_key_avp_name >= 0)
destroy_avps( b2bl_key_avp_type, b2bl_key_avp_name, 1);
Expand All @@ -4043,29 +4046,33 @@ str* internal_init_scenario(struct sip_msg* msg, str *scen_name,
}

if (init_params.id == B2B_INTERNAL_ID_PTR) {
new_entities[0] = pkg_malloc(sizeof(struct b2bl_new_entity));
if (!new_entities[0]) {
new_ent = pkg_malloc(sizeof(struct b2bl_new_entity));
if (!new_ent) {
LM_ERR("No more pkg memory!\n");
goto error;
}
memset(new_entities[0], 0, sizeof(struct b2bl_new_entity));
memset(new_ent, 0, sizeof(struct b2bl_new_entity));

new_entities[0]->type = scen_params->e1_type;
new_entities[0]->dest_uri = scen_params->e1_to;
new_entities[0]->from_dname = scen_params->e1_from_dname;
new_ent->type = scen_params->e1_type;
new_ent->dest_uri = scen_params->e1_to;
new_ent->from_dname = scen_params->e1_from_dname;

new_entities[1] = pkg_malloc(sizeof(struct b2bl_new_entity));
if (!new_entities[1]) {
context_put_ptr(CONTEXT_GLOBAL, current_processing_ctx,
new_ent_1_ctx_idx, new_ent);

new_ent = pkg_malloc(sizeof(struct b2bl_new_entity));
if (!new_ent) {
LM_ERR("No more pkg memory!\n");
goto error;
}
memset(new_entities[1], 0, sizeof(struct b2bl_new_entity));
memset(new_ent, 0, sizeof(struct b2bl_new_entity));

new_entities[1]->type = scen_params->e2_type;
new_entities[1]->dest_uri = scen_params->e2_to;
new_entities[1]->from_dname = scen_params->e2_from_dname;
new_ent->type = scen_params->e2_type;
new_ent->dest_uri = scen_params->e2_to;
new_ent->from_dname = scen_params->e2_from_dname;

new_entities_no = 2;
context_put_ptr(CONTEXT_GLOBAL, current_processing_ctx,
new_ent_2_ctx_idx, new_ent);
}

return init_request(msg, &init_params, cbf, cb_param, cb_mask, custom_hdrs);
Expand All @@ -4075,15 +4082,6 @@ str* internal_init_scenario(struct sip_msg* msg, str *scen_name,
}

error:
if (new_entities[0]) {
pkg_free(new_entities[0]);
new_entities[0] = NULL;
}
if (new_entities[1]) {
pkg_free(new_entities[1]);
new_entities[1] = NULL;
}
new_entities_no = 0;
return NULL;
}

Expand Down Expand Up @@ -4154,11 +4152,16 @@ int b2bl_entity_new(struct sip_msg *msg, str *id, str *dest_uri, str *proxy,
str *adv_contact)
{
unsigned short type;
struct b2bl_new_entity *entity;
struct b2bl_new_entity *entity, *e1, *e2;
struct sip_uri sip_uri;
unsigned int size;

if (new_entities_no == MAX_BRIDGE_ENT-1) {
if (get_new_entities(&e1, &e2) < 0) {
LM_ERR("Failed to get new bridging entities from context\n");
return -1;
}

if (e1 && e2) {
LM_ERR("New bridge entities already created!\n");
return -1;
}
Expand Down Expand Up @@ -4255,7 +4258,15 @@ int b2bl_entity_new(struct sip_msg *msg, str *id, str *dest_uri, str *proxy,

entity->type = etype;

new_entities[new_entities_no++] = entity;
if (!e1) {
context_put_ptr(CONTEXT_GLOBAL, current_processing_ctx,
new_ent_1_ctx_idx, entity);
LM_DBG("First new entity [%.*s] saved in context\n", id->len, id->s);
} else {
context_put_ptr(CONTEXT_GLOBAL, current_processing_ctx,
new_ent_2_ctx_idx, entity);
LM_DBG("Second new entity [%.*s] saved in context\n", id->len, id->s);
}

return 1;
error:
Expand Down Expand Up @@ -4491,7 +4502,6 @@ int b2bl_bridge(str* key, str* new_dst, str *new_proxy, str* new_from_dname,
return -1;
}


int b2bl_terminate_call(str* key)
{
unsigned int hash_index, local_index;
Expand Down

0 comments on commit 312056a

Please sign in to comment.