Module: sip-router Branch: andrei/cancel_reason Commit: 984eec800fcab256ce46ee03729374aee7c44617 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=984eec80...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Wed Mar 3 14:57:43 2010 +0100
tm: CANCEL reason header on/off switches
Config support (both runtime and modparam) for turning on/off Reason header support in locally generated or end-to-end hop-by-hop CANCELs: - local_cancel_reason = 0|1. Default 1 (on). - e2e_cancel_reason= 0|1. (Default 1 (on).
End-to-end CANCEL reason header copy can also be turned on/off on a per transaction basis: t_set_no_e2e_cancel_reason(0|1). E.g.: t_set_no_e2e_cancel_reason(1); # disable reason copy t_relay();
t_set_no_e2e_cancel_reason(0) can be used to enable reason header on a per transaction basis, if the default is disabled (e2e_cancel_reason is set to 0).
---
modules/tm/config.c | 19 ++++++++++++++----- modules/tm/config.h | 9 +++++---- modules/tm/h_table.h | 8 ++++---- modules/tm/t_lookup.c | 2 ++ modules/tm/t_msgbuilder.c | 22 ++++++++++++++-------- modules/tm/tm.c | 27 +++++++++++++++++++++------ 6 files changed, 60 insertions(+), 27 deletions(-)
diff --git a/modules/tm/config.c b/modules/tm/config.c index b715d03..8a4e456 100644 --- a/modules/tm/config.c +++ b/modules/tm/config.c @@ -24,10 +24,9 @@ * 2008-02-05 adapting tm module for the configuration framework (Miklos) */
-/*! - * \file - * \brief TM :: Configuration - * \ingroup tm +/** TM :: Runtime configuration variables. + * @file + * @ingroup tm */
@@ -94,7 +93,11 @@ struct cfg_group_tm default_tm_cfg = { 1, /* cancel_b_method used for e2e and 6xx cancels*/ 1, /* reparse_on_dns_failover */ 0, /* disable_6xx, by default off */ - 0 /* local_ack_mode, default 0 (rfc3261 conformant) */ + 0, /* local_ack_mode, default 0 (rfc3261 conformant) */ + 1, /* local_cancel_reason -- add Reason header to locally generated + CANCELs; on by default */ + 1 /* e2e_cancel_reason -- copy the Reason headers from incoming CANCELs + into the corresp. hop-by-hop CANCELs, on by default */ };
void *tm_cfg = &default_tm_cfg; @@ -196,5 +199,11 @@ cfg_def_t tm_cfg_def[] = { " it is not set to 0 but allows dealing with NATed contacts in some " "simple cases)" }, + {"local_cancel_reason", CFG_VAR_INT | CFG_ATOMIC, 0, 1, 0, 0, + "if set to 1, a Reason header is added to locally generated CANCELs" + " (see RFC3326)" }, + {"e2e_cancel_reason", CFG_VAR_INT | CFG_ATOMIC, 0, 1, 0, 0, + "if set to 1, Reason headers from received CANCELs are copied into" + " the corresponding generated hop-by-hop CANCELs"}, {0, 0, 0, 0, 0, 0} }; diff --git a/modules/tm/config.h b/modules/tm/config.h index ed65acf..b740ec4 100644 --- a/modules/tm/config.h +++ b/modules/tm/config.h @@ -21,10 +21,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/*! - * \file - * \brief TM :: Configuration - * \ingroup tm +/** TM :: Runtime configuration variables. + * @file + * @ingroup tm */
@@ -136,6 +135,8 @@ struct cfg_group_tm { int reparse_on_dns_failover; int disable_6xx; int local_ack_mode; + int local_cancel_reason; + int e2e_cancel_reason; };
extern struct cfg_group_tm default_tm_cfg; diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h index 1c1cd2d..ad7c3d7 100644 --- a/modules/tm/h_table.h +++ b/modules/tm/h_table.h @@ -40,10 +40,9 @@ * inlined often used functions (andrei) */
-/*! - * \file - * \brief TM :: - * \ingroup tm +/** TM :: hash table, flags and other general defines. + * @file + * @ingroup tm */
@@ -281,6 +280,7 @@ struct totag_elem {
#define T_DISABLE_6xx (1<<8) /* treat 6xx as a normal reply */ #define T_DISABLE_FAILOVER (1<<9) /* don't perform dns failover */ +#define T_NO_E2E_CANCEL_REASON (1<<10) /* don't propagate CANCEL Reason */ #define T_DONT_FORK (T_CANCELED|T_6xx)
/* unsigned short should be enough for a retr. timer: max. 65535 ticks => diff --git a/modules/tm/t_lookup.c b/modules/tm/t_lookup.c index 58e6fbc..01f6a82 100644 --- a/modules/tm/t_lookup.c +++ b/modules/tm/t_lookup.c @@ -1265,6 +1265,8 @@ static inline void init_new_t(struct cell *new_cell, struct sip_msg *p_msg) (!cfg_get(tm, tm_cfg, tm_auto_inv_100) -1); new_cell->flags|=T_DISABLE_6xx & (!cfg_get(tm, tm_cfg, disable_6xx) -1); + new_cell->flags|=T_NO_E2E_CANCEL_REASON & + (!!cfg_get(tm, tm_cfg, e2e_cancel_reason) -1); /* reset flags */ new_cell->flags &= (~ get_msgid_val(user_cell_reset_flags, p_msg->id, int)); diff --git a/modules/tm/t_msgbuilder.c b/modules/tm/t_msgbuilder.c index 4ccf3d2..a05fdbc 100644 --- a/modules/tm/t_msgbuilder.c +++ b/modules/tm/t_msgbuilder.c @@ -171,16 +171,18 @@ char *build_local(struct cell *Trans,unsigned int branch, *len+=CONTENT_LENGTH_LEN+1 + CRLF_LEN; reason_len = 0; reas1 = 0; - /* compute reason size */ + /* compute reason size (if no reason or disabled => reason_len == 0)*/ if (reason && reason->cause != CANCEL_REAS_UNKNOWN){ - if (likely(reason->cause > 0)){ + if (likely(reason->cause > 0 && + cfg_get(tm, tm_cfg, local_cancel_reason))){ /* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */ reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN + (reason->u.text.s? REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) + CRLF_LEN; } else if (reason->cause == CANCEL_REAS_RCVD_CANCEL && - reason->u.e2e_cancel) { + reason->u.e2e_cancel && + !(Trans->flags & T_NO_E2E_CANCEL_REASON)) { /* parse the entire cancel, to get all the Reason headers */ parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0); for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr; @@ -189,7 +191,7 @@ char *build_local(struct cell *Trans,unsigned int branch, reason_len += hdr->len; reas_last=hdr; } - } else if (unlikely(reason->cause != -1)) + } else if (unlikely(reason->cause < -1)) BUG("unhandled reason cause %d\n", reason->cause); } *len+= reason_len; @@ -305,16 +307,18 @@ char *build_local_reparse(struct cell *Trans,unsigned int branch, reason_len = 0; reas1 = 0; - /* compute reason size */ + /* compute reason size (if no reason or disabled => reason_len == 0)*/ if (reason && reason->cause != CANCEL_REAS_UNKNOWN){ - if (likely(reason->cause > 0)){ + if (likely(reason->cause > 0 && + cfg_get(tm, tm_cfg, local_cancel_reason))){ /* Reason: SIP;cause=<reason->cause>[;text=<reason->u.text.s>] */ reason_len = REASON_PREFIX_LEN + USHORT2SBUF_MAX_LEN + (reason->u.text.s? REASON_TEXT_LEN + 1 + reason->u.text.len + 1 : 0) + CRLF_LEN; } else if (reason->cause == CANCEL_REAS_RCVD_CANCEL && - reason->u.e2e_cancel) { + reason->u.e2e_cancel && + !(Trans->flags & T_NO_E2E_CANCEL_REASON)) { /* parse the entire cancel, to get all the Reason headers */ parse_headers(reason->u.e2e_cancel, HDR_EOH_F, 0); for(hdr=get_hdr(reason->u.e2e_cancel, HDR_REASON_T), reas1=hdr; @@ -323,7 +327,7 @@ char *build_local_reparse(struct cell *Trans,unsigned int branch, reason_len += hdr->len; reas_last=hdr; } - } else if (unlikely(reason->cause != -1)) + } else if (unlikely(reason->cause < -1)) BUG("unhandled reason cause %d\n", reason->cause); }
@@ -431,6 +435,8 @@ char *build_local_reparse(struct cell *Trans,unsigned int branch, /* end of SIP message found */ /* add reason if needed */ if (reason_len) { + /* if reason_len !=0, no need for any reason enabled + checks */ if (likely(reason->cause > 0)) { append_str(d, REASON_PREFIX, REASON_PREFIX_LEN); code_len=ushort2sbuf(reason->cause, d, diff --git a/modules/tm/tm.c b/modules/tm/tm.c index 2b35681..221be3b 100644 --- a/modules/tm/tm.c +++ b/modules/tm/tm.c @@ -87,16 +87,17 @@ * 2008-08-11 sctp support: t_relay_to_sctp, t_replicate_sctp, * t_forward_nonack_sctp (andrei) * 2009-03-18 added a new param: auto_inv_100_reason (aheise) + * 2010-03-03 added new params: local_cancel_reason and e2e_cancel_reason + * (andrei) */
-/*! - * \file - * \brief TM :: Module API (core) - * \ingroup tm +/** TM :: Module API (core). + * @file + * @ingroup tm */
-/*! - * \defgroup tm TM :: Transaction stateful proxy support +/** + * @defgroup tm TM :: Transaction stateful proxy support * The TM module enables stateful processing of SIP transactions. The main use of stateful logic, which is costly in terms of memory and CPU, is some @@ -283,6 +284,8 @@ static int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar); static int t_set_auto_inv_100(struct sip_msg* msg, char* on_off, char* foo); static int t_set_disable_6xx(struct sip_msg* msg, char* on_off, char* foo); static int t_set_disable_failover(struct sip_msg* msg, char* on_off, char* f); +static int t_set_no_e2e_cancel_reason(struct sip_msg* msg, char* on_off, + char* f); static int t_branch_timeout(struct sip_msg* msg, char*, char*); static int t_branch_replied(struct sip_msg* msg, char*, char*); static int t_any_timeout(struct sip_msg* msg, char*, char*); @@ -428,6 +431,13 @@ static cmd_export_t cmds[]={ REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_set_disable_failover", t_set_disable_failover, 1, fixup_var_int_1, REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + {"t_set_no_e2e_cancel_reason", t_set_no_e2e_cancel_reason, 1, + fixup_var_int_1, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, + /* alias for t_set_no_e2e_cancel_reason */ + {"t_disable_e2e_cancel_reason", t_set_no_e2e_cancel_reason, 1, + fixup_var_int_1, + REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE }, {"t_branch_timeout", t_branch_timeout, 0, 0, FAILURE_ROUTE}, {"t_branch_replied", t_branch_replied, 0, 0, FAILURE_ROUTE}, {"t_any_timeout", t_any_timeout, 0, 0, @@ -535,6 +545,8 @@ static param_export_t params[]={ {"contacts_avp", PARAM_STRING, &contacts_avp_param }, {"disable_6xx_block", PARAM_INT, &default_tm_cfg.disable_6xx }, {"local_ack_mode", PARAM_INT, &default_tm_cfg.local_ack_mode }, + {"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason }, + {"e2e_cancel_reason", PARAM_INT, &default_tm_cfg.e2e_cancel_reason }, {0,0,0} };
@@ -1736,6 +1748,9 @@ T_SET_FLAG_GEN_FUNC(t_set_disable_6xx, T_DISABLE_6xx) T_SET_FLAG_GEN_FUNC(t_set_disable_failover, T_DISABLE_FAILOVER)
+/* disable/enable e2e cancel reason copy for the current transaction */ +T_SET_FLAG_GEN_FUNC(t_set_no_e2e_cancel_reason, T_NO_E2E_CANCEL_REASON) +
/* script function, FAILURE_ROUTE only, returns true if the * choosed "failure" branch failed because of a timeout,