Skip to content

Commit 0712680

Browse files
committed
tm: proper handling of t_reply_with_body() in failure route
Credits go to 46Labs for pointing out the limitation
1 parent f59b12f commit 0712680

File tree

3 files changed

+61
-34
lines changed

3 files changed

+61
-34
lines changed

modules/tm/doc/tm_admin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ t_reply(404, "Use $rU not found");
10581058
</itemizedlist>
10591059

10601060
<para>
1061-
This function can be used from REQUEST_ROUTE.
1061+
This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
10621062
</para>
10631063
<example>
10641064
<title><function>t_reply_with_body</function> usage</title>

modules/tm/t_reply.c

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1696,37 +1696,8 @@ int reply_received( struct sip_msg *p_msg )
16961696
return 1;
16971697
}
16981698

1699-
int w_t_reply_body(struct sip_msg* msg, unsigned int* code, str *text,
1700-
str *body)
1701-
{
1702-
struct cell *t;
1703-
int r;
1704-
1705-
t=get_t();
1706-
if ( t==0 || t==T_UNDEFINED ) {
1707-
/* t_reply_with_body() is a bit of a weird function as it
1708-
* receiving as parameter the actual msg, but the transaction
1709-
* (and uses the saved msg from transaction).
1710-
* So we need to take care and save everything into transaction,
1711-
* otherwise we will loose the rpl lumps. --bogdan */
1712-
r = t_newtran( msg, 1/*full uas cloning*/ );
1713-
if (r==0) {
1714-
/* retransmission -> break the script */
1715-
return 0;
1716-
} else if (r<0) {
1717-
LM_ERR("could not create a new transaction\n");
1718-
return -1;
1719-
}
1720-
t=get_t();
1721-
} else {
1722-
update_cloned_msg_from_msg( t->uas.request, msg);
1723-
}
1724-
return t_reply_with_body(t, *code, text, body, 0, 0);
1725-
}
1726-
1727-
1728-
int t_reply_with_body( struct cell *trans, unsigned int code, str *text,
1729-
str *body, str *new_header, str *to_tag )
1699+
static int _reply_with_body( struct cell *trans, unsigned int code, str *text,
1700+
str *body, str *new_header, str *to_tag, int lock_replies)
17301701
{
17311702
struct lump_rpl *hdr_lump;
17321703
struct lump_rpl *body_lump;
@@ -1795,7 +1766,7 @@ int t_reply_with_body( struct cell *trans, unsigned int code, str *text,
17951766
goto error;
17961767
}
17971768
ret=_reply_light( trans, rpl.s, rpl.len, code, to_tag_rpl.s, to_tag_rpl.len,
1798-
1 /* lock replies */, &bm );
1769+
lock_replies, &bm );
17991770

18001771
/* mark the transaction as replied */
18011772
if (code>=200) set_kr(REQ_RPLD);
@@ -1810,3 +1781,59 @@ int t_reply_with_body( struct cell *trans, unsigned int code, str *text,
18101781
return -1;
18111782
}
18121783

1784+
1785+
int w_t_reply_body(struct sip_msg* msg, unsigned int* code, str *text,
1786+
str *body)
1787+
{
1788+
struct cell *t;
1789+
int r, lock_replies = 1;
1790+
1791+
if (msg->REQ_METHOD==METHOD_ACK) {
1792+
LM_DBG("ACKs are not replied\n");
1793+
return 0;
1794+
}
1795+
1796+
switch (route_type) {
1797+
case FAILURE_ROUTE:
1798+
t=get_t();
1799+
if ( t==0 || t==T_UNDEFINED ) {
1800+
LM_BUG("no transaction found in Failure Route\n");
1801+
return -1;
1802+
}
1803+
lock_replies = 0;
1804+
break;
1805+
case REQUEST_ROUTE:
1806+
t=get_t();
1807+
if ( t==0 || t==T_UNDEFINED ) {
1808+
/* t_reply_with_body() is a bit of a weird function as it is
1809+
* receiving as parameter the actual msg, but the transaction
1810+
* (and uses the saved msg from transaction).
1811+
* So we need to take care and save everything into transaction,
1812+
* otherwise we will loose the rpl lumps. --bogdan */
1813+
r = t_newtran( msg, 1/*full uas cloning*/ );
1814+
if (r==0) {
1815+
/* retransmission -> break the script */
1816+
return 0;
1817+
} else if (r<0) {
1818+
LM_ERR("could not create a new transaction\n");
1819+
return -1;
1820+
}
1821+
t=get_t();
1822+
} else {
1823+
update_cloned_msg_from_msg( t->uas.request, msg);
1824+
}
1825+
break;
1826+
default:
1827+
LM_CRIT("unsupported route_type (%d)\n", route_type);
1828+
return -1;
1829+
}
1830+
return _reply_with_body(t, *code, text, body, 0, 0, lock_replies);
1831+
}
1832+
1833+
1834+
int t_reply_with_body( struct cell *trans, unsigned int code, str *text,
1835+
str *body, str *new_header, str *to_tag)
1836+
{
1837+
return _reply_with_body(trans, code, text, body, new_header,
1838+
to_tag, 1 /* lock replies */);
1839+
}

modules/tm/tm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static cmd_export_t cmds[]={
240240
{CMD_PARAM_INT, fixup_reply_code, 0},
241241
{CMD_PARAM_STR, 0, 0},
242242
{CMD_PARAM_STR, 0, 0}, {0,0,0}},
243-
REQUEST_ROUTE},
243+
REQUEST_ROUTE|FAILURE_ROUTE},
244244
{"t_new_request", (cmd_function)w_t_new_request, {
245245
{CMD_PARAM_STR, 0, 0},
246246
{CMD_PARAM_STR, 0, 0},

0 commit comments

Comments
 (0)