Skip to content

Commit

Permalink
b2b_entities: proper handling of overlapping BYE
Browse files Browse the repository at this point in the history
Although in normal circumstances we should reply with a 500 reply code,
in case a BYE is received, we should process it accordingly, and as soon
as the overlapping transaction completes, we should terminate the other
leg as well.

Completes c4032f9

(cherry picked from commit 761e880)
  • Loading branch information
razvancrainea committed Oct 13, 2023
1 parent 11dedbd commit a9704bb
Showing 1 changed file with 49 additions and 32 deletions.
81 changes: 49 additions & 32 deletions modules/b2b_entities/dlg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,55 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam)
{
LM_ERR("failed to send reply with tm\n");
}
LM_DBG("Sent reply [200] and unreffed the cell %p\n",
tm_tran);

tmb.unref_cell(tm_tran); /* for t_newtran() */
b2b_cb_flags |= B2B_NOTIFY_FL_TERM_BYE;
goto run_cb;
}
tmb.unref_cell(tm_tran); /* for t_newtran() */
lock_release(&table[hash_index].lock);
return SCB_DROP_MSG;
} else
if(dlg->uas_tran && dlg->uas_tran!=T_UNDEFINED)
{
if (method_value != METHOD_BYE) {
/* We have another UAS ongoing transaction on the dialog
* -> reject with 500, "Overlapping Requests" */
#define RETRY_AFTER_HDR "Retry-After: "
#define RETRY_AFTER_HDR_LEN (sizeof("Retry-After: ")-1)
char ra_s[RETRY_AFTER_HDR_LEN + 3 + CRLF_LEN];
str ra = {ra_s, 0};
str text = str_init("Overlapping Requests");
LM_DBG("Received another request when the previous "
"one was in process\n");
memcpy( ra.s+ra.len, RETRY_AFTER_HDR, RETRY_AFTER_HDR_LEN);
ra.len += RETRY_AFTER_HDR_LEN;
/* the retry value is between 0 and 10 */
ra.len += btostr(ra.s+ra.len, (unsigned char)(rand()%10) );
memcpy( ra.s+ra.len, CRLF, CRLF_LEN);
ra.len += CRLF_LEN;
/* send reply */
if(tmb.t_reply_with_body( tm_tran, 500,
&text, 0, &ra, &to_tag) < 0)
{
LM_ERR("failed to send reply with tm\n");
}
LM_DBG("Sent reply [500] and unreffed the cell %p\n",
tm_tran);
tmb.unref_cell(tm_tran); /* for t_newtran() */
lock_release(&table[hash_index].lock);
return SCB_DROP_MSG;
} else {
LM_DBG("Received BYE while having an ongoing "
"inbound/UAS transaction\n");
str text_ok = str_init("OK");
if(tmb.t_reply_with_body( tm_tran, 200,
&text_ok, 0, 0, &to_tag) < 0)
{
LM_ERR("failed to send reply with tm\n");
}
LM_DBG("Sent reply [200] and unreffed the cell %p\n",
tm_tran);
tmb.unref_cell(tm_tran);
Expand All @@ -1203,38 +1252,6 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam)
b2b_cb_flags |= B2B_NOTIFY_FL_TERM_BYE;
goto run_cb;
}
tmb.unref_cell(tm_tran); /* for t_newtran() */
lock_release(&table[hash_index].lock);
return SCB_DROP_MSG;
} else
if(dlg->uas_tran && dlg->uas_tran!=T_UNDEFINED)
{
/* We have another UAS ongoing transaction on the dialog
* -> reject with 500, "Overlapping Requests" */
#define RETRY_AFTER_HDR "Retry-After: "
#define RETRY_AFTER_HDR_LEN (sizeof("Retry-After: ")-1)
char ra_s[RETRY_AFTER_HDR_LEN + 3 + CRLF_LEN];
str ra = {ra_s, 0};
str text = str_init("Overlapping Requests");
LM_DBG("Received another request when the previous "
"one was in process\n");
memcpy( ra.s+ra.len, RETRY_AFTER_HDR, RETRY_AFTER_HDR_LEN);
ra.len += RETRY_AFTER_HDR_LEN;
/* the retry value is between 0 and 10 */
ra.len += btostr(ra.s+ra.len, (unsigned char)(rand()%10) );
memcpy( ra.s+ra.len, CRLF, CRLF_LEN);
ra.len += CRLF_LEN;
/* send reply */
if(tmb.t_reply_with_body( tm_tran, 500,
&text, 0, &ra, &to_tag) < 0)
{
LM_ERR("failed to send reply with tm\n");
}
LM_DBG("Sent reply [500] and unreffed the cell %p\n",
tm_tran);
tmb.unref_cell(tm_tran); /* for t_newtran() */
lock_release(&table[hash_index].lock);
return SCB_DROP_MSG;
}

/* the new request is accepted for handling */
Expand Down

0 comments on commit a9704bb

Please sign in to comment.