Skip to content

Commit

Permalink
[b2b_logic] fix crash on tracing expired b2b tuples
Browse files Browse the repository at this point in the history
When a tuple expires via timer, be sure to provide a processing context, otherwise the tracer (if enabled) will simply crash.
As part of the fix, two new helper functions were added for pushing and poping new processing contexts - these are to be reused by some prev similar fix on uac_registrant.
Related to #3110
Many thanks to @vtzan for helping with the troubleshooting and testing

(cherry picked from commit 2a3eb1e)
  • Loading branch information
bogdan-iancu committed Jun 30, 2023
1 parent 57c2a8d commit a0bbd60
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
39 changes: 39 additions & 0 deletions context.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,45 @@ int ensure_global_context(void)
}


#define CTX_STACK_SIZE 8
static context_p ctx_stack[CTX_STACK_SIZE];
static unsigned int ctx_stack_idx = 0;

int push_new_global_context(void)
{
if (ctx_stack_idx==CTX_STACK_SIZE) {
LM_ERR("too many stacked contexts (%d)\n",ctx_stack_idx);
return -1;
}

ctx_stack[ctx_stack_idx++] = current_processing_ctx;

current_processing_ctx = context_alloc(CONTEXT_GLOBAL);
if (!current_processing_ctx) {
LM_ERR("oom\n");
current_processing_ctx = ctx_stack[--ctx_stack_idx];
return -1;
}

memset(current_processing_ctx, 0, context_size(CONTEXT_GLOBAL));
return 0;
}

int pop_pushed_global_context(void)
{
if (ctx_stack_idx==0) {
LM_ERR("nothing to pop form the stack\n");
return -1;
}

context_destroy(CONTEXT_GLOBAL, current_processing_ctx);
context_free(current_processing_ctx);

current_processing_ctx = ctx_stack[--ctx_stack_idx];
return 0;
}


void clear_global_context(void)
{
if (current_processing_ctx) {
Expand Down
6 changes: 6 additions & 0 deletions context.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ context_p context_alloc(enum osips_context type);
int ensure_global_context(void);


/* pushes or pops a context level from internal stack
*/
int push_new_global_context(void);
int pop_pushed_global_context(void);


/* free and reset the global context */
void clear_global_context(void);

Expand Down
33 changes: 22 additions & 11 deletions modules/b2b_logic/b2b_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,11 +682,12 @@ void b2bl_db_timer_update(unsigned int ticks, void* param)
b2b_logic_dump(0);
}

static void term_entity(b2bl_entity_id_t *entity, int hash_index)
static void term_entity(b2bl_entity_id_t *entity, int hash_index, str *key)
{
str bye = {BYE, BYE_LEN};
b2b_req_data_t req_data;
b2b_rpl_data_t rpl_data;
struct b2b_context *ctx;

if (entity->type == B2B_SERVER &&
entity->state != B2BL_ENT_CONFIRMED) {
Expand All @@ -710,12 +711,22 @@ static void term_entity(b2bl_entity_id_t *entity, int hash_index)
entity->key.s);
b2bl_htable[hash_index].locked_by = -1;
} else {
memset(&req_data, 0, sizeof(b2b_req_data_t));
PREP_REQ_DATA(entity);
req_data.method =&bye;
b2bl_htable[hash_index].locked_by = process_no;
b2b_api.send_request(&req_data);
b2bl_htable[hash_index].locked_by = -1;
if ( key && ( !push_new_global_context() ||
(ctx=b2b_api.get_context())==NULL ||
pkg_str_dup(&ctx->b2bl_key, key)==0 )
) {
LM_ERR("preparing ctx for request failed, entity [%.*s]\n",
entity->key.len, entity->key.s);
} else {
memset(&req_data, 0, sizeof(b2b_req_data_t));
PREP_REQ_DATA(entity);
req_data.method =&bye;
b2bl_htable[hash_index].locked_by = process_no;
b2b_api.send_request(&req_data);
b2bl_htable[hash_index].locked_by = -1;
if (key)
pop_pushed_global_context();
}
}
}

Expand All @@ -741,10 +752,10 @@ void b2bl_clean(unsigned int ticks, void* param)
if(tuple->bridge_entities[0] && tuple->bridge_entities[1] && !tuple->to_del)
{
if(!tuple->bridge_entities[0]->disconnected)
term_entity(tuple->bridge_entities[0], i);
term_entity(tuple->bridge_entities[0], i, tuple->key);

if(!tuple->bridge_entities[1]->disconnected)
term_entity(tuple->bridge_entities[1], i);
term_entity(tuple->bridge_entities[1], i, tuple->key);
}
b2bl_delete(tuple, i, 1, tuple->repl_flag != TUPLE_REPL_RECV);
}
Expand Down Expand Up @@ -1206,12 +1217,12 @@ static mi_response_t *mi_b2b_terminate_call(const mi_params_t *params,
if(tuple->bridge_entities[0] && tuple->bridge_entities[1] && !tuple->to_del)
{
if(!tuple->bridge_entities[0]->disconnected) {
term_entity(tuple->bridge_entities[0], hash_index);
term_entity(tuple->bridge_entities[0], hash_index, &key);
tuple->bridge_entities[0]->disconnected = 1;
}

if(!tuple->bridge_entities[1]->disconnected) {
term_entity(tuple->bridge_entities[1], hash_index);
term_entity(tuple->bridge_entities[1], hash_index, &key);
tuple->bridge_entities[1]->disconnected = 1;
}
}
Expand Down

0 comments on commit a0bbd60

Please sign in to comment.