Selaa lähdekoodia

modules/lcr: added URI parameters gateway attribute

Juha Heinanen 15 vuotta sitten
vanhempi
commit
f26fde383c
6 muutettua tiedostoa jossa 318 lisäystä ja 196 poistoa
  1. 9 1
      lib/srdb1/schema/gw.xml
  2. 178 159
      modules/lcr/README
  3. 52 18
      modules/lcr/doc/lcr_admin.xml
  4. 72 17
      modules/lcr/lcr_mod.c
  5. 3 0
      modules/lcr/lcr_mod.h
  6. 4 1
      modules/lcr/lcr_rpc.c

+ 9 - 1
lib/srdb1/schema/gw.xml

@@ -10,7 +10,7 @@
 
 <table id="gw" xmlns:db="http://docbook.org/ns/docbook">
     <name>gw</name>
-    <version>10</version>
+    <version>11</version>
     <type db="mysql">&MYSQL_TABLE_TYPE;</type>
     <description>
         <db:para>This table contains Least Cost Routing Gateway definitions for the LCR module.
@@ -69,6 +69,14 @@
         <description>Port of the gateway</description>
     </column>
 
+    <column id="params">
+        <name>params</name>
+        <type>string</type>
+        <size>64</size>
+        <null/>
+        <description>Gateway's URI parameters</description>
+    </column>
+
     <column id="uri_scheme">
         <name>uri_scheme</name>
         <type>unsigned char</type>

+ 178 - 159
modules/lcr/README

@@ -35,26 +35,27 @@ Juha Heinanen
               3.6. ip_addr_column (string)
               3.7. hostname_column (string)
               3.8. port_column (string)
-              3.9. uri_scheme_column (string)
-              3.10. transport_column (string)
-              3.11. strip_column (string)
-              3.12. tag_column (string)
-              3.13. weight_column (string)
-              3.14. flags_column (string)
-              3.15. defunct_column (string)
-              3.16. lcr_table (string)
-              3.17. prefix_column (string)
-              3.18. from_uri_column (string)
-              3.19. priority_column (string)
-              3.20. lcr_count (integer)
-              3.21. gw_uri_avp (AVP string)
-              3.22. ruri_user_avp (AVP string)
-              3.23. flags_avp (AVP string)
-              3.24. defunct_capability (integer)
-              3.25. lcr_id_avp (AVP string)
-              3.26. defunct_gw_avp (AVP string)
-              3.27. lcr_hash_size (integer)
-              3.28. fetch_rows (integer)
+              3.9. params_column (string)
+              3.10. uri_scheme_column (string)
+              3.11. transport_column (string)
+              3.12. strip_column (string)
+              3.13. tag_column (string)
+              3.14. weight_column (string)
+              3.15. flags_column (string)
+              3.16. defunct_column (string)
+              3.17. lcr_table (string)
+              3.18. prefix_column (string)
+              3.19. from_uri_column (string)
+              3.20. priority_column (string)
+              3.21. lcr_count (integer)
+              3.22. gw_uri_avp (AVP string)
+              3.23. ruri_user_avp (AVP string)
+              3.24. flags_avp (AVP string)
+              3.25. defunct_capability (integer)
+              3.26. lcr_id_avp (AVP string)
+              3.27. defunct_gw_avp (AVP string)
+              3.28. lcr_hash_size (integer)
+              3.29. fetch_rows (integer)
 
         4. Exported Functions
 
@@ -90,37 +91,38 @@ Juha Heinanen
    1.6. Setting ip_addr_column module parameter
    1.7. Setting hostname_column module parameter
    1.8. Setting port_column module parameter
-   1.9. Setting uri_scheme_column module parameter
-   1.10. Setting transport_column module parameter
-   1.11. Setting strip_column module parameter
-   1.12. Setting tag_column module parameter
-   1.13. Setting weight_column module parameter
-   1.14. Setting flags_column module parameter
-   1.15. Setting defunct_column module parameter
-   1.16. Setting lcr_table module parameter
-   1.17. Setting prefix_column module parameter
-   1.18. Setting from_uri_column module parameter
-   1.19. Setting priority_column module parameter
-   1.20. Setting lcr_count module parameter
-   1.21. Setting gw_uri_avp module parameter
-   1.22. Setting ruri_user_avp module parameter
-   1.23. Setting flags_avp module parameter
-   1.24. Setting defunct_capability module parameter
-   1.25. Setting lcr_id_avp module parameter
-   1.26. Setting defunct_gw_avp module parameter
-   1.27. Setting lcr_hash_size module parameter
-   1.28. Set fetch_rows parameter
-   1.29. load_gws usage
-   1.30. next_gw usage from a route block
-   1.31. next_gw usage from a failure route block
-   1.32. defunct_gw usage
-   1.33. from_gw usage
+   1.9. Setting params_column module parameter
+   1.10. Setting uri_scheme_column module parameter
+   1.11. Setting transport_column module parameter
+   1.12. Setting strip_column module parameter
+   1.13. Setting tag_column module parameter
+   1.14. Setting weight_column module parameter
+   1.15. Setting flags_column module parameter
+   1.16. Setting defunct_column module parameter
+   1.17. Setting lcr_table module parameter
+   1.18. Setting prefix_column module parameter
+   1.19. Setting from_uri_column module parameter
+   1.20. Setting priority_column module parameter
+   1.21. Setting lcr_count module parameter
+   1.22. Setting gw_uri_avp module parameter
+   1.23. Setting ruri_user_avp module parameter
+   1.24. Setting flags_avp module parameter
+   1.25. Setting defunct_capability module parameter
+   1.26. Setting lcr_id_avp module parameter
+   1.27. Setting defunct_gw_avp module parameter
+   1.28. Setting lcr_hash_size module parameter
+   1.29. Set fetch_rows parameter
+   1.30. load_gws usage
+   1.31. next_gw usage from a route block
+   1.32. next_gw usage from a failure route block
+   1.33. defunct_gw usage
    1.34. from_gw usage
-   1.35. to_gw usage
+   1.35. from_gw usage
    1.36. to_gw usage
-   1.37. lcr.reload RPC example
-   1.38. lcr.dump_gws RPC example
-   1.39. lcr.dump_lcr RPC example
+   1.37. to_gw usage
+   1.38. lcr.reload RPC example
+   1.39. lcr.dump_gws RPC example
+   1.40. lcr.dump_lcr RPC example
 
 Chapter 1. Admin Guide
 
@@ -142,26 +144,27 @@ Chapter 1. Admin Guide
         3.6. ip_addr_column (string)
         3.7. hostname_column (string)
         3.8. port_column (string)
-        3.9. uri_scheme_column (string)
-        3.10. transport_column (string)
-        3.11. strip_column (string)
-        3.12. tag_column (string)
-        3.13. weight_column (string)
-        3.14. flags_column (string)
-        3.15. defunct_column (string)
-        3.16. lcr_table (string)
-        3.17. prefix_column (string)
-        3.18. from_uri_column (string)
-        3.19. priority_column (string)
-        3.20. lcr_count (integer)
-        3.21. gw_uri_avp (AVP string)
-        3.22. ruri_user_avp (AVP string)
-        3.23. flags_avp (AVP string)
-        3.24. defunct_capability (integer)
-        3.25. lcr_id_avp (AVP string)
-        3.26. defunct_gw_avp (AVP string)
-        3.27. lcr_hash_size (integer)
-        3.28. fetch_rows (integer)
+        3.9. params_column (string)
+        3.10. uri_scheme_column (string)
+        3.11. transport_column (string)
+        3.12. strip_column (string)
+        3.13. tag_column (string)
+        3.14. weight_column (string)
+        3.15. flags_column (string)
+        3.16. defunct_column (string)
+        3.17. lcr_table (string)
+        3.18. prefix_column (string)
+        3.19. from_uri_column (string)
+        3.20. priority_column (string)
+        3.21. lcr_count (integer)
+        3.22. gw_uri_avp (AVP string)
+        3.23. ruri_user_avp (AVP string)
+        3.24. flags_avp (AVP string)
+        3.25. defunct_capability (integer)
+        3.26. lcr_id_avp (AVP string)
+        3.27. defunct_gw_avp (AVP string)
+        3.28. lcr_hash_size (integer)
+        3.29. fetch_rows (integer)
 
    4. Exported Functions
 
@@ -221,12 +224,12 @@ Chapter 1. Admin Guide
    URI is first stripped by the number of characters as specified by the
    gateway's strip count and then prefixed by the gateway's tag. Upon
    first call, if a gateway's hostname is NULL, the request URI will be
-   rewritten based on gateway's URI scheme, IP address, port, and
-   transport protocol. If hostname is not NULL, the request-URI is
-   rewritten based on the gateway's URI scheme and hostname, and
-   destination URI is set based on gateway's URI scheme, IP address, port,
-   and transport protocol. Upon subsequent calls, the same is done, but
-   instead of rewriting the Request URI, a new branch is added.
+   rewritten based on gateway's URI scheme, IP address, port, parameters,
+   and transport protocol. If hostname is not NULL, the request-URI is
+   rewritten based on the gateway's URI scheme, hostname, and parameters,
+   and destination URI is set based on gateway's URI scheme, IP address,
+   port, and transport protocol. Upon subsequent calls, the same is done,
+   but instead of rewriting the Request URI, a new branch is added.
 
    Valid URI scheme values are NULL = sip, 1 = sip and 2 = sips. Currently
    valid transport protocol values are NULL = none, 1 = udp, 2 = tcp, 3 =
@@ -263,26 +266,27 @@ Chapter 1. Admin Guide
    3.6. ip_addr_column (string)
    3.7. hostname_column (string)
    3.8. port_column (string)
-   3.9. uri_scheme_column (string)
-   3.10. transport_column (string)
-   3.11. strip_column (string)
-   3.12. tag_column (string)
-   3.13. weight_column (string)
-   3.14. flags_column (string)
-   3.15. defunct_column (string)
-   3.16. lcr_table (string)
-   3.17. prefix_column (string)
-   3.18. from_uri_column (string)
-   3.19. priority_column (string)
-   3.20. lcr_count (integer)
-   3.21. gw_uri_avp (AVP string)
-   3.22. ruri_user_avp (AVP string)
-   3.23. flags_avp (AVP string)
-   3.24. defunct_capability (integer)
-   3.25. lcr_id_avp (AVP string)
-   3.26. defunct_gw_avp (AVP string)
-   3.27. lcr_hash_size (integer)
-   3.28. fetch_rows (integer)
+   3.9. params_column (string)
+   3.10. uri_scheme_column (string)
+   3.11. transport_column (string)
+   3.12. strip_column (string)
+   3.13. tag_column (string)
+   3.14. weight_column (string)
+   3.15. flags_column (string)
+   3.16. defunct_column (string)
+   3.17. lcr_table (string)
+   3.18. prefix_column (string)
+   3.19. from_uri_column (string)
+   3.20. priority_column (string)
+   3.21. lcr_count (integer)
+   3.22. gw_uri_avp (AVP string)
+   3.23. ruri_user_avp (AVP string)
+   3.24. flags_avp (AVP string)
+   3.25. defunct_capability (integer)
+   3.26. lcr_id_avp (AVP string)
+   3.27. defunct_gw_avp (AVP string)
+   3.28. lcr_hash_size (integer)
+   3.29. fetch_rows (integer)
 
 3.1. db_url (string)
 
@@ -377,142 +381,154 @@ modparam("lcr", "hostname_column","hostname")
 modparam("lcr","port_column","port")
 ...
 
-3.9. uri_scheme_column (string)
+3.9. params_column (string)
+
+   Name of the column holding gateway's parameters that is used in
+   Request-URI, when request is sent to the gateway.
+
+   Default value is “params”.
+
+   Example 1.9. Setting params_column module parameter
+...
+modparam("lcr", "params_column","parameters")
+...
+
+3.10. uri_scheme_column (string)
 
    Name of the column holding the uri scheme of the gateway.
 
    Default value is “uri_scheme”.
 
-   Example 1.9. Setting uri_scheme_column module parameter
+   Example 1.10. Setting uri_scheme_column module parameter
 ...
 modparam("lcr","uri_scheme_column","uri_scheme")
 ...
 
-3.10. transport_column (string)
+3.11. transport_column (string)
 
    Name of the column holding the transport type to be used for the
    gateway.
 
    Default value is “transport”.
 
-   Example 1.10. Setting transport_column module parameter
+   Example 1.11. Setting transport_column module parameter
 ...
 modparam("lcr","transport_column","transport")
 ...
 
-3.11. strip_column (string)
+3.12. strip_column (string)
 
    Name of the column holding the number of characters to be stripped from
    the front of Request URI user part before inserting tag.
 
    Default value is “strip”.
 
-   Example 1.11. Setting strip_column module parameter
+   Example 1.12. Setting strip_column module parameter
 ...
 modparam("lcr","strip_column","strip_count")
 ...
 
-3.12. tag_column (string)
+3.13. tag_column (string)
 
    Name of the column holding gateway specific tag string.
 
    Default value is “tag”.
 
-   Example 1.12. Setting tag_column module parameter
+   Example 1.13. Setting tag_column module parameter
 ...
 modparam("lcr","tag_column","gw_tag")
 ...
 
-3.13. weight_column (string)
+3.14. weight_column (string)
 
    Name of the column holding gateway's weight within its group.
 
    Default value is “weight”.
 
-   Example 1.13. Setting weight_column module parameter
+   Example 1.14. Setting weight_column module parameter
 ...
 modparam("lcr","weight_column","gw_weight")
 ...
 
-3.14. flags_column (string)
+3.15. flags_column (string)
 
    Name of the column holding gateway specific flag values.
 
    Default value is “flags”.
 
-   Example 1.14. Setting flags_column module parameter
+   Example 1.15. Setting flags_column module parameter
 ...
 modparam("lcr","flags_column","gw_flags")
 ...
 
-3.15. defunct_column (string)
+3.16. defunct_column (string)
 
    Name of the column holding UNIX timestamp telling the time until which
    the gw is considered as defunct.
 
    Default value is “defunct”.
 
-   Example 1.15. Setting defunct_column module parameter
+   Example 1.16. Setting defunct_column module parameter
 ...
 modparam("lcr","defunct_column","defunct_until")
 ...
 
-3.16. lcr_table (string)
+3.17. lcr_table (string)
 
    Name of the table holding the LCR rules.
 
    Default value is “lcr”.
 
-   Example 1.16. Setting lcr_table module parameter
+   Example 1.17. Setting lcr_table module parameter
 ...
 modparam("lcr","lcr_table","lcr")
 ...
 
-3.17. prefix_column (string)
+3.18. prefix_column (string)
 
    Name of the column holding prefix of Request URI user part.
 
    Default value is “prefix”.
 
-   Example 1.17. Setting prefix_column module parameter
+   Example 1.18. Setting prefix_column module parameter
 ...
 modparam("lcr","prefix_column","prefix")
 ...
 
-3.18. from_uri_column (string)
+3.19. from_uri_column (string)
 
    Name of the column holding the FROM (source) URI.
 
    Default value is “from_uri”.
 
-   Example 1.18. Setting from_uri_column module parameter
+   Example 1.19. Setting from_uri_column module parameter
 ...
 modparam("lcr","from_uri_column","from_uri")
 ...
 
-3.19. priority_column (string)
+3.20. priority_column (string)
 
    Name of the column holding the priority of the rule.
 
    Default value is “priority”.
 
-   Example 1.19. Setting priority_column module parameter
+   Example 1.20. Setting priority_column module parameter
 ...
 modparam("lcr","priority_column","priority")
 ...
 
-3.20. lcr_count (integer)
+3.21. lcr_count (integer)
 
    Number of LCR instances.
 
    Default value is 1.
 
-   Example 1.20.  Setting lcr_count module parameter
+   Example 1.21.  Setting lcr_count module parameter
 ...
 modparam("lcr", "lcr_count", 10)
 ...
 
-3.21. gw_uri_avp (AVP string)
+3.22. gw_uri_avp (AVP string)
 
    Internal AVP that load_gws() function uses to store information of
    matching gateways.
@@ -520,12 +536,12 @@ modparam("lcr", "lcr_count", 10)
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.21. Setting gw_uri_avp module parameter
+   Example 1.22. Setting gw_uri_avp module parameter
 ...
 modparam("lcr", "gw_uri_avp", "$avp(i:709)")
 ...
 
-3.22. ruri_user_avp (AVP string)
+3.23. ruri_user_avp (AVP string)
 
    Internal AVP that next_gw function uses to store Request-URI user for
    subsequent next_gw calls.
@@ -533,12 +549,12 @@ modparam("lcr", "gw_uri_avp", "$avp(i:709)")
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.22. Setting ruri_user_avp module parameter
+   Example 1.23. Setting ruri_user_avp module parameter
 ...
 modparam("lcr", "ruri_user_avp", "$avp(i:500)")
 ...
 
-3.23. flags_avp (AVP string)
+3.24. flags_avp (AVP string)
 
    An AVP where successful next_gw and from_gw functions store gateway's
    flags.
@@ -546,24 +562,24 @@ modparam("lcr", "ruri_user_avp", "$avp(i:500)")
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.23. Setting flags_avp module parameter
+   Example 1.24. Setting flags_avp module parameter
 ...
 modparam("lcr", "flags_avp", "$avp(i:712)")
 ...
 
-3.24. defunct_capability (integer)
+3.25. defunct_capability (integer)
 
    Tells if defunct capability of (non-responsive) gateways is supported.
    Non-zero value turns on defunct capability.
 
    Default value is 0.
 
-   Example 1.24.  Setting defunct_capability module parameter
+   Example 1.25.  Setting defunct_capability module parameter
 ...
 modparam("lcr", "defunct_capability", 1)
 ...
 
-3.25. lcr_id_avp (AVP string)
+3.26. lcr_id_avp (AVP string)
 
    Internal AVP that load_gws() function uses to store LCR instance
    identifier of loaded gateways. Only needed if gateway defunct
@@ -571,12 +587,12 @@ modparam("lcr", "defunct_capability", 1)
 
    There is NO default value.
 
-   Example 1.25. Setting lcr_id_avp module parameter
+   Example 1.26. Setting lcr_id_avp module parameter
 ...
 modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 ...
 
-3.26. defunct_gw_avp (AVP string)
+3.27. defunct_gw_avp (AVP string)
 
    Internal AVP that next_gw() function uses to store IP address of the
    selected gateway for later use by defunct_gw() function. Only needed if
@@ -584,12 +600,12 @@ modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 
    There is NO default value.
 
-   Example 1.26. Setting defunct_gw_avp module parameter
+   Example 1.27. Setting defunct_gw_avp module parameter
 ...
 modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 ...
 
-3.27. lcr_hash_size (integer)
+3.28. lcr_hash_size (integer)
 
    Defines the size of hash table used to store <prefix, from_pattern,
    priority> tuples. Hashing is done based on prefix. Larger value means
@@ -598,12 +614,12 @@ modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 
    Default value is 128.
 
-   Example 1.27.  Setting lcr_hash_size module parameter
+   Example 1.28.  Setting lcr_hash_size module parameter
 ...
 modparam("lcr", "lcr_hash_size", 1024)
 ...
 
-3.28. fetch_rows (integer)
+3.29. fetch_rows (integer)
 
    The number of the rows to be fetched at once from database when loading
    data from the lcr table. This value can be used to tune the load time
@@ -613,7 +629,7 @@ modparam("lcr", "lcr_hash_size", 1024)
 
    Default value is “2000”.
 
-   Example 1.28. Set fetch_rows parameter
+   Example 1.29. Set fetch_rows parameter
 ...
 modparam("lcr", "fetch_rows", 3000)
 ...
@@ -630,11 +646,11 @@ modparam("lcr", "fetch_rows", 3000)
 
 4.1.  load_gws(lcr_id, caller_uri)
 
-   Loads URI schemes, IP addresses, hostnames, ports, and transports of
-   matching gateways to gw_uri_avp (see Overview section). Argument lcr_id
-   specifies the used LCR instance. It can be an integer or a pseudo
-   variable containing an integer value. Caller's URI is given by
-   caller_uri argument, which must be a pseudo variable.
+   Loads URI schemes, IP addresses, hostnames, ports, params, and
+   transports of matching gateways to gw_uri_avp (see Overview section).
+   Argument lcr_id specifies the used LCR instance. It can be an integer
+   or a pseudo variable containing an integer value. Caller's URI is given
+   by caller_uri argument, which must be a pseudo variable.
 
    Returns 1 if at least one matching gateway was found, 2 if no matching
    gateways was found, and -1 on error.
@@ -645,7 +661,7 @@ modparam("lcr", "fetch_rows", 3000)
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.29. load_gws usage
+   Example 1.30. load_gws usage
 ...
 if (!load_gws("1", "$var(caller_uri)")) {
         sl_send_reply("500", "Server Internal Error - Cannot load gateways");
@@ -655,15 +671,18 @@ if (!load_gws("1", "$var(caller_uri)")) {
 
 4.2.  next_gw()
 
-   Upon first call, replaces URI scheme, host, port, and transport of
-   Request-URI by the values stored in first gw_uri_avp and destroys that
-   AVP (see Overview section). Saves user part of Request-URI into
-   ruri_user_avp for use in subsequent next_gw() calls.
+   Upon first call, fetches values stored in first gw_uri_avp and then
+   destroys that AVP. If gateway's hostname is NULL, rewrites Request URI
+   based on gateway's URI scheme, IP address, port, parameters, and
+   transport protocol. If hostname is not NULL, the rewrites Request-URI
+   based on the gateway's URI scheme, hostname, and parameters, and sets
+   destination URI based on gateway's URI scheme, IP address, port, and
+   transport protocol. Saves user part of Request-URI into ruri_user_avp
+   for use in subsequent next_gw() calls.
 
-   Upon subsequent calls, appends a new branch URI to the request, where
-   URI scheme, host, port, and transport of are taken from values stored
-   in the first gw_uri_avp and destroys that AVP. URI user is taken from
-   ruri_user_avp.
+   Upon subsequent calls, does the same as in above, but instead of
+   rewriting Request URI, appends a new branch to the request. Takes URI
+   user from ruri_user_avp.
 
    As a side effect, stores gateway's flags to flags_avp.
 
@@ -674,7 +693,7 @@ if (!load_gws("1", "$var(caller_uri)")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.30. next_gw usage from a route block
+   Example 1.31. next_gw usage from a route block
 ...
 if (!next_gw()) {
         sl_send_reply("503", "Service not available - No gateways");
@@ -682,7 +701,7 @@ if (!next_gw()) {
 };
 ...
 
-   Example 1.31. next_gw usage from a failure route block
+   Example 1.32. next_gw usage from a failure route block
 ...
 if (!next_gw()) {
         t_reply("503", "Service not available - No more gateways");
@@ -701,7 +720,7 @@ if (!next_gw()) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.32. defunct_gw usage
+   Example 1.33. defunct_gw usage
 ...
 defunct_gw("60");
 ...
@@ -725,7 +744,7 @@ defunct_gw("60");
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.33. from_gw usage
+   Example 1.34. from_gw usage
 ...
 if (from_gw("1", "$avp(s:real_source_addr)") {
         ...
@@ -751,7 +770,7 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.34. from_gw usage
+   Example 1.35. from_gw usage
 ...
 $var(lcr_id) = from_any_gw();
 ...
@@ -770,7 +789,7 @@ $var(lcr_id) = from_any_gw();
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.35. to_gw usage
+   Example 1.36. to_gw usage
 ...
 if (to_gw("1")) {
         ...
@@ -793,7 +812,7 @@ if (to_gw("1")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.36. to_gw usage
+   Example 1.37. to_gw usage
 ...
 if (to_any_gw()) {
         ...
@@ -864,7 +883,7 @@ if (to_any_gw()) {
 
    Parameters: none
 
-   Example 1.37. lcr.reload RPC example
+   Example 1.38. lcr.reload RPC example
                 $ sercmd lcr.reload
 
 6.2. lcr.dump_gws
@@ -873,7 +892,7 @@ if (to_any_gw()) {
 
    Parameters: none
 
-   Example 1.38. lcr.dump_gws RPC example
+   Example 1.39. lcr.dump_gws RPC example
                 $ sercmd lcr.dump_gws
 
 6.3. lcr.dump_lcrs
@@ -882,7 +901,7 @@ if (to_any_gw()) {
 
    Parameters: none
 
-   Example 1.39. lcr.dump_lcr RPC example
+   Example 1.40. lcr.dump_lcr RPC example
                 $ sercmd lcr.dump_lcrs
 
 7. Known Limitations

+ 52 - 18
modules/lcr/doc/lcr_admin.xml

@@ -61,14 +61,22 @@
 	value being 0).  Weight is an integer value from 1 to 254.
 	</para>
 	<para>
-        The function <emphasis>next_gw()</emphasis> can then be used to select one gateway at a
-	time for forwarding.  Upon each call, the user part of the original request URI is first 
-	stripped by the number of characters as specified by the gateway's strip count and then prefixed by
-	the gateway's tag.  Upon first call, if a gateway's hostname is NULL, the request URI will be 
-	rewritten based on gateway's URI scheme, IP address, port, and transport protocol.  If hostname is not NULL,
-	the request-URI is rewritten based on the gateway's URI scheme and hostname, and destination URI is set 
-	based on gateway's URI scheme, IP address, port, and transport protocol.  Upon
-	subsequent calls, the same is done, but instead of rewriting the Request URI, a new branch is added.
+        The function <emphasis>next_gw()</emphasis> can then be used to
+	select one gateway at a 
+	time for forwarding.  Upon each call, the user part of the
+	original request URI is first  
+	stripped by the number of characters as specified by the
+	gateway's strip count and then prefixed by 
+	the gateway's tag.  Upon first call, if a gateway's hostname is
+	NULL, the request URI will be  
+	rewritten based on gateway's URI scheme, IP address, port,
+	parameters, and transport protocol.  If hostname is not NULL,
+	the request-URI is rewritten based on the gateway's URI scheme,
+	hostname, and parameters, and destination URI is set 
+	based on gateway's URI scheme, IP address, port, and transport
+	protocol.  Upon 
+	subsequent calls, the same is done, but instead of rewriting the
+	Request URI, a new branch is added. 
 	</para>
         <para>
         Valid URI scheme values are NULL = sip, 1 = sip and 2
@@ -287,6 +295,28 @@ modparam("lcr","port_column","port")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>params_column</varname> (string)</title>
+		<para>
+		Name of the column holding gateway's parameters that is
+		used in Request-URI, when request is sent to the
+		gateway.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>params</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>params_column</varname> module parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "params_column","parameters")
+...
+</programlisting>
+		</example>
+	</section>
+
 	<section>
 		<title><varname>uri_scheme_column</varname> (string)</title>
 		<para>
@@ -734,7 +764,8 @@ modparam("lcr", "fetch_rows", 3000)
 		<function moreinfo="none">load_gws(lcr_id, caller_uri)</function>
 		</title>
 		<para>
-		Loads URI schemes, IP addresses, hostnames, ports, and
+		Loads URI schemes, IP addresses, hostnames, ports,
+		params, and
 		transports of matching gateways to gw_uri_avp
 		(see Overview section).  Argument lcr_id specifies the used
 	        LCR instance.  It can be an integer or a pseudo
@@ -773,18 +804,21 @@ if (!load_gws("1", "$var(caller_uri)")) {
 		<function moreinfo="none">next_gw()</function>
 		</title>	
 		<para>
-		Upon first call, replaces URI scheme, host,
-		port, and transport of Request-URI by the values stored
-		in first gw_uri_avp and destroys that AVP (see
-		Overview section).  Saves user part of Request-URI into
+		Upon first call, fetches values stored in first
+		gw_uri_avp and then destroys that AVP.  If gateway's
+		hostname is NULL, rewrites Request URI based on
+		gateway's URI scheme, IP address, port, parameters, and
+		transport protocol. If hostname is not NULL, the
+		rewrites Request-URI based on the gateway's URI scheme,
+		hostname, and parameters, and sets destination URI based
+		on gateway's URI scheme, IP address, port, and transport
+		protocol. Saves user part of Request-URI into
 		ruri_user_avp for use in subsequent next_gw() calls.
 		</para>
 		<para>
-		Upon subsequent calls, appends a new branch URI to
-		the request, where URI scheme, host, port, and transport of
-		are taken from values stored in the first gw_uri_avp
-		and destroys that AVP.  URI user is taken from
-		ruri_user_avp.
+		Upon subsequent calls, does the same as in above, but
+		instead of rewriting Request URI, appends a new branch
+		to the request.  Takes URI user from ruri_user_avp.
 		</para>
 		<para>
 		As a side effect, stores gateway's flags to flags_avp.

+ 72 - 17
modules/lcr/lcr_mod.c

@@ -1,5 +1,4 @@
 /*
- *
  * Least Cost Routing module
  *
  * Copyright (C) 2005-2009 Juha Heinanen
@@ -100,7 +99,7 @@ MODULE_VERSION
  * increment this value if you change the table in
  * an backwards incompatible way
  */
-#define GW_TABLE_VERSION 10
+#define GW_TABLE_VERSION 11
 #define LCR_TABLE_VERSION 3
 
 static void destroy(void);       /* Module destroy function */
@@ -123,6 +122,8 @@ static void free_shared_memory(void);
 
 #define PORT_COL "port"
 
+#define PARAMS_COL "params"
+
 #define URI_SCHEME_COL "uri_scheme"
 
 #define TRANSPORT_COL "transport"
@@ -194,6 +195,7 @@ static str grp_id_col       = str_init(GRP_ID_COL);
 static str ip_addr_col      = str_init(IP_ADDR_COL);
 static str hostname_col     = str_init(HOSTNAME_COL);
 static str port_col         = str_init(PORT_COL);
+static str params_col       = str_init(PARAMS_COL);
 static str uri_scheme_col   = str_init(URI_SCHEME_COL);
 static str transport_col    = str_init(TRANSPORT_COL);
 static str strip_col        = str_init(STRIP_COL);
@@ -304,6 +306,7 @@ static param_export_t params[] = {
     {"ip_addr_column",           STR_PARAM, &ip_addr_col.s  },
     {"hostname_column",          STR_PARAM, &hostname_col.s },
     {"port_column",              STR_PARAM, &port_col.s     },
+    {"params_column",            STR_PARAM, &params_col.s   },
     {"uri_scheme_column",        STR_PARAM, &uri_scheme_col.s },
     {"transport_column",         STR_PARAM, &transport_col.s },
     {"strip_column",             STR_PARAM, &strip_col.s    },
@@ -443,6 +446,7 @@ static int mod_init(void)
     ip_addr_col.len = strlen(ip_addr_col.s);
     hostname_col.len = strlen(hostname_col.s);
     port_col.len = strlen(port_col.s);
+    params_col.len = strlen(params_col.s);
     uri_scheme_col.len = strlen(uri_scheme_col.s);
     transport_col.len = strlen(transport_col.s);
     strip_col.len = strlen(strip_col.s);
@@ -810,6 +814,7 @@ static int gw_unique(const struct gw_info *gws, const unsigned int count,
 static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int ip_addr,
 		     char *hostname, unsigned int hostname_len,
 		     unsigned int grp_id, char *ip_string, unsigned int port,
+		     char *params, unsigned int params_len,
 		     unsigned int scheme, unsigned int transport,
 		     unsigned int flags, unsigned int strip, char *tag,
 		     unsigned int tag_len, unsigned short weight,
@@ -825,6 +830,8 @@ static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int ip_addr,
     gws[i].hostname_len = hostname_len;
     gws[i].ip_addr = ip_addr;
     gws[i].port = port;
+    if (params_len) memcpy(&(gws[i].params[0]), params, params_len);
+    gws[i].params_len = params_len;
     gws[i].grp_id = grp_id;
     gws[i].scheme = scheme;
     gws[i].transport = transport;
@@ -937,17 +944,17 @@ int reload_gws_and_lcrs(int lcr_id)
 {
     unsigned int i, n, port, strip, tag_len, prefix_len, from_uri_len,
 	grp_id,	grp_cnt, priority, flags, first_gw, weight, gw_cnt,
-	hostname_len, defunct_until;
+	hostname_len, params_len, defunct_until;
     struct in_addr ip_addr;
     uri_type scheme;
     uri_transport transport;
-    char *ip_string, *hostname, *tag, *prefix, *from_uri;
+    char *ip_string, *hostname, *tag, *prefix, *from_uri, *params;
     db1_res_t* res = NULL;
     db_row_t* row;
     db_key_t key_cols[1];
     db_op_t op[1];
     db_val_t vals[1];
-    db_key_t gw_cols[11];
+    db_key_t gw_cols[12];
     db_key_t lcr_cols[4];
     pcre *from_uri_re;
     struct gw_grp gw_grps[MAX_NO_OF_GWS];
@@ -971,6 +978,7 @@ int reload_gws_and_lcrs(int lcr_id)
     gw_cols[8] = &weight_col;
     gw_cols[9] = &hostname_col;
     gw_cols[10] = &defunct_col;
+    gw_cols[11] = &params_col;
 
     lcr_cols[0] = &prefix_col;
     lcr_cols[1] = &from_uri_col;
@@ -991,7 +999,7 @@ int reload_gws_and_lcrs(int lcr_id)
 	return -1;
     }
 
-    if (lcr_dbf.query(dbh, key_cols, op, vals, gw_cols, 1, 11, 0, &res) < 0) {
+    if (lcr_dbf.query(dbh, key_cols, op, vals, gw_cols, 1, 12, 0, &res) < 0) {
 	LM_ERR("failed to query gw data\n");
 	lcr_db_close();
 	return -1;
@@ -1159,10 +1167,33 @@ int reload_gws_and_lcrs(int lcr_id)
 	    }
 	    defunct_until = (unsigned int)VAL_INT(ROW_VALUES(row) + 10);
 	}
+	if (VAL_NULL(ROW_VALUES(row) + 11)) {
+	    params_len = 0;
+	    params = (char *)0;
+	} else {
+	    if (VAL_TYPE(ROW_VALUES(row) + 11) != DB1_STRING) {
+		LM_ERR("params of gw <%s> at row <%u> is not string\n",
+		       ip_string, i);
+		goto gw_err;
+	    }
+	    params = (char *)VAL_STRING(ROW_VALUES(row) + 11);
+	    params_len = strlen(params);
+	    if ((params_len > 0) && (params[0] != ';')) {
+		LM_ERR("params of gw <%s> at row <%u> does not start "
+		       "with ';'\n", ip_string, i);
+		goto gw_err;
+	    }
+		
+	}
+	if (params_len > MAX_PARAMS_LEN) {
+	    LM_ERR("params length <%u> of gw <%s> at row <%u> it too large\n",
+		   params_len, ip_string, i);
+	    goto gw_err;
+	}
 	if (!insert_gw(gws, i + 1, (unsigned int)ip_addr.s_addr, 
 		       hostname, hostname_len, grp_id,
-		       ip_string, port, scheme, transport, flags, strip,
-		       tag, tag_len, weight, defunct_until)) {
+		       ip_string, port, params, params_len, scheme, transport,
+		       flags, strip, tag, tag_len, weight, defunct_until)) {
 	    goto gw_err;
 	}
     }
@@ -1372,6 +1403,10 @@ int mi_print_gws(struct mi_node* rpl)
 	    }	    
 	    if (attr == NULL) goto err;
 
+	    attr = add_mi_attr(node, MI_DUP_VALUE, "PARAMS", 6,
+			       gws[i].params, gws[i].params_len );
+	    if (attr == NULL) goto err;
+
 	    if (gws[i].scheme == SIP_URI_T) {
 		attr = add_mi_attr(node, MI_DUP_VALUE, "SCHEME", 6, "sip", 3);
 	    } else {
@@ -1500,6 +1535,7 @@ inline int encode_avp_value(char *value, uri_type scheme, unsigned int strip,
 			    char *tag, unsigned int tag_len,
 			    unsigned int ip_addr, char *hostname,
 			    unsigned int hostname_len, unsigned int port,
+			    char *params, unsigned int params_len,
 			    uri_transport transport, unsigned int flags)
 {
     char *at, *string;
@@ -1528,6 +1564,9 @@ inline int encode_avp_value(char *value, uri_type scheme, unsigned int strip,
     string = int2str(port, &len);
     append_str(at, string, len);
     append_chr(at, '|');
+    /* params */
+    append_str(at, params, params_len);
+    append_chr(at, '|');
     /* transport */
     string = int2str(transport, &len);
     append_str(at, string, len);
@@ -1540,7 +1579,8 @@ inline int encode_avp_value(char *value, uri_type scheme, unsigned int strip,
 
 inline int decode_avp_value(char *value, str *scheme, unsigned int *strip,
 			    str *tag, unsigned int *addr, str *hostname,
-			    str *port, str *transport, unsigned int *flags)
+			    str *port, str *params, str *transport,
+			    unsigned int *flags)
 {
     unsigned int u;
     str s;
@@ -1604,6 +1644,14 @@ inline int decode_avp_value(char *value, str *scheme, unsigned int *strip,
 	return 0;
     }
     port->len = sep - port->s;
+    /* params */
+    params->s = sep + 1;
+    sep = index(params->s, '|');
+    if (sep == NULL) {
+	LM_ERR("params was not found in AVP value\n");
+	return 0;
+    }
+    params->len = sep - params->s;
     /* transport */
     s.s = sep + 1;
     sep = index(s.s, '|');
@@ -1644,7 +1692,7 @@ inline int decode_avp_value(char *value, str *scheme, unsigned int *strip,
 void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
 		       unsigned int gw_cnt, str *ruri_user)
 {
-    unsigned int i, index, strip, hostname_len;
+    unsigned int i, index, strip, hostname_len, params_len;
     int tag_len;
     str value;
     char encoded_value[MAX_URI_LEN];
@@ -1656,6 +1704,7 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
 	if (matched_gws[i].duplicate == 1) continue;
 	index = matched_gws[i].gw_index;
       	hostname_len = gws[index].hostname_len;
+      	params_len = gws[index].params_len;
 	strip = gws[index].strip;
 	if (strip > ruri_user->len) {
 	    LM_ERR("strip count of gw is too large <%u>\n", strip);
@@ -1664,8 +1713,8 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
 	tag_len = gws[index].tag_len;
 	if (5 /* scheme */ + 4 /* strip */ + tag_len + 1 /* @ */ +
 	    ((hostname_len > 15)?hostname_len:15) + 6 /* port */ +
-	    15 /* transport */ + 10 /* flags */ + 7 /* separators */
-	    > MAX_URI_LEN) {
+	    params_len /* params */ + 15 /* transport */ + 10 /* flags */ +
+	    7 /* separators */ > MAX_URI_LEN) {
 	    LM_ERR("too long AVP value\n");
 	    goto skip;
 	}
@@ -1673,8 +1722,8 @@ void add_gws_into_avps(struct gw_info *gws, struct matched_gw_info *matched_gws,
 	    encode_avp_value(encoded_value, gws[index].scheme, strip,
 			     gws[index].tag, tag_len, gws[index].ip_addr,
 			     gws[index].hostname, hostname_len,
-			     gws[index].port, gws[index].transport,
-			     gws[index].flags);
+			     gws[index].port, gws[index].params, params_len,
+			     gws[index].transport, gws[index].flags);
 	value.s = (char *)&(encoded_value[0]);
 	val.s = value;
 	add_avp(gw_uri_avp_type|AVP_VAL_STR, gw_uri_avp, val);
@@ -1825,7 +1874,7 @@ static int generate_uris(char *r_uri, str *r_uri_user, unsigned int *r_uri_len,
 {
     int_str gw_uri_val;
     struct usr_avp *gu_avp;
-    str scheme, tag, hostname, port, transport, addr_str;
+    str scheme, tag, hostname, port, params, transport, addr_str;
     char *at;
     unsigned int strip;
     struct ip_addr a;
@@ -1835,7 +1884,7 @@ static int generate_uris(char *r_uri, str *r_uri_user, unsigned int *r_uri_len,
     if (!gu_avp) return 0; /* No more gateways left */
 
     decode_avp_value(gw_uri_val.s.s, &scheme, &strip, &tag, addr,
-		     &hostname, &port, &transport, flags);
+		     &hostname, &port, &params, &transport, flags);
 
     a.af = AF_INET;
     a.len = 4;
@@ -1845,7 +1894,7 @@ static int generate_uris(char *r_uri, str *r_uri_user, unsigned int *r_uri_len,
     
     if (scheme.len + r_uri_user->len - strip + tag.len + 1 /* @ */ +
 	((hostname.len > 15)?hostname.len:15) + 1 /* : */ +
-	port.len + transport.len + 1 /* null */ > MAX_URI_LEN) {
+	port.len + params.len + transport.len + 1 /* null */ > MAX_URI_LEN) {
 	LM_ERR("too long Request URI or DST URI\n");
 	return -1;
     }
@@ -1870,6 +1919,9 @@ static int generate_uris(char *r_uri, str *r_uri_user, unsigned int *r_uri_len,
 	    append_chr(at, ':');
 	    append_str(at, port.s, port.len);
 	}
+	if (params.len > 0) {
+	    append_str(at, params.s, params.len);
+	}
 	if (transport.len > 0) {
 	    append_str(at, transport.s, transport.len);
 	}
@@ -1878,6 +1930,9 @@ static int generate_uris(char *r_uri, str *r_uri_user, unsigned int *r_uri_len,
 	*dst_uri_len = 0;
     } else {
 	append_str(at, hostname.s, hostname.len);
+	if (params.len > 0) {
+	    append_str(at, params.s, params.len);
+	}
 	*at = '\0';
 	*r_uri_len = at - r_uri;
 	at = dst_uri;

+ 3 - 0
modules/lcr/lcr_mod.h

@@ -49,6 +49,7 @@
 #define MAX_NO_OF_GWS 128
 #define MAX_TAG_LEN 16
 #define MAX_USER_LEN 64
+#define MAX_PARAMS_LEN 64
 
 struct lcr_info {
     char prefix[MAX_PREFIX_LEN + 1];
@@ -69,6 +70,8 @@ struct gw_info {
     char hostname[MAX_HOST_LEN];
     unsigned short hostname_len;
     unsigned int port;
+    char params[MAX_PARAMS_LEN];
+    unsigned short params_len;
     unsigned int grp_id;
     uri_type scheme;
     uri_transport transport;

+ 4 - 1
modules/lcr/lcr_rpc.c

@@ -69,7 +69,7 @@ static void dump_gws(rpc_t* rpc, void* c)
 	void* st;
 	unsigned int i, j;
 	enum sip_protos transport;
-	str hostname;
+	str hostname, params;
 	str tag;
 	struct gw_info *gws;
 
@@ -91,6 +91,9 @@ static void dump_gws(rpc_t* rpc, void* c)
 		rpc->struct_add(st, "S", "hostname", &hostname);
 		if  (gws[i].port > 0)
 			rpc->struct_add(st, "d", "port", gws[i].port);
+		params.s=gws[i].params;
+		params.len=gws[i].params_len;
+		rpc->struct_add(st, "S", "params", &params);
 		if (gws[i].scheme == SIP_URI_T) {
 		    rpc->struct_add(st, "s", "scheme", "sip");
 		} else {