Skip to content

Commit

Permalink
Fix CANCEL matching in B2B stack
Browse files Browse the repository at this point in the history
Instead of attempting a dialog level matching (callid and tags), do a proper incoming CANCEL matching at transaction level.
This fixes scenarios where the B2B handles several branches of a call that was forked by an ahead proxy.
Many thanks to Denys Pozniak for reporting
  • Loading branch information
bogdan-iancu committed Aug 16, 2022
1 parent 37df05a commit 30214dc
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
20 changes: 14 additions & 6 deletions modules/b2b_entities/dlg.c
Expand Up @@ -501,8 +501,8 @@ void set_dlg_state(b2b_dlg_t* dlg, int meth)
}
}

b2b_dlg_t* b2bl_search_iteratively(str* callid, str* from_tag, str* ruri,
unsigned int hash_index)
static b2b_dlg_t* b2bl_search_iteratively(str* callid, str* from_tag,
struct cell *T, unsigned int hash_index)
{
b2b_dlg_t* dlg= NULL;

Expand All @@ -514,15 +514,16 @@ b2b_dlg_t* b2bl_search_iteratively(str* callid, str* from_tag, str* ruri,
dlg = server_htable[hash_index].first;
while(dlg)
{
LM_DBG("Found callid= %.*s, tag= %.*s\n", dlg->callid.len, dlg->callid.s,
LM_DBG("Found callid= %.*s, tag= %.*s\n",
dlg->callid.len, dlg->callid.s,
dlg->tag[CALLER_LEG].len, dlg->tag[CALLER_LEG].s);
if(dlg->callid.len == callid->len && strncmp(dlg->callid.s, callid->s, callid->len)== 0 &&
dlg->tag[CALLER_LEG].len == from_tag->len &&
strncmp(dlg->tag[CALLER_LEG].s, from_tag->s, from_tag->len)== 0)
{
if(!ruri)
if(!T || !dlg->uas_tran)
break;
if(ruri->len == dlg->ruri.len && strncmp(ruri->s, dlg->ruri.s, ruri->len)== 0)
if(T == dlg->uas_tran)
break;
}
dlg = dlg->next;
Expand Down Expand Up @@ -844,6 +845,7 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam)
{
/*str ruri= msg->first_line.u.request.uri;*/
str reply_text={"canceling", 9};
struct cell *T_invite = NULL;
/* This makes no sense - why not accepting a CANCEL that was
generated by other b2b instance ? or ourselves ? - bogdan
if(b2b_parse_key(&callid, &hash_index, &local_index, NULL) >= 0)
Expand All @@ -853,14 +855,20 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam)
}
*/

if ( (T_invite=tmb.t_lookup_original_t(msg))==NULL ) {
LM_DBG("No INVITE transaction found for cancel\n");
return SCB_RUN_ALL;
}

hash_index = core_hash(&callid, &from_tag, server_hsize);
/* As per RFC3261, the RURI must be used when matching the CANCEL
against the INVITE, but we should not do it here as B2B learns
a RURI that may have been changed in script (before invoking the
B2B module), while the CANCEL has the original RURI (as received)
*/
dlg = b2bl_search_iteratively(&callid, &from_tag, NULL/*&ruri*/,
dlg = b2bl_search_iteratively(&callid, &from_tag, T_invite,
hash_index);
tmb.unref_cell( T_invite );
if(dlg == NULL)
{
B2BE_LOCK_RELEASE(server_htable, hash_index);
Expand Down
3 changes: 3 additions & 0 deletions modules/tm/t_lookup.c
Expand Up @@ -577,6 +577,9 @@ struct cell* t_lookupOriginalT( struct sip_msg* p_msg )
return cancelled_T;

/* start searching in the table */
if (!p_msg->hash_index)
p_msg->hash_index = tm_hash( p_msg->callid->body,
get_cseq(p_msg)->number);
hash_index = p_msg->hash_index;
LM_DBG("searching on hash entry %d\n",hash_index );

Expand Down

0 comments on commit 30214dc

Please sign in to comment.