瀏覽代碼

modules/tm: add faked_reply_prio parameter to be able to punish faked replies

Thi should fix FS#54.
Alex Hermann 14 年之前
父節點
當前提交
6b2d6a3f8b
共有 5 個文件被更改,包括 142 次插入52 次删除
  1. 68 44
      modules/tm/README
  2. 40 0
      modules/tm/doc/params.xml
  3. 29 8
      modules/tm/t_reply.c
  4. 4 0
      modules/tm/t_reply.h
  5. 1 0
      modules/tm/tm.c

+ 68 - 44
modules/tm/README

@@ -55,8 +55,9 @@ Juha Heinanen
         1.4.35. disable_6xx_block (integer)
         1.4.36. local_ack_mode (integer)
         1.4.37. failure_reply_mode (integer)
-        1.4.38. local_cancel_reason (boolean)
-        1.4.39. e2e_cancel_reason (boolean)
+        1.4.38. faked_reply_prio (integer)
+        1.4.39. local_cancel_reason (boolean)
+        1.4.40. e2e_cancel_reason (boolean)
 
    1.5. Functions
 
@@ -1129,7 +1130,30 @@ modparam("tm", "local_ack_mode", 1)
 modparam("tm", "failure_reply_mode", 3)
 ...
 
-1.4.38. local_cancel_reason (boolean)
+1.4.38. faked_reply_prio (integer)
+
+   It controls how branch selection is done. It allows to give a penalty
+   to faked replies such as the infamous 408 on branch timeout.
+
+   Internally, every reply is assigned a priority between 0 (high prio)
+   and 32000 (low prio). With this parameter the priority of fake replies
+   can be adjusted.
+     * 0 - disabled (default)
+     * < 0 - priority is increased by given amount.
+     * > 0 - priority is decreased by given amount. Do not make it higer
+       than 10000 or faked replies will even loose from 1xx clsss replies.
+
+   The default value is 0.
+
+   To let received replies win from a locally generated 408, set this
+   value to 2000.
+
+   Example 38. Set faked_reply_prio parameter
+...
+modparam("tm", "faked_reply_prio", 2000)
+...
+
+1.4.39. local_cancel_reason (boolean)
 
    Enables/disables adding reason headers (RFC 3326) for CANCELs generated
    due to receiving a final reply. The reason header added will look like:
@@ -1142,12 +1166,12 @@ modparam("tm", "failure_reply_mode", 3)
 
    See also: e2e_cancel_reason.
 
-   Example 38. Set local_cancel_reason parameter
+   Example 39. Set local_cancel_reason parameter
 ...
 modparam("tm", "local_cancel_reason", 0)
 ...
 
-1.4.39. e2e_cancel_reason (boolean)
+1.4.40. e2e_cancel_reason (boolean)
 
    Enables/disables adding reason headers (RFC 3326) for CANCELs generated
    due to a received CANCEL. If enabled the reason headers from received
@@ -1160,7 +1184,7 @@ modparam("tm", "local_cancel_reason", 0)
 
    See also: t_set_no_e2e_cancel_reason() and local_cancel_reason.
 
-   Example 39. Set e2e_cancel_reason parameter
+   Example 40. Set e2e_cancel_reason parameter
 ...
 modparam("tm", "e2e_cancel_reason", 0)
 ...
@@ -1187,7 +1211,7 @@ t_relay_to_sctp(ip, port) t_relay_to_sctp()
    derived from the message uri (using sip sepcific DNS lookups), but with
    the protocol corresponding to the function name.
 
-   Example 40. t_relay_to_udp usage
+   Example 41. t_relay_to_udp usage
 ...
 if (src_ip==10.0.0.0/8)
         t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp
@@ -1214,7 +1238,7 @@ else
    Returns a negative value on failure--you may still want to send a
    negative reply upstream statelessly not to leave upstream UAC in lurch.
 
-   Example 41. t_relay usage
+   Example 42. t_relay usage
 ...
 if (!t_relay())
 {
@@ -1243,7 +1267,7 @@ if (!t_relay())
    Meaning of the parameters is as follows:
      * failure_route - Failure route block to be called.
 
-   Example 42. t_on_failure usage
+   Example 43. t_on_failure usage
 ...
 route {
     t_on_failure("1");
@@ -1269,7 +1293,7 @@ failure_route[1] {
    Meaning of the parameters is as follows:
      * onreply_route - Onreply route block to be called.
 
-   Example 43. t_on_reply usage
+   Example 44. t_on_reply usage
 ...
 loadmodule "/usr/local/lib/ser/modules/nathelper.so"
 ...
@@ -1301,7 +1325,7 @@ es');
    Meaning of the parameters is as follows:
      * branch_route - branch route block to be called.
 
-   Example 44. t_on_branch usage
+   Example 45. t_on_branch usage
 ...
 route {
         t_on_branch("1");
@@ -1319,7 +1343,7 @@ branch_route[1] {
    Similarly to t_fork_to, it extends destination set by a new entry. The
    difference is that current URI is taken as new entry.
 
-   Example 45. append_branch usage
+   Example 46. append_branch usage
 ...
 set_user("john");
 t_fork();
@@ -1334,7 +1358,7 @@ t_relay();
    the only way a script can add a new transaction in an atomic way.
    Typically, it is used to deploy a UAS.
 
-   Example 46. t_newtran usage
+   Example 47. t_newtran usage
 ...
 if (t_newtran()) {
     log("UAS logic");
@@ -1353,7 +1377,7 @@ if (t_newtran()) {
      * code - Reply code number.
      * reason_phrase - Reason string.
 
-   Example 47. t_reply usage
+   Example 48. t_reply usage
 ...
 t_reply("404", "Not found");
 ...
@@ -1366,7 +1390,7 @@ t_reply("404", "Not found");
    none was found. However this is safely (atomically) done using
    t_newtran.
 
-   Example 48. t_lookup_request usage
+   Example 49. t_lookup_request usage
 ...
 if (t_lookup_request()) {
     ...
@@ -1377,7 +1401,7 @@ if (t_lookup_request()) {
 
    Retransmits a reply sent previously by UAS transaction.
 
-   Example 49. t_retransmit_reply usage
+   Example 50. t_retransmit_reply usage
 ...
 t_retransmit_reply();
 ...
@@ -1387,7 +1411,7 @@ t_retransmit_reply();
    Remove transaction from memory (it will be first put on a wait timer to
    absorb delayed messages).
 
-   Example 50. t_release usage
+   Example 51. t_release usage
 ...
 t_release();
 ...
@@ -1402,7 +1426,7 @@ t_forward_nonack_tls(ip, port) t_forward_nonack_sctp(ip, port)
      * ip - IP address where the message should be sent.
      * port - Port number.
 
-   Example 51. t_forward_nonack usage
+   Example 52. t_forward_nonack usage
 ...
 t_forward_nonack("1.2.3.4", "5060");
 ...
@@ -1425,7 +1449,7 @@ t_forward_nonack("1.2.3.4", "5060");
 
    See also: fr_timer, fr_inv_timer, t_reset_fr().
 
-   Example 52. t_set_fr usage
+   Example 53. t_set_fr usage
 ...
 route {
         t_set_fr(10000); # set only fr invite timeout to 10s
@@ -1452,7 +1476,7 @@ branch_route[1] {
 
    See also: fr_timer, fr_inv_timer, t_set_fr.
 
-   Example 53. t_reset_fr usage
+   Example 54. t_reset_fr usage
 ...
 route {
 ...
@@ -1478,7 +1502,7 @@ route {
 
    See also: max_inv_lifetime, max_noninv_lifetime, t_reset_max_lifetime.
 
-   Example 54. t_set_max_lifetime usage
+   Example 55. t_set_max_lifetime usage
 ...
 route {
     if (src_ip=1.2.3.4)
@@ -1500,7 +1524,7 @@ route {
 
    See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime.
 
-   Example 55. t_reset_max_lifetime usage
+   Example 56. t_reset_max_lifetime usage
 ...
 route {
 ...
@@ -1538,7 +1562,7 @@ route {
 
    See also: retr_timer1, retr_timer2, t_reset_retr().
 
-   Example 56. t_set_retr usage
+   Example 57. t_set_retr usage
 ...
 route {
         t_set_retr(250, 0); # set only T1 to 250 ms
@@ -1565,7 +1589,7 @@ branch_route[1] {
 
    See also: retr_timer1, retr_timer2, t_set_retr.
 
-   Example 57. t_reset_retr usage
+   Example 58. t_reset_retr usage
 ...
 route {
 ...
@@ -1581,7 +1605,7 @@ route {
 
    See also: auto_inv_100.
 
-   Example 58. t_set_auto_inv_100 usage
+   Example 59. t_set_auto_inv_100 usage
 ...
 route {
 ...
@@ -1595,7 +1619,7 @@ route {
    Returns true if the failure route is executed for a branch that did
    timeout. It can be used only from the failure_route.
 
-   Example 59. t_branch_timeout usage
+   Example 60. t_branch_timeout usage
 ...
 failure_route[0]{
         if (t_branch_timeout()){
@@ -1610,7 +1634,7 @@ failure_route[0]{
    receive at least one reply in the past (the "current" reply is not
    taken into account). It can be used only from the failure_route.
 
-   Example 60. t_branch_replied usage
+   Example 61. t_branch_replied usage
 ...
 failure_route[0]{
         if (t_branch_timeout()){
@@ -1627,7 +1651,7 @@ failure_route[0]{
    Returns true if at least one of the current transactions branches did
    timeout.
 
-   Example 61. t_any_timeout usage
+   Example 62. t_any_timeout usage
 ...
 failure_route[0]{
         if (!t_branch_timeout()){
@@ -1644,7 +1668,7 @@ failure_route[0]{
    receive some reply in the past. If called from a failure or onreply
    route, the "current" reply is not taken into account.
 
-   Example 62. t_any_replied usage
+   Example 63. t_any_replied usage
 ...
 onreply_route[0]{
         if (!t_any_replied()){
@@ -1658,7 +1682,7 @@ onreply_route[0]{
    Returns true if "code" is the final reply received (or locally
    generated) in at least one of the current transactions branches.
 
-   Example 63. t_grep_status usage
+   Example 64. t_grep_status usage
 ...
 onreply_route[0]{
         if (t_grep_status("486")){
@@ -1671,7 +1695,7 @@ onreply_route[0]{
 
    Returns true if the current transaction was canceled.
 
-   Example 64. t_is_canceled usage
+   Example 65. t_is_canceled usage
 ...
 failure_route[0]{
         if (t_is_canceled()){
@@ -1685,7 +1709,7 @@ failure_route[0]{
    Returns true if the current transaction has already been expired, i.e.
    the max_inv_lifetime/max_noninv_lifetime interval has already elapsed.
 
-   Example 65. t_is_expired usage
+   Example 66. t_is_expired usage
 ...
 failure_route[0]{
         if (t_is_expired()){
@@ -1706,7 +1730,7 @@ failure_route[0]{
    CANCELs were successfully sent to the pending branches, true if the
    INVITE was not found, and false in case of any error.
 
-   Example 66. t_relay_cancel usage
+   Example 67. t_relay_cancel usage
 if (method == CANCEL) {
         if (!t_relay_cancel()) {  # implicit drop if relaying was successful,
                                   # nothing to do
@@ -1733,7 +1757,7 @@ if (method == CANCEL) {
    overwritten with the flags of the INVITE. isflagset() can be used to
    check the flags of the previously forwarded INVITE in this case.
 
-   Example 67. t_lookup_cancel usage
+   Example 68. t_lookup_cancel usage
 if (method == CANCEL) {
         if (t_lookup_cancel()) {
                 log("INVITE transaction exists");
@@ -1763,7 +1787,7 @@ if (method == CANCEL) {
    Dropping replies works only if a new branch is added to the
    transaction, or it is explicitly replied in the script!
 
-   Example 68. t_drop_replies() usage
+   Example 69. t_drop_replies() usage
 ...
 failure_route[0]{
         if (t_check_status("5[0-9][0-9]")){
@@ -1794,7 +1818,7 @@ failure_route[0]{
    The transaction must be created by t_newtran() before calling
    t_save_lumps().
 
-   Example 69. t_save_lumps() usage
+   Example 70. t_save_lumps() usage
 route {
         ...
         t_newtran();
@@ -1864,7 +1888,7 @@ failure_route[1] {
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 70. t_load_contacts usage
+   Example 71. t_load_contacts usage
 ...
 if (!t_load_contacts()) {
         sl_send_reply("500", "Server Internal Error - Cannot load contacts");
@@ -1905,7 +1929,7 @@ if (!t_load_contacts()) {
    anymore set. Based on that test, you can then use t_set_fr() function
    to set timers according to your needs.
 
-   Example 71. t_next_contacts usage
+   Example 72. t_next_contacts usage
 ...
 # First call after t_load_contacts() when transaction does not exist yet
 # and contacts should be available
@@ -1969,7 +1993,7 @@ Note
 
    See also: t_lookup_request(), t_lookup_cancel().
 
-   Example 72. t_check_trans usage
+   Example 73. t_check_trans usage
 if ( method == "CANCEL" && !t_check_trans())
         sl_reply("403", "cancel out of the blue forbidden");
 # note: in this example t_check_trans() can be replaced by t_lookup_cancel()
@@ -1984,7 +2008,7 @@ if ( method == "CANCEL" && !t_check_trans())
 
    See also: disable_6xx_block.
 
-   Example 73. t_set_disable_6xx usage
+   Example 74. t_set_disable_6xx usage
 ...
 route {
 ...
@@ -1999,7 +2023,7 @@ route {
 
    See also: use_dns_failover.
 
-   Example 74. t_set_disable_failover usage
+   Example 75. t_set_disable_failover usage
 ...
 route {
 ...
@@ -2030,7 +2054,7 @@ route {
      * hostport - address in "host:port" format. It can be given via an
        AVP.
 
-   Example 75. t_replicate usage
+   Example 76. t_replicate usage
 ...
 # sent to 1.2.3.4:5060 over tcp
 t_replicate("sip:1.2.3.4:5060;transport=tcp");
@@ -2065,7 +2089,7 @@ t_replicate_to_udp("1.2.3.4", "5060");
             effect anymore).
           + 0x04 - disable dns failover.
 
-   Example 76. t_replicate usage
+   Example 77. t_replicate usage
 ...
 # sent to 1.2.3.4:5060 over tcp
 t_relay_to("tcp:1.2.3.4:5060");
@@ -2088,7 +2112,7 @@ t_relay_to("0x01");
 
    See also: e2e_cancel_reason.
 
-   Example 77. t_set_no_e2e_cancel_reason usage
+   Example 78. t_set_no_e2e_cancel_reason usage
 ...
 route {
 ...

+ 40 - 0
modules/tm/doc/params.xml

@@ -1168,6 +1168,46 @@ modparam("tm", "failure_reply_mode", 3)
 	</example>
 	</section>
 
+	<section id="faked_reply_prio">
+	<title><varname>faked_reply_prio</varname> (integer)</title>
+	<para>
+		It controls how branch selection is done. It allows to give a penalty
+		to faked replies such as the infamous 408 on branch timeout.
+	</para>
+	<para>
+		Internally, every reply is assigned a priority between 0 (high prio) 
+		and 32000 (low prio). With this parameter the priority of fake replies
+		can be adjusted.
+	</para>
+	<itemizedlist>
+		<listitem><para>
+		<emphasis>0</emphasis> - disabled (default)
+		</para></listitem>
+		<listitem><para>
+		<emphasis>&lt; 0</emphasis> - priority is increased by given amount.
+		</para></listitem>
+		<listitem><para>
+		<emphasis>&gt; 0</emphasis> - priority is decreased by given amount.
+		Do not make it higer than 10000 or faked replies will even loose
+		from 1xx clsss replies.
+		</para></listitem>
+	</itemizedlist>
+	<para>
+		The default value is 0.
+	</para>
+	<para>
+		To let received replies win from a locally generated 408, set this
+		value to 2000.
+	</para>
+	<example>
+		<title>Set <varname>faked_reply_prio</varname> parameter</title>
+		<programlisting>
+...
+modparam("tm", "faked_reply_prio", 2000)
+...
+	    </programlisting>
+	</example>
+	</section>
 
 	<section id="local_cancel_reason">
 		<title><varname>local_cancel_reason</varname> (boolean)</title>

+ 29 - 8
modules/tm/t_reply.c

@@ -201,6 +201,14 @@ static unsigned short resp_class_prio[]={
 			1000   /* 6xx, highest priority */
 };
 
+/* How to prioritize faked replies 
+ * The value will be added to the default prio
+ * - 0 disabled
+ * - < 0 increase prio
+ * - > 0 decrease prio
+ */
+int faked_reply_prio = 0;
+
 
 int t_get_reply_totag(struct sip_msg *msg, str *totag)
 {
@@ -1007,18 +1015,26 @@ inline static short int get_4xx_prio(unsigned char xx)
  *  6xx                          1000+xx              (high)
  *  2xx                          0000+xx              (highest) 
  */
-inline static short int get_prio(unsigned int resp)
+inline static short int get_prio(unsigned int resp, struct sip_msg *rpl)
 {
 	int class;
 	int xx;
+	int prio;
 	
 	class=resp/100;
 
 	if (class<7){
 		xx=resp%100;
-		return resp_class_prio[class]+((class==4)?get_4xx_prio(xx):xx);
+		prio = resp_class_prio[class]+((class==4)?get_4xx_prio(xx):xx);
+	} else {
+		prio = 10000+resp; /* unknown response class => return very low prio */
+	}
+	if (rpl == FAKED_REPLY) {
+		/* Add faked_reply penalty */
+		return prio + faked_reply_prio;
+	} else {
+		return prio;
 	}
-	return 10000+resp; /* unknown response class => return very low prio */
 }
 
 
@@ -1031,12 +1047,15 @@ inline static short int get_prio(unsigned int resp)
 int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
 {
 	int best_b, best_s, b;
+	sip_msg_t *rpl;
 
 	best_b=-1; best_s=0;
 	for ( b=0; b<t->nr_of_outgoings ; b++ ) {
+		rpl = t->uac[b].reply;
+
 		/* "fake" for the currently processed branch */
 		if (b==inc_branch) {
-			if (get_prio(inc_code)<get_prio(best_s)) {
+			if (get_prio(inc_code, rpl)<get_prio(best_s, rpl)) {
 				best_b=b;
 				best_s=inc_code;
 			}
@@ -1051,8 +1070,8 @@ int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
 		if ( t->uac[b].last_received<200 )
 			return -2;
 		/* if reply is null => t_send_branch "faked" reply, skip over it */
-		if ( t->uac[b].reply && 
-				get_prio(t->uac[b].last_received)<get_prio(best_s) ) {
+		if ( rpl && 
+				get_prio(t->uac[b].last_received, rpl)<get_prio(best_s, rpl) ) {
 			best_b =b;
 			best_s = t->uac[b].last_received;
 		}
@@ -1075,6 +1094,7 @@ int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code)
 int t_pick_branch_blind(struct cell *t, int *res_code)
 {
 	int best_b, best_s, b;
+	sip_msg_t *rpl;
 
 	best_b=-1; best_s=0;
 	for ( b=0; b<t->nr_of_outgoings ; b++ ) {
@@ -1082,8 +1102,9 @@ int t_pick_branch_blind(struct cell *t, int *res_code)
 		if ( t->uac[b].last_received<200 )
 			return -2;
 		/* if reply is null => t_send_branch "faked" reply, skip over it */
-		if ( t->uac[b].reply && 
-				get_prio(t->uac[b].last_received)<get_prio(best_s) ) {
+		rpl = t->uac[b].reply;
+		if ( rpl && 
+				get_prio(t->uac[b].last_received, rpl)<get_prio(best_s, rpl) ) {
 			best_b = b;
 			best_s = t->uac[b].last_received;
 		}

+ 4 - 0
modules/tm/t_reply.h

@@ -65,6 +65,10 @@ extern int goto_on_sl_reply;
 
 extern int failure_reply_mode;
 
+extern int faked_reply_prio;
+
+extern int tm_rich_redirect;
+ 
 /* has this to-tag been never seen in previous 200/INVs? */
 int unmatched_totag(struct cell *t, struct sip_msg *ack);
 

+ 1 - 0
modules/tm/tm.c

@@ -517,6 +517,7 @@ static param_export_t params[]={
 	{"disable_6xx_block",   PARAM_INT, &default_tm_cfg.disable_6xx           },
 	{"local_ack_mode",      PARAM_INT, &default_tm_cfg.local_ack_mode        },
 	{"failure_reply_mode",  PARAM_INT, &failure_reply_mode                   },
+	{"faked_reply_prio",    PARAM_INT, &faked_reply_prio                     },
 #ifdef CANCEL_REASON_SUPPORT
 	{"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason   },
 	{"e2e_cancel_reason",   PARAM_INT, &default_tm_cfg.e2e_cancel_reason     },