Selaa lähdekoodia

modules/lcr: [from|to][any]_gw functions now check also transport protocol

Juha Heinanen 15 vuotta sitten
vanhempi
commit
34db55ba00
3 muutettua tiedostoa jossa 259 lisäystä ja 211 poistoa
  1. 52 42
      modules/lcr/README
  2. 45 31
      modules/lcr/doc/lcr_admin.xml
  3. 162 138
      modules/lcr/lcr_mod.c

+ 52 - 42
modules/lcr/README

@@ -70,10 +70,10 @@ Juha Heinanen
               4.1. load_gws(lcr_id[, uri_user[, caller_uri]])
               4.1. load_gws(lcr_id[, uri_user[, caller_uri]])
               4.2. next_gw()
               4.2. next_gw()
               4.3. defunct_gw(period)
               4.3. defunct_gw(period)
-              4.4. from_gw(lcr_id [, ip_addr])
-              4.5. from_any_gw([ip_addr])
-              4.6. to_gw(lcr_id [, ip_addr])
-              4.7. to_any_gw([ip_addr])
+              4.4. from_gw(lcr_id[, ip_addr, proto])
+              4.5. from_any_gw([ip_addr, proto])
+              4.6. to_gw(lcr_id[, ip_addr, proto])
+              4.7. to_any_gw([ip_addr, proto])
 
 
         5. Exported RPC Commands
         5. Exported RPC Commands
 
 
@@ -189,10 +189,10 @@ Chapter 1. Admin Guide
         4.1. load_gws(lcr_id[, uri_user[, caller_uri]])
         4.1. load_gws(lcr_id[, uri_user[, caller_uri]])
         4.2. next_gw()
         4.2. next_gw()
         4.3. defunct_gw(period)
         4.3. defunct_gw(period)
-        4.4. from_gw(lcr_id [, ip_addr])
-        4.5. from_any_gw([ip_addr])
-        4.6. to_gw(lcr_id [, ip_addr])
-        4.7. to_any_gw([ip_addr])
+        4.4. from_gw(lcr_id[, ip_addr, proto])
+        4.5. from_any_gw([ip_addr, proto])
+        4.6. to_gw(lcr_id[, ip_addr, proto])
+        4.7. to_any_gw([ip_addr, proto])
 
 
    5. Exported RPC Commands
    5. Exported RPC Commands
 
 
@@ -768,10 +768,10 @@ modparam("lcr", "fetch_rows", 3000)
    4.1. load_gws(lcr_id[, uri_user[, caller_uri]])
    4.1. load_gws(lcr_id[, uri_user[, caller_uri]])
    4.2. next_gw()
    4.2. next_gw()
    4.3. defunct_gw(period)
    4.3. defunct_gw(period)
-   4.4. from_gw(lcr_id [, ip_addr])
-   4.5. from_any_gw([ip_addr])
-   4.6. to_gw(lcr_id [, ip_addr])
-   4.7. to_any_gw([ip_addr])
+   4.4. from_gw(lcr_id[, ip_addr, proto])
+   4.5. from_any_gw([ip_addr, proto])
+   4.6. to_gw(lcr_id[, ip_addr, proto])
+   4.7. to_any_gw([ip_addr, proto])
 
 
 4.1.  load_gws(lcr_id[, uri_user[, caller_uri]])
 4.1.  load_gws(lcr_id[, uri_user[, caller_uri]])
 
 
@@ -852,17 +852,22 @@ if (!next_gw()) {
 
 
    Example 1.41. defunct_gw usage
    Example 1.41. defunct_gw usage
 ...
 ...
-defunct_gw("60");
+defunct_gw(60);
 ...
 ...
 
 
-4.4.  from_gw(lcr_id [, ip_addr])
+4.4.  from_gw(lcr_id[, ip_addr, proto])
 
 
-   Checks if request comes from IP address of a gateway in LCR instance
-   specified by lcr_id argument, which can be an integer constant or a
-   pseudo variable with integer value. Fails if LCR instance includes one
-   or more gateways without IP address. IP address to be checked is either
-   taken from source IP address of the request or (if present) from
-   ip_addr pseudo variable argument.
+   Checks if request comes from IP address and transport protocol
+   spesified for a gateway in LCR instance lcr_id. Fails if the LCR
+   instance includes one or more gateways without IP address. IP address
+   and transport protocol to be checked are either taken from source IP
+   address of the request or (if present) from ip_addr and proto
+   arguments.
+
+   lcr_id can be an integer constant or a pseudo variable holding an
+   integer value. ip_addr can be a string or a pseudo variable holding a
+   string value. proto can be an integer constant (0 = 1 = UDP, 2 = TCP, 3
+   = TLS, 4 = SCTP) or a pseudo variable holding such an integer value.
 
 
    If request comes from a gateway, gateway's tag and flags are stored as
    If request comes from a gateway, gateway's tag and flags are stored as
    a side effect to tag_avp and flags_avp, respectively, if the
    a side effect to tag_avp and flags_avp, respectively, if the
@@ -878,21 +883,23 @@ defunct_gw("60");
 
 
    Example 1.42. from_gw usage
    Example 1.42. from_gw usage
 ...
 ...
-if (from_gw("1", "$avp(s:real_source_addr)") {
+if (from_gw(1, $avp(s:real_source_addr), 2) {
         ...
         ...
 };
 };
 ...
 ...
 
 
-4.5.  from_any_gw([ip_addr])
+4.5.  from_any_gw([ip_addr, proto])
 
 
-   Checks if request comes from IP address and port of any gateway. Only
-   LCR instances, where all gateways have IP address, are included in the
-   test. IP address to be checked is either taken from source IP address
-   of the request or (if present) from ip_addr pseudo variable argument.
+   Checks if request comes from IP address and transport protocol
+   spesified for any gateway. Only LCR instances, where all gateways have
+   IP address, are included in the test. IP address and transport protocol
+   to be checked are either taken from source IP address and transport
+   protocol of the request or (if present) from ip_addr and proto
+   arguments. See from_gw() function for more info about the arguments.
 
 
-   If any gateway has the IP address, function returns LCR identifier of
-   the gateway. Returns -1 on error or if the request does not come from a
-   gateway.
+   If any gateway has the IP address and transport protocol, function
+   returns LCR identifier of the gateway. Returns -1 on error or if the
+   request does not come from a gateway.
 
 
    If request comes from a gateway, gateway's tag and flags are stored as
    If request comes from a gateway, gateway's tag and flags are stored as
    a side effect to tag_avp and flags_avp, respectively, if the
    a side effect to tag_avp and flags_avp, respectively, if the
@@ -906,16 +913,17 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
 
 
    Example 1.43. from_gw usage
    Example 1.43. from_gw usage
 ...
 ...
-$var(lcr_id) = from_any_gw();
+$var(lcr_id) = from_any_gw("192.168.1.1", 3);
 ...
 ...
 
 
-4.6.  to_gw(lcr_id [, ip_addr])
+4.6.  to_gw(lcr_id[, ip_addr, proto])
 
 
-   Checks if in-dialog request goes to IP address and port of a gateway in
-   LCR instance specified by lcr_id argument. Fails if LCR instance
-   includes one or more gateways without IP address. IP address to be
-   checked is either taken from Request-URI hostpart or (if present) from
-   ip_addr pseudo variable argument.
+   Checks if in-dialog request goes to IP address and transport protocol
+   spesified for a gateway in LCR instance lcr_id. Fails if LCR instance
+   includes one or more gateways without IP address. IP address and
+   transport protocol to be checked are either taken from Request-URI or
+   (if present) from ip_addr and proto arguments. See from_gw() for more
+   info regarding the arguments.
 
 
    Returns 1 on success and -1 on failure and error.
    Returns 1 on success and -1 on failure and error.
 
 
@@ -932,12 +940,14 @@ if (to_gw("1")) {
 };
 };
 ...
 ...
 
 
-4.7.  to_any_gw([ip_addr])
+4.7.  to_any_gw([ip_addr, proto])
 
 
-   Checks if in-dialog request goes to any gateway. Only LCR instances,
-   where all gateways have IP address, are included in the test. IP
-   address to be checked is either taken from Request-URI hostpart or (if
-   present) from ip_addr pseudo variable argument.
+   Checks if in-dialog request goes to IP address and transport protocol
+   of any gateway. Only LCR instances, where all gateways have IP address,
+   are included in the test. IP address and transport protocol to be
+   checked are either taken from Request-URI or (if present) from ip_addr
+   and proto arguments. See from_gw() for more info regarding the
+   arguments.
 
 
    Execution time of to_any_gw() function is M * O(log N), where M is
    Execution time of to_any_gw() function is M * O(log N), where M is
    number of LCR instances and N is average number of gateways in LCR
    number of LCR instances and N is average number of gateways in LCR
@@ -950,7 +960,7 @@ if (to_gw("1")) {
 
 
    Example 1.45. to_gw usage
    Example 1.45. to_gw usage
 ...
 ...
-if (to_any_gw()) {
+if (to_any_gw("192.55.66.2", 1)) {
         ...
         ...
         exit;
         exit;
 };
 };

+ 45 - 31
modules/lcr/doc/lcr_admin.xml

@@ -1092,7 +1092,7 @@ if (!next_gw()) {
 		<title><function>defunct_gw</function> usage</title>
 		<title><function>defunct_gw</function> usage</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-defunct_gw("60");
+defunct_gw(60);
 ...
 ...
 </programlisting>
 </programlisting>
 		</example>
 		</example>
@@ -1100,17 +1100,24 @@ defunct_gw("60");
 
 
 	<section>
 	<section>
 		<title>
 		<title>
-		<function moreinfo="none">from_gw(lcr_id [, ip_addr])</function>
+		<function moreinfo="none">from_gw(lcr_id[, ip_addr, proto])</function>
 		</title>
 		</title>
 		<para>
 		<para>
-		Checks if request comes from IP address of a
-		gateway in LCR instance specified by lcr_id argument,
-		which can be an integer constant or a pseudo variable
-		with integer value.  Fails if LCR instance includes
+		Checks if request comes from IP address and transport protocol
+		spesified for a gateway in LCR instance lcr_id.
+		Fails if the LCR instance includes 
 		one or more gateways without IP address.
 		one or more gateways without IP address.
-		IP address to be checked is either 
+		IP address and transport protocol to be checked are either
 		taken from source IP address of the request or
 		taken from source IP address of the request or
-		(if present) from ip_addr pseudo variable argument.
+		(if present) from ip_addr and proto arguments.
+		</para>
+		<para>
+		lcr_id can be an integer constant or a pseudo variable
+		holding an integer value.  ip_addr can be a string or a pseudo
+		variable holding a string value.  proto can be an integer
+		constant (0 = 1 = UDP, 2 = TCP,
+		3 = TLS, 4 = SCTP) or a pseudo variable holding such an
+		integer value.
 		</para>
 		</para>
 		<para>
 		<para>
 		If request comes from a gateway, gateway's tag and flags are
 		If request comes from a gateway, gateway's tag and flags are
@@ -1133,7 +1140,7 @@ defunct_gw("60");
 		<title><function>from_gw</function> usage</title>
 		<title><function>from_gw</function> usage</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-if (from_gw("1", "$avp(s:real_source_addr)") {
+if (from_gw(1, $avp(s:real_source_addr), 2) {
 	...
 	...
 };
 };
 ...
 ...
@@ -1143,18 +1150,22 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
 
 
 	<section>
 	<section>
 		<title>
 		<title>
-		<function moreinfo="none">from_any_gw([ip_addr])</function>
+		<function moreinfo="none">from_any_gw([ip_addr, proto])</function>
 		</title>
 		</title>
 		<para>
 		<para>
-		Checks if request comes from IP address and port of
-		any gateway.  Only LCR instances, where all gateways
+		Checks if request comes from IP address and transport 
+		protocol spesified for any gateway.  Only LCR instances,
+		where all gateways
 		have IP address, are included in the test.
 		have IP address, are included in the test.
-		IP address to be checked is either
-		taken from source IP address of the request or
-		(if present) from ip_addr pseudo variable argument.
+		IP address and transport protocol to be checked are either
+		taken from source IP address and transport protocol 
+		of the request or
+		(if present) from ip_addr and proto arguments.  See from_gw()
+		function for more info about the arguments.
 		</para>
 		</para>
 		<para>
 		<para>
-		If any gateway has the IP address, function returns LCR
+		If any gateway has the IP address and transport protocol,
+		function returns LCR
 		identifier of the gateway.  Returns -1 on error or if
 		identifier of the gateway.  Returns -1 on error or if
 		the request does not come from a gateway. 
 		the request does not come from a gateway. 
 		</para>
 		</para>
@@ -1177,7 +1188,7 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
 		<title><function>from_gw</function> usage</title>
 		<title><function>from_gw</function> usage</title>
 		<programlisting format="linespecific">
 		<programlisting format="linespecific">
 ...
 ...
-$var(lcr_id) = from_any_gw();
+$var(lcr_id) = from_any_gw("192.168.1.1", 3);
 ...
 ...
 </programlisting>
 </programlisting>
 		</example>
 		</example>
@@ -1185,16 +1196,17 @@ $var(lcr_id) = from_any_gw();
 
 
 		<section>
 		<section>
 		<title>
 		<title>
-		<function moreinfo="none">to_gw(lcr_id [, ip_addr])</function>
+		<function moreinfo="none">to_gw(lcr_id[, ip_addr, proto])</function>
 		</title>
 		</title>
 		<para>
 		<para>
-		Checks if in-dialog request goes to IP address and port
-		of a gateway in LCR
-		instance specified by lcr_id argument.  Fails if LCR
+		Checks if in-dialog request goes to IP address and transport
+		protocol spesified for a gateway in LCR instance lcr_id.
+		Fails if LCR
 		instance includes one or more gateways without IP
 		instance includes one or more gateways without IP
-		address.  IP address to be
-		checked is either taken from Request-URI hostpart or (if
-		present) from ip_addr pseudo variable argument. 
+		address.  IP address and transport protocol to be
+		checked are either taken from Request-URI or (if
+		present) from ip_addr and proto arguments.  See from_gw()
+		for more info regarding the arguments.
 		</para>
 		</para>
 		<para>
 		<para>
 		Returns 1 on success and -1 on failure and error.
 		Returns 1 on success and -1 on failure and error.
@@ -1221,15 +1233,17 @@ if (to_gw("1")) {
 
 
 	<section>
 	<section>
 		<title>
 		<title>
-		<function moreinfo="none">to_any_gw([ip_addr])</function>
+		<function moreinfo="none">to_any_gw([ip_addr, proto])</function>
 		</title>
 		</title>
 		<para>
 		<para>
-		Checks if in-dialog request goes to any gateway. Only
-		LCR instances, where all gateways 
+		Checks if in-dialog request goes to IP address and transport
+		protocol of any gateway.
+		Only LCR instances, where all gateways 
 		have IP address, are included in the test. IP
 		have IP address, are included in the test. IP
-		address to be checked is either taken from Request-URI
-		hostpart or (if present) from ip_addr pseudo variable
-		argument.
+		address and transport protocol to be checked are
+		either taken from Request-URI or (if present)
+		from ip_addr and proto arguments.   See from_gw()
+		for more info regarding the arguments.
 		</para>
 		</para>
 		<para>
 		<para>
 		Execution time of to_any_gw() function is M * O(log N),
 		Execution time of to_any_gw() function is M * O(log N),
@@ -1248,7 +1262,7 @@ if (to_gw("1")) {
 		<title><function>to_gw</function> usage</title>
 		<title><function>to_gw</function> usage</title>
 		<programlisting format = "linespecific">
 		<programlisting format = "linespecific">
 ...
 ...
-if (to_any_gw()) {
+if (to_any_gw("192.55.66.2", 1)) {
 	...
 	...
 	exit;
 	exit;
 };
 };

+ 162 - 138
modules/lcr/lcr_mod.c

@@ -245,13 +245,13 @@ static int load_gws(struct sip_msg* _m, int argc, action_u_t argv[]);
 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
 static int next_gw(struct sip_msg* _m, char* _s1, char* _s2);
 static int defunct_gw(struct sip_msg* _m, char* _s1, char* _s2);
 static int defunct_gw(struct sip_msg* _m, char* _s1, char* _s2);
 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
 static int from_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
-static int from_gw_2(struct sip_msg* _m, char* _s1, char* _s2);
+static int from_gw_3(struct sip_msg* _m, char* _s1, char* _s2, char* _s3);
 static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
 static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
-static int from_any_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
+static int from_any_gw_2(struct sip_msg* _m, char* _s1, char* _s2);
 static int to_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
 static int to_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
-static int to_gw_2(struct sip_msg* _m, char* _s1, char* _s2);
+static int to_gw_3(struct sip_msg* _m, char* _s1, char* _s2, char* _s3);
 static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
 static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2);
-static int to_any_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
+static int to_any_gw_2(struct sip_msg* _m, char* _s1, char* _s2);
 
 
 /*
 /*
  * Exported functions
  * Exported functions
@@ -259,26 +259,25 @@ static int to_any_gw_1(struct sip_msg* _m, char* _s1, char* _s2);
 static cmd_export_t cmds[] = {
 static cmd_export_t cmds[] = {
     {"load_gws", (cmd_function)load_gws, VAR_PARAM_NO, 0, 0,
     {"load_gws", (cmd_function)load_gws, VAR_PARAM_NO, 0, 0,
      REQUEST_ROUTE | FAILURE_ROUTE},
      REQUEST_ROUTE | FAILURE_ROUTE},
-    {"next_gw", (cmd_function)next_gw, 0, 0, 0,
+    {"next_gw", (cmd_function)next_gw, 0, 0, 0, REQUEST_ROUTE | FAILURE_ROUTE},
+    {"defunct_gw", (cmd_function)defunct_gw, 1, 0, 0,
      REQUEST_ROUTE | FAILURE_ROUTE},
      REQUEST_ROUTE | FAILURE_ROUTE},
-    {"defunct_gw", (cmd_function)defunct_gw, 1, fixup_igp_null, 0,
-     REQUEST_ROUTE | FAILURE_ROUTE},
-    {"from_gw", (cmd_function)from_gw_1, 1, fixup_igp_null, 0,
+    {"from_gw", (cmd_function)from_gw_1, 1, 0, 0,
+     REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
+    {"from_gw", (cmd_function)from_gw_3, 3, 0, 0,
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
-    {"from_gw", (cmd_function)from_gw_2, 2, fixup_igp_pvar,
-     fixup_free_igp_pvar, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
     {"from_any_gw", (cmd_function)from_any_gw_0, 0, 0, 0,
     {"from_any_gw", (cmd_function)from_any_gw_0, 0, 0, 0,
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
-    {"from_any_gw", (cmd_function)from_any_gw_1, 1, fixup_pvar_null,
-     fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
-    {"to_gw", (cmd_function)to_gw_1, 1, fixup_igp_null, 0,
+    {"from_any_gw", (cmd_function)from_any_gw_2, 2, 0, 0,
+     REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
+    {"to_gw", (cmd_function)to_gw_1, 1, 0, 0,
+     REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
+    {"to_gw", (cmd_function)to_gw_3, 3, 0, 0,
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
-    {"to_gw", (cmd_function)to_gw_2, 2, fixup_igp_pvar,
-     fixup_free_igp_pvar, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
     {"to_any_gw", (cmd_function)to_any_gw_0, 0, 0, 0,
     {"to_any_gw", (cmd_function)to_any_gw_0, 0, 0, 0,
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
      REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
-    {"to_any_gw", (cmd_function)to_any_gw_1, 1, fixup_pvar_null,
-     fixup_free_pvar_null, REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
+    {"to_any_gw", (cmd_function)to_any_gw_2, 2, 0, 0,
+     REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE},
     {0, 0, 0, 0, 0, 0}
     {0, 0, 0, 0, 0, 0}
 };
 };
 
 
@@ -346,7 +345,6 @@ struct module_exports exports = {
 	child_init /* child initialization function */
 	child_init /* child initialization function */
 };
 };
 
 
-
 static int lcr_db_init(const str* db_url)
 static int lcr_db_init(const str* db_url)
 {	
 {	
 	if (lcr_dbf.init==0){
 	if (lcr_dbf.init==0){
@@ -633,7 +631,7 @@ static int mod_init(void)
     memset(gw_pt, 0, sizeof(struct gw_info *) * (lcr_count_param + 1));
     memset(gw_pt, 0, sizeof(struct gw_info *) * (lcr_count_param + 1));
 
 
     /* gw tables themselves */
     /* gw tables themselves */
-    /* ordered by <ip_addr, port> for from_gw/to_gw functions */
+    /* ordered by ip_addr for from_gw/to_gw functions */
     /* in each table i, (gw_pt[i])[0].ip_addr contains number of
     /* in each table i, (gw_pt[i])[0].ip_addr contains number of
        gateways in the table and (gw_pt[i])[0].port as value 1
        gateways in the table and (gw_pt[i])[0].port as value 1
        if some gateways in the table have null ip addr */
        if some gateways in the table have null ip addr */
@@ -1621,10 +1619,13 @@ inline int decode_avp_value(char *value, unsigned int *gw_index, str *scheme,
     str2int(&s, &u);
     str2int(&s, &u);
     switch (u) {
     switch (u) {
     case PROTO_NONE:
     case PROTO_NONE:
-    case PROTO_UDP:
 	transport->s = (char *)0;
 	transport->s = (char *)0;
 	transport->len = 0;
 	transport->len = 0;
 	break;
 	break;
+    case PROTO_UDP:
+	transport->s = ";transport=udp";
+	transport->len = 14;
+	break;
     case PROTO_TCP:
     case PROTO_TCP:
 	transport->s = ";transport=tcp";
 	transport->s = ";transport=tcp";
 	transport->len = 14;
 	transport->len = 14;
@@ -1961,6 +1962,7 @@ static int defunct_gw(struct sip_msg* _m, char *_defunct_period, char *_s2)
 {
 {
     int_str lcr_id_val, index_val;
     int_str lcr_id_val, index_val;
     struct gw_info *gws;
     struct gw_info *gws;
+    char *tmp;
     unsigned int gw_index, defunct_until;
     unsigned int gw_index, defunct_until;
     int defunct_period;
     int defunct_period;
 
 
@@ -1972,12 +1974,15 @@ static int defunct_gw(struct sip_msg* _m, char *_defunct_period, char *_s2)
     }
     }
 
 
     /* Get parameter value */
     /* Get parameter value */
-    if (get_int_fparam(&defunct_period, _m, (fparam_t *)_defunct_period) != 0) {
-	LM_ERR("no defunct_period param value\n");
+
+    /* Get and check parameter value */
+    defunct_period = strtol(_defunct_period, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _defunct_period)) {
+	LM_ERR("invalid defunct_period parameter %s\n", _defunct_period);
 	return -1;
 	return -1;
     }
     }
     if (defunct_period < 1) {
     if (defunct_period < 1) {
-	LM_ERR("invalid defunct_period param value\n");
+	LM_ERR("invalid defunct_period param value %d\n", defunct_period);
 	return -1;
 	return -1;
     }
     }
 
 
@@ -2115,7 +2120,7 @@ static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
  * Checks if request comes from ip address of a gateway
  * Checks if request comes from ip address of a gateway
  */
  */
 static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id,
 static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id,
-		      unsigned int src_addr)
+		      unsigned int src_addr, uri_transport transport)
 {
 {
     struct gw_info *res, gw, *gws;
     struct gw_info *res, gw, *gws;
     int_str val;
     int_str val;
@@ -2133,11 +2138,10 @@ static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id,
     res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr,
     res = (struct gw_info *)bsearch(&gw, &(gws[1]), gws[0].ip_addr,
 				    sizeof(struct gw_info), comp_gws);
 				    sizeof(struct gw_info), comp_gws);
 
 
-    /* Store flags and return result */
-    if (res == NULL) {
-	LM_DBG("request did not come from gw\n");
-	return -1;
-    } else {
+    /* Store tag and flags and return result */
+    if ((res != NULL) &&
+	((res->transport == transport) ||
+	 ((res->transport == PROTO_NONE) && (transport == PROTO_UDP)))) {
 	LM_DBG("request game from gw\n");
 	LM_DBG("request game from gw\n");
 	if (tag_avp_param) {
 	if (tag_avp_param) {
 	    val.s.s = res->tag;
 	    val.s.s = res->tag;
@@ -2151,22 +2155,28 @@ static int do_from_gw(struct sip_msg* _m, unsigned int lcr_id,
 	    LM_DBG("added flags_avp <%u>\n", (unsigned int)val.n);
 	    LM_DBG("added flags_avp <%u>\n", (unsigned int)val.n);
 	}
 	}
 	return 1;
 	return 1;
+    } else {
+	LM_DBG("request did not come from gw\n");
+	return -1;
     }
     }
 }
 }
 
 
 
 
 /*
 /*
  * Checks if request comes from ip address of a gateway taking source
  * Checks if request comes from ip address of a gateway taking source
- * address from request.
+ * address and transport protocol from request.
  */
  */
 static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
 static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
 {
 {
     int lcr_id;
     int lcr_id;
+    char *tmp;
     unsigned int src_addr;
     unsigned int src_addr;
+    uri_transport transport;
 
 
     /* Get and check parameter value */
     /* Get and check parameter value */
-    if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
-	LM_ERR("no lcr_id param value\n");
+    lcr_id = strtol(_lcr_id, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _lcr_id)) {
+	LM_ERR("invalid lcr_id parameter %s\n", _lcr_id);
 	return -1;
 	return -1;
     }
     }
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
@@ -2174,57 +2184,59 @@ static int from_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
 	return -1;
 	return -1;
     }
     }
 
 
-    /* Get source address */
+    /* Get source address and transport preotocol */
     src_addr = _m->rcv.src_ip.u.addr32[0];
     src_addr = _m->rcv.src_ip.u.addr32[0];
+    transport = _m->rcv.proto;
 
 
     /* Do test */
     /* Do test */
-    return do_from_gw(_m, lcr_id, src_addr);
+    return do_from_gw(_m, lcr_id, src_addr, transport);
 }
 }
 
 
 
 
 /*
 /*
  * Checks if request comes from ip address of a gateway taking source
  * Checks if request comes from ip address of a gateway taking source
- * address from param.
+ * address and transport protocol from parameters
  */
  */
-static int from_gw_2(struct sip_msg* _m, char* _lcr_id, char* _addr)
+static int from_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr,
+		     char* _transport)
 {
 {
     unsigned int src_addr;
     unsigned int src_addr;
     int lcr_id;
     int lcr_id;
-    pv_value_t pv_val;
+    char *tmp;
     struct ip_addr *ip;
     struct ip_addr *ip;
+    str addr_str;
+    uri_transport transport;
 
 
     /* Get and check parameter values */
     /* Get and check parameter values */
-    if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
-	LM_ERR("no lcr_id param value\n");
+    lcr_id = strtol(_lcr_id, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _lcr_id)) {
+	LM_ERR("invalid lcr_id parameter %s\n", _lcr_id);
 	return -1;
 	return -1;
     }
     }
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
 	LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
 	LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
 	return -1;
 	return -1;
     }
     }
-
-    if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
-	if (pv_val.flags & PV_VAL_INT) {
-	    src_addr = pv_val.ri;
-	} else if (pv_val.flags & PV_VAL_STR) {
-	    if ((ip = str2ip(&pv_val.rs)) == NULL) {
-		LM_DBG("request did not come from gw "
-		       "(addr param value is not an IP address)\n");
-		return -1;
-	    } else {
-		src_addr = ip->u.addr32[0];
-	    }
-	} else {
-	    LM_ERR("addr param has no value\n");
-	    return -1;
-	}
+    addr_str.s = _addr;
+    addr_str.len = strlen(_addr);
+    if ((ip = str2ip(&addr_str)) == NULL) {
+	LM_ERR("addr param value %s is not an IP address\n", _addr);
+	return -1;
     } else {
     } else {
-	LM_ERR("could not get source address from param\n");
+	src_addr = ip->u.addr32[0];
+    }
+    transport = strtol(_transport, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _transport)) {
+	LM_ERR("invalid transport parameter %s\n", _lcr_id);
+	return -1;
+    }
+    if ((transport < PROTO_NONE) || (transport > PROTO_SCTP)) {
+	LM_ERR("invalid transport parameter value %d\n", transport);
 	return -1;
 	return -1;
     }
     }
 
 
     /* Do test */
     /* Do test */
-    return do_from_gw(_m, lcr_id, src_addr);
+    return do_from_gw(_m, lcr_id, src_addr, transport);
 }
 }
 
 
 
 
@@ -2235,11 +2247,13 @@ static int from_gw_2(struct sip_msg* _m, char* _lcr_id, char* _addr)
 static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
 static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
 {
 {
     unsigned int src_addr, i;
     unsigned int src_addr, i;
+    uri_transport transport;
 
 
     src_addr = _m->rcv.src_ip.u.addr32[0];
     src_addr = _m->rcv.src_ip.u.addr32[0];
+    transport = _m->rcv.proto;
 
 
     for (i = 1; i <= lcr_count_param; i++) {
     for (i = 1; i <= lcr_count_param; i++) {
-	if (do_from_gw(_m, i, src_addr) == 1) {
+	if (do_from_gw(_m, i, src_addr, transport) == 1) {
 	    return i;
 	    return i;
 	}
 	}
     }
     }
@@ -2249,38 +2263,38 @@ static int from_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
 
 
 /*
 /*
  * Checks if request comes from ip address of a a gateway taking source
  * Checks if request comes from ip address of a a gateway taking source
- * address from param.
+ * IP address and transport protocol from parameters.
  */
  */
-static int from_any_gw_1(struct sip_msg* _m, char* _addr, char* _s2)
+static int from_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport)
 {
 {
     unsigned int i, src_addr;
     unsigned int i, src_addr;
-    pv_value_t pv_val;
+    char *tmp;
     struct ip_addr *ip;
     struct ip_addr *ip;
+    str addr_str;
+    uri_transport transport;
 
 
-    /* Get parameter value */
-    if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
-	if (pv_val.flags & PV_VAL_INT) {
-	    src_addr = pv_val.ri;
-	} else if (pv_val.flags & PV_VAL_STR) {
-	    if ((ip = str2ip(&pv_val.rs)) == NULL) {
-		LM_DBG("request did not come from gw "
-		       "(addr param value is not an IP address)\n");
-		return -1;
-	    } else {
-		src_addr = ip->u.addr32[0];
-	    }
-	} else {
-	    LM_ERR("addr param has no value\n");
-	    return -1;
-	}
+    /* Get and check parameter values */
+    addr_str.s = _addr;
+    addr_str.len = strlen(_addr);
+    if ((ip = str2ip(&addr_str)) == NULL) {
+	LM_ERR("addr param value %s is not an IP address\n", _addr);
+	return -1;
     } else {
     } else {
-	LM_ERR("could not get source address from param\n");
+	src_addr = ip->u.addr32[0];
+    }
+    transport = strtol(_transport, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _transport)) {
+	LM_ERR("invalid transport parameter %s\n", _transport);
+	return -1;
+    }
+    if ((transport < PROTO_NONE) || (transport > PROTO_SCTP)) {
+	LM_ERR("invalid transport parameter value %d\n", transport);
 	return -1;
 	return -1;
     }
     }
 
 
     /* Do test */
     /* Do test */
     for (i = 1; i <= lcr_count_param; i++) {
     for (i = 1; i <= lcr_count_param; i++) {
-	if (do_from_gw(_m, i, src_addr) == 1) {
+	if (do_from_gw(_m, i, src_addr, transport) == 1) {
 	    return i;
 	    return i;
 	}
 	}
     }
     }
@@ -2292,7 +2306,7 @@ static int from_any_gw_1(struct sip_msg* _m, char* _addr, char* _s2)
  * Checks if in-dialog request goes to ip address of a gateway.
  * Checks if in-dialog request goes to ip address of a gateway.
  */
  */
 static int do_to_gw(struct sip_msg* _m, unsigned int lcr_id,
 static int do_to_gw(struct sip_msg* _m, unsigned int lcr_id,
-		    unsigned int dst_addr)
+		    unsigned int dst_addr, uri_transport transport)
 {
 {
     struct gw_info *res, gw, *gws;
     struct gw_info *res, gw, *gws;
 
 
@@ -2310,29 +2324,35 @@ static int do_to_gw(struct sip_msg* _m, unsigned int lcr_id,
 				    sizeof(struct gw_info), comp_gws);
 				    sizeof(struct gw_info), comp_gws);
 
 
     /* Return result */
     /* Return result */
-    if (res == NULL) {
-	LM_DBG("request is not going to gw\n");
-	return -1;
-    } else {
+    if ((res != NULL) &&
+	((res->transport == transport) ||
+	 ((res->transport == PROTO_NONE) && (transport == PROTO_UDP)))) {
 	LM_DBG("request goes to gw\n");
 	LM_DBG("request goes to gw\n");
 	return 1;
 	return 1;
+    } else {
+	LM_DBG("request is not going to gw\n");
+	return -1;
     }
     }
 }
 }
 
 
 
 
 /*
 /*
- * Checks if request goes to ip address of a gateway taking destination
- * address from Request URI.
+ * Checks if request goes to ip address and transport protocol of a gateway
+ * taking lcr_id from parameter and destination address and transport protocol
+ * from Request URI.
  */
  */
 static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
 static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
 {
 {
     int lcr_id;
     int lcr_id;
+    char *tmp;
     unsigned int dst_addr;
     unsigned int dst_addr;
     struct ip_addr *ip;
     struct ip_addr *ip;
+    uri_transport transport;
 
 
     /* Get and check parameter value */
     /* Get and check parameter value */
-    if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
-	LM_ERR("no lcr_id param value\n");
+    lcr_id = strtol(_lcr_id, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _lcr_id)) {
+	LM_ERR("invalid lcr_id parameter %s\n", _lcr_id);
 	return -1;
 	return -1;
     }
     }
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
@@ -2340,7 +2360,7 @@ static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
 	return -1;
 	return -1;
     }
     }
 
 
-    /* Get destination address */
+    /* Get destination address and transport protocol from R-URI */
     if ((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
     if ((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
 	LM_ERR("while parsing Request-URI\n");
 	LM_ERR("while parsing Request-URI\n");
 	return -1;
 	return -1;
@@ -2357,68 +2377,71 @@ static int to_gw_1(struct sip_msg* _m, char* _lcr_id, char* _s2)
     } else {
     } else {
 	dst_addr = ip->u.addr32[0];
 	dst_addr = ip->u.addr32[0];
     }
     }
+    transport = _m->parsed_uri.proto;
 
 
     /* Do test */
     /* Do test */
-    return do_to_gw(_m, lcr_id, dst_addr);
+    return do_to_gw(_m, lcr_id, dst_addr, transport);
 }
 }
 
 
 
 
 /*
 /*
- * Checks if request goes to ip address of a gateway taking destination
- * address from param.
+ * Checks if request goes to ip address of a gateway taking lcr_id,
+ * destination address and transport protocol from parameters.
  */
  */
-static int to_gw_2(struct sip_msg* _m, char* _lcr_id, char* _addr)
+static int to_gw_3(struct sip_msg* _m, char* _lcr_id, char* _addr,
+		   char* _transport)
 {
 {
     int lcr_id;
     int lcr_id;
+    char *tmp;
     unsigned int dst_addr;
     unsigned int dst_addr;
-    pv_value_t pv_val;
     struct ip_addr *ip;
     struct ip_addr *ip;
+    str addr_str;
+    uri_transport transport;
 
 
     /* Get and check parameter values */
     /* Get and check parameter values */
-    if (get_int_fparam(&lcr_id, _m, (fparam_t *)_lcr_id) != 0) {
-	LM_ERR("no lcr_id param value\n");
+    lcr_id = strtol(_lcr_id, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _lcr_id)) {
+	LM_ERR("invalid lcr_id parameter %s\n", _lcr_id);
 	return -1;
 	return -1;
     }
     }
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
     if ((lcr_id < 1) || (lcr_id > lcr_count_param)) {
 	LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
 	LM_ERR("invalid lcr_id parameter value %d\n", lcr_id);
 	return -1;
 	return -1;
     }
     }
-
-    if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
-	if (pv_val.flags & PV_VAL_INT) {
-	    dst_addr = pv_val.ri;
-	} else if (pv_val.flags & PV_VAL_STR) {
-	    if ((ip = str2ip(&pv_val.rs)) == NULL) {
-		LM_DBG("request is not going to gw "
-		       "(addr param value is not an IP address)\n");
-		return -1;
-	    } else {
-		dst_addr = ip->u.addr32[0];
-	    }
-	} else {
-	    LM_ERR("addr param has no value\n");
-	    return -1;
-	}
+    addr_str.s = _addr;
+    addr_str.len = strlen(_addr);
+    if ((ip = str2ip(&addr_str)) == NULL) {
+	LM_ERR("addr param value %s is not an IP address\n", _addr);
+	return -1;
     } else {
     } else {
-	LM_ERR("could not get destination address from param\n");
+	dst_addr = ip->u.addr32[0];
+    }
+    transport = strtol(_transport, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _transport)) {
+	LM_ERR("invalid transport parameter %s\n", _transport);
+	return -1;
+    }
+    if ((transport < PROTO_NONE) || (transport > PROTO_SCTP)) {
+	LM_ERR("invalid transport parameter value %d\n", transport);
 	return -1;
 	return -1;
     }
     }
     
     
     /* Do test */
     /* Do test */
-    return do_to_gw(_m, lcr_id, dst_addr);
+    return do_to_gw(_m, lcr_id, dst_addr, transport);
 }
 }
 
 
 
 
 /*
 /*
  * Checks if request goes to ip address of any gateway taking destination
  * Checks if request goes to ip address of any gateway taking destination
- * address from Request-URI.
+ * address and transport protocol from Request-URI.
  */
  */
 static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
 static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
 {
 {
     unsigned int dst_addr, i;
     unsigned int dst_addr, i;
     struct ip_addr *ip;
     struct ip_addr *ip;
+    uri_transport transport;
 
 
-    /* Get destination address */
+    /* Get destination address and transport protocol from R-URI */
     if ((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
     if ((_m->parsed_uri_ok == 0) && (parse_sip_msg_uri(_m) < 0)) {
 	LM_ERR("while parsing Request-URI\n");
 	LM_ERR("while parsing Request-URI\n");
 	return -1;
 	return -1;
@@ -2435,10 +2458,11 @@ static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
     } else {
     } else {
 	dst_addr = ip->u.addr32[0];
 	dst_addr = ip->u.addr32[0];
     }
     }
+    transport = _m->parsed_uri.proto;
 
 
     /* Do test */
     /* Do test */
     for (i = 1; i <= lcr_count_param; i++) {
     for (i = 1; i <= lcr_count_param; i++) {
-	if (do_to_gw(_m, i, dst_addr) == 1) {
+	if (do_to_gw(_m, i, dst_addr, transport) == 1) {
 	    return i;
 	    return i;
 	}
 	}
     }
     }
@@ -2448,38 +2472,38 @@ static int to_any_gw_0(struct sip_msg* _m, char* _s1, char* _s2)
 
 
 /*
 /*
  * Checks if request goes to ip address of any gateway taking destination
  * Checks if request goes to ip address of any gateway taking destination
- * address from param.
+ * address and transport protocol from parameters.
  */
  */
-static int to_any_gw_1(struct sip_msg* _m, char* _addr, char* _s2)
+static int to_any_gw_2(struct sip_msg* _m, char* _addr, char* _transport)
 {
 {
     unsigned int i, dst_addr;
     unsigned int i, dst_addr;
-    pv_value_t pv_val;
+    char *tmp;
     struct ip_addr *ip;
     struct ip_addr *ip;
+    uri_transport transport;
+    str addr_str;
 
 
-    /* Get parameter value */
-    if (_addr && (pv_get_spec_value(_m, (pv_spec_t *)_addr, &pv_val) == 0)) {
-	if (pv_val.flags & PV_VAL_INT) {
-	    dst_addr = pv_val.ri;
-	} else if (pv_val.flags & PV_VAL_STR) {
-	    if ((ip = str2ip(&pv_val.rs)) == NULL) {
-		LM_DBG("request did go to any gw "
-		       "(addr param value is not an IP address)\n");
-		return -1;
-	    } else {
-		dst_addr = ip->u.addr32[0];
-	    }
-	} else {
-	    LM_ERR("addr param has no value\n");
-	    return -1;
-	}
+    /* Get and check parameter values */
+    addr_str.s = _addr;
+    addr_str.len = strlen(_addr);
+    if ((ip = str2ip(&addr_str)) == NULL) {
+	LM_ERR("addr param value %s is not an IP address\n", _addr);
+	return -1;
     } else {
     } else {
-	LM_ERR("could not get destination address from param\n");
+	dst_addr = ip->u.addr32[0];
+    }
+    transport = strtol(_transport, &tmp, 10);
+    if ((tmp == 0) || (*tmp) || (tmp == _transport)) {
+	LM_ERR("invalid transport parameter %s\n", _transport);
+	return -1;
+    }
+    if ((transport < PROTO_NONE) || (transport > PROTO_SCTP)) {
+	LM_ERR("invalid transport parameter value %d\n", transport);
 	return -1;
 	return -1;
     }
     }
 
 
     /* Do test */
     /* Do test */
     for (i = 1; i <= lcr_count_param; i++) {
     for (i = 1; i <= lcr_count_param; i++) {
-	if (do_to_gw(_m, i, dst_addr) == 1) {
+	if (do_to_gw(_m, i, dst_addr, transport) == 1) {
 	    return i;
 	    return i;
 	}
 	}
     }
     }