Sfoglia il codice sorgente

modules/lcr: major rewrite
- For easier management, information is now kept in three tables:
lcr_rule, lcr_rule_target, and lcr_gw.
- For simplicity, gateway groups are not anymore supported.
- Added possibility to stop trying to match shorter prefixes, when a
matching prefix is found.
- Stripping and tagging can be controlled by a flag.
- New database schema and upgrade script will be provided
later today.

Juha Heinanen 15 anni fa
parent
commit
550db5cb15
8 ha cambiato i file con 1645 aggiunte e 1161 eliminazioni
  1. 353 243
      modules/lcr/README
  2. 297 126
      modules/lcr/doc/lcr_admin.xml
  3. 119 49
      modules/lcr/hash.c
  4. 18 12
      modules/lcr/hash.h
  5. 694 592
      modules/lcr/lcr_mod.c
  6. 35 21
      modules/lcr/lcr_mod.h
  7. 123 112
      modules/lcr/lcr_rpc.c
  8. 6 6
      modules/lcr/lcr_rpc.h

+ 353 - 243
modules/lcr/README

@@ -28,10 +28,10 @@ Juha Heinanen
         3. Exported Parameters
 
               3.1. db_url (string)
-              3.2. gw_table (string)
-              3.3. lcr_id_column (string)
-              3.4. gw_name_column (string)
-              3.5. grp_id_column (string)
+              3.2. lcr_gw_table (string)
+              3.3. id_column (string)
+              3.4. lcr_id_column (string)
+              3.5. gw_name_column (string)
               3.6. ip_addr_column (string)
               3.7. hostname_column (string)
               3.8. port_column (string)
@@ -40,22 +40,29 @@ Juha Heinanen
               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.14. flags_column (string)
+              3.15. defunct_column (string)
+              3.16. lcr_rule_table (string)
+              3.17. prefix_column (string)
+              3.18. from_uri_column (string)
+              3.19. stopper_column (string)
+              3.20. enabled_column (string)
+              3.21. lcr_rule_target_table (string)
+              3.22. rule_id_column (string)
+              3.23. gw_id_column (string)
+              3.24. priority_column (string)
+              3.25. weight_column (string)
+              3.26. lcr_count (integer)
+              3.27. gw_uri_avp (AVP string)
+              3.28. ruri_user_avp (AVP string)
+              3.29. flags_avp (AVP string)
+              3.30. defunct_capability (integer)
+              3.31. lcr_id_avp (AVP string)
+              3.32. defunct_gw_avp (AVP string)
+              3.33. lcr_rule_hash_size (integer)
+              3.34. lcr_gw_count (integer)
+              3.35. dont_strip_or_tag (integer)
+              3.36. fetch_rows (integer)
 
         4. Exported Functions
 
@@ -71,7 +78,7 @@ Juha Heinanen
 
               5.1. lcr.reload
               5.2. lcr.dump_gws
-              5.3. lcr.dump_lcrs
+              5.3. lcr.dump_rules
 
         6. Known Limitations
 
@@ -79,9 +86,9 @@ Juha Heinanen
 
    1.1. Setting db_url module parameter
    1.2. Setting gw_table module parameter
-   1.3. Setting lcr_id_column module parameter
-   1.4. Setting gw_name_column module parameter
-   1.5. Setting grp_id_column module parameter
+   1.3. Setting id_column module parameter
+   1.4. Setting lcr_id_column module parameter
+   1.5. Setting gw_name_column module parameter
    1.6. Setting ip_addr_column module parameter
    1.7. Setting hostname_column module parameter
    1.8. Setting port_column module parameter
@@ -90,33 +97,40 @@ Juha Heinanen
    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. from_gw usage
-   1.36. to_gw usage
-   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
+   1.14. Setting flags_column module parameter
+   1.15. Setting defunct_column module parameter
+   1.16. Setting lcr_rule_table module parameter
+   1.17. Setting prefix_column module parameter
+   1.18. Setting from_uri_column module parameter
+   1.19. Setting stopper_column module parameter
+   1.20. Setting enabled_column module parameter
+   1.21. Setting lcr_rule_target_table module parameter
+   1.22. Setting rule_id_column module parameter
+   1.23. Setting gw_id_column module parameter
+   1.24. Setting priority_column module parameter
+   1.25. Setting weight_column module parameter
+   1.26. Setting lcr_count module parameter
+   1.27. Setting gw_uri_avp module parameter
+   1.28. Setting ruri_user_avp module parameter
+   1.29. Setting flags_avp module parameter
+   1.30. Setting defunct_capability module parameter
+   1.31. Setting lcr_id_avp module parameter
+   1.32. Setting defunct_gw_avp module parameter
+   1.33. Setting lcr_rule_hash_size module parameter
+   1.34. Setting lcr_gw_count module parameter
+   1.35. Setting dont_strip_or_tag_flag module parameter
+   1.36. Set fetch_rows parameter
+   1.37. load_gws usage
+   1.38. next_gw usage from a route block
+   1.39. next_gw usage from a failure route block
+   1.40. defunct_gw usage
+   1.41. from_gw usage
+   1.42. from_gw usage
+   1.43. to_gw usage
+   1.44. to_gw usage
+   1.45. lcr.reload RPC example
+   1.46. lcr.dump_gws RPC example
+   1.47. lcr.dump_rules RPC example
 
 Chapter 1. Admin Guide
 
@@ -131,10 +145,10 @@ Chapter 1. Admin Guide
    3. Exported Parameters
 
         3.1. db_url (string)
-        3.2. gw_table (string)
-        3.3. lcr_id_column (string)
-        3.4. gw_name_column (string)
-        3.5. grp_id_column (string)
+        3.2. lcr_gw_table (string)
+        3.3. id_column (string)
+        3.4. lcr_id_column (string)
+        3.5. gw_name_column (string)
         3.6. ip_addr_column (string)
         3.7. hostname_column (string)
         3.8. port_column (string)
@@ -143,22 +157,29 @@ Chapter 1. Admin Guide
         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.14. flags_column (string)
+        3.15. defunct_column (string)
+        3.16. lcr_rule_table (string)
+        3.17. prefix_column (string)
+        3.18. from_uri_column (string)
+        3.19. stopper_column (string)
+        3.20. enabled_column (string)
+        3.21. lcr_rule_target_table (string)
+        3.22. rule_id_column (string)
+        3.23. gw_id_column (string)
+        3.24. priority_column (string)
+        3.25. weight_column (string)
+        3.26. lcr_count (integer)
+        3.27. gw_uri_avp (AVP string)
+        3.28. ruri_user_avp (AVP string)
+        3.29. flags_avp (AVP string)
+        3.30. defunct_capability (integer)
+        3.31. lcr_id_avp (AVP string)
+        3.32. defunct_gw_avp (AVP string)
+        3.33. lcr_rule_hash_size (integer)
+        3.34. lcr_gw_count (integer)
+        3.35. dont_strip_or_tag (integer)
+        3.36. fetch_rows (integer)
 
    4. Exported Functions
 
@@ -174,7 +195,7 @@ Chapter 1. Admin Guide
 
         5.1. lcr.reload
         5.2. lcr.dump_gws
-        5.3. lcr.dump_lcrs
+        5.3. lcr.dump_rules
 
    6. Known Limitations
 
@@ -188,45 +209,48 @@ Chapter 1. Admin Guide
    least cost rules). Each such instance has its own LCR identifier.
 
    For the purpose of facilitating least cost routing of requests, each
-   gateway of an LCR instance belongs to a gateway group and each gateway
-   group is associated with one or more <prefix, from pattern, priority>
-   tuples. A gateway matches a request if the user part of the Request-URI
-   matches a "prefix" and the caller's URI matches a "from" pattern in a
-   tuple that belongs to the group of the gateway.
+   gateway of an LCR instance is associated with one or more <prefix, from
+   pattern, priority, weight> tuples. A gateway matches a request if user
+   part of the Request-URI matches a "prefix" and the caller's URI matches
+   a "from" pattern in a tuple that is associated with the gateway.
 
    When the function load_gws() is called, matching gateways (that are not
-   currently designated as defunct) are ordered for forwarding purposes in
-   the following order:
+   currently designated as defunct) are ordered for forwarding purposes as
+   follows:
+
      * (1) according to longest user part match
      * (2) according to tuple's priority
-     * (3) gateway's randomized weight within its group
+     * (3) according to tuple's randomized weight
+
+   A tuple can be marked as a "stopper" tuple. If a "stopper" tuple
+   matches, then matching stops at it and all other tuples with shorter
+   prefixes are not considered.
 
    Prefix is a string of characters or NULL. From pattern is a regular
    expression (see 'man pcresyntax' for syntax), an empty string, or NULL.
    An empty or NULL from pattern or prefix matches anything. Smaller
-   priority value means higher priority (highest priority value being 0).
-   Weight is an integer value from 1 to 254.
+   priority value means higher priority (highest priority value being 0
+   and lowest being 255). Weight is an integer value from 1 to 254.
 
    The function next_gw() 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, Request-URI will be
-   rewritten based on gateway's URI scheme, IP address, port, parameters,
-   and transport protocol. If hostname is not NULL and IP address is NULL,
-   Request-URI will be rewritten based on the gateway's URI scheme,
-   hostname, port, parameters and transport protocol. If both hostname and
-   IP address are not NULL, Request-URI will be rewritten based on
-   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.
+   for forwarding. Upon each call, unless "dont_strip_of_tag" flag is set,
+   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 each call, if a gateway's hostname
+   is NULL, Request-URI will be rewritten based on gateway's URI scheme,
+   IP address, port, parameters, and transport protocol. If hostname is
+   not NULL and IP address is NULL, Request-URI will be rewritten based on
+   the gateway's URI scheme, hostname, port, parameters and transport
+   protocol. If both hostname and IP address are not NULL, Request-URI
+   will be rewritten based on gateway's URI scheme, hostname, and
+   parameters, and destination URI is set based on gateway's URI scheme,
+   IP address, port, and transport protocol.
 
    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 =
    tls, and 4 = sctp.
 
-   As a side effect of the gateway selection, the gateway's flags (that
+   As a side effect of gateway selection, selected gateway's flags (that
    may contain information about capabilities of the gateway) are stored
    into an AVP.
 
@@ -238,7 +262,6 @@ Chapter 1. Admin Guide
 2.1. SIP Router modules
 
    The following modules must be loaded before this module:
-     * TM module
      * A database module like mysql, postgres or dbtext.
 
 2.2. External libraries or applications
@@ -250,10 +273,10 @@ Chapter 1. Admin Guide
 3. Exported Parameters
 
    3.1. db_url (string)
-   3.2. gw_table (string)
-   3.3. lcr_id_column (string)
-   3.4. gw_name_column (string)
-   3.5. grp_id_column (string)
+   3.2. lcr_gw_table (string)
+   3.3. id_column (string)
+   3.4. lcr_id_column (string)
+   3.5. gw_name_column (string)
    3.6. ip_addr_column (string)
    3.7. hostname_column (string)
    3.8. port_column (string)
@@ -262,22 +285,29 @@ Chapter 1. Admin Guide
    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.14. flags_column (string)
+   3.15. defunct_column (string)
+   3.16. lcr_rule_table (string)
+   3.17. prefix_column (string)
+   3.18. from_uri_column (string)
+   3.19. stopper_column (string)
+   3.20. enabled_column (string)
+   3.21. lcr_rule_target_table (string)
+   3.22. rule_id_column (string)
+   3.23. gw_id_column (string)
+   3.24. priority_column (string)
+   3.25. weight_column (string)
+   3.26. lcr_count (integer)
+   3.27. gw_uri_avp (AVP string)
+   3.28. ruri_user_avp (AVP string)
+   3.29. flags_avp (AVP string)
+   3.30. defunct_capability (integer)
+   3.31. lcr_id_avp (AVP string)
+   3.32. defunct_gw_avp (AVP string)
+   3.33. lcr_rule_hash_size (integer)
+   3.34. lcr_gw_count (integer)
+   3.35. dont_strip_or_tag (integer)
+   3.36. fetch_rows (integer)
 
 3.1. db_url (string)
 
@@ -290,50 +320,50 @@ Chapter 1. Admin Guide
 modparam("lcr","db_url","dbdriver://username:password@dbhost/dbname")
 ...
 
-3.2. gw_table (string)
+3.2. lcr_gw_table (string)
 
    Name of the table holding gateways definitions.
 
-   Default value is “gw”.
+   Default value is “lcr_gw”.
 
    Example 1.2. Setting gw_table module parameter
 ...
-modparam("lcr","gw_table","gw")
+modparam("lcr", "lcr_gw_table","gw")
 ...
 
-3.3. lcr_id_column (string)
+3.3. id_column (string)
 
-   Name of the column holding the identifier of an LCR instance. Common to
-   both gw and lcr tables.
+   Name of the auto-increment, primary key column. Common to all lcr
+   module tables.
 
-   Default value is “lcr_id”.
+   Default value is “id”.
 
-   Example 1.3. Setting lcr_id_column module parameter
+   Example 1.3. Setting id_column module parameter
 ...
-modparam("lcr", "lcr_id_column", "lcr_identifier")
+modparam("lcr", "id_column", "row_id")
 ...
 
-3.4. gw_name_column (string)
+3.4. lcr_id_column (string)
 
-   Name of the column holding the gateway name.
+   Name of the column holding the identifier of an LCR instance. Common to
+   all lcr module tables.
 
-   Default value is “gw_name”.
+   Default value is “lcr_id”.
 
-   Example 1.4. Setting gw_name_column module parameter
+   Example 1.4. Setting lcr_id_column module parameter
 ...
-modparam("lcr","gw_name_column","gw_name")
+modparam("lcr", "lcr_id_column", "lcr_identifier")
 ...
 
-3.5. grp_id_column (string)
+3.5. gw_name_column (string)
 
-   Name of the column holding the group ID of gateway both in gw and lcr
-   tables.
+   Name of the column holding gateway's name for documentation purpose.
 
-   Default value is “grp_id”.
+   Default value is “gw_name”.
 
-   Example 1.5. Setting grp_id_column module parameter
+   Example 1.5. Setting gw_name_column module parameter
 ...
-modparam("lcr","grp_id_column","grp_id")
+modparam("lcr", "gw_name_column", "name")
 ...
 
 3.6. ip_addr_column (string)
@@ -344,19 +374,19 @@ modparam("lcr","grp_id_column","grp_id")
 
    Example 1.6. Setting ip_addr_column module parameter
 ...
-modparam("lcr","ip_addr_column","ip_addr")
+modparam("lcr", "ip_addr_column", "ip")
 ...
 
 3.7. hostname_column (string)
 
    Name of the column holding gateway's hostname that is used in
-   Request-URI, when request is sent to the gateway.
+   Request-URI hostpart, when request is sent to the gateway.
 
    Default value is “hostname”.
 
    Example 1.7. Setting hostname_column module parameter
 ...
-modparam("lcr", "hostname_column","hostname")
+modparam("lcr", "hostname_column", "host")
 ...
 
 3.8. port_column (string)
@@ -367,7 +397,7 @@ modparam("lcr", "hostname_column","hostname")
 
    Example 1.8. Setting port_column module parameter
 ...
-modparam("lcr","port_column","port")
+modparam("lcr", "port_column", "port")
 ...
 
 3.9. params_column (string)
@@ -379,7 +409,7 @@ modparam("lcr","port_column","port")
 
    Example 1.9. Setting params_column module parameter
 ...
-modparam("lcr", "params_column","parameters")
+modparam("lcr", "params_column", "parameters")
 ...
 
 3.10. uri_scheme_column (string)
@@ -390,19 +420,19 @@ modparam("lcr", "params_column","parameters")
 
    Example 1.10. Setting uri_scheme_column module parameter
 ...
-modparam("lcr","uri_scheme_column","uri_scheme")
+modparam("lcr", "uri_scheme_column", "uri_scheme")
 ...
 
 3.11. transport_column (string)
 
-   Name of the column holding the transport type to be used for the
+   Name of the column holding the transport protocol to be used for the
    gateway.
 
    Default value is “transport”.
 
    Example 1.11. Setting transport_column module parameter
 ...
-modparam("lcr","transport_column","transport")
+modparam("lcr", "transport_column", "trans")
 ...
 
 3.12. strip_column (string)
@@ -414,110 +444,169 @@ modparam("lcr","transport_column","transport")
 
    Example 1.12. Setting strip_column module parameter
 ...
-modparam("lcr","strip_column","strip_count")
+modparam("lcr", "strip_column", "strip_count")
 ...
 
 3.13. tag_column (string)
 
-   Name of the column holding gateway specific tag string.
+   Name of the column holding gateway specific tag string that is added to
+   Request URI userpart after stripping.
 
    Default value is “tag”.
 
    Example 1.13. Setting tag_column module parameter
 ...
-modparam("lcr","tag_column","gw_tag")
-...
-
-3.14. weight_column (string)
-
-   Name of the column holding gateway's weight within its group.
-
-   Default value is “weight”.
-
-   Example 1.14. Setting weight_column module parameter
-...
-modparam("lcr","weight_column","gw_weight")
+modparam("lcr", "tag_column", "gw_tag")
 ...
 
-3.15. flags_column (string)
+3.14. flags_column (string)
 
    Name of the column holding gateway specific flag values.
 
    Default value is “flags”.
 
-   Example 1.15. Setting flags_column module parameter
+   Example 1.14. Setting flags_column module parameter
 ...
-modparam("lcr","flags_column","gw_flags")
+modparam("lcr", "flags_column", "gw_flags")
 ...
 
-3.16. defunct_column (string)
+3.15. 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.16. Setting defunct_column module parameter
+   Example 1.15. Setting defunct_column module parameter
 ...
-modparam("lcr","defunct_column","defunct_until")
+modparam("lcr", "defunct_column", "defunct_until")
 ...
 
-3.17. lcr_table (string)
+3.16. lcr_rule_table (string)
 
    Name of the table holding the LCR rules.
 
-   Default value is “lcr”.
+   Default value is “lcr_rule”.
 
-   Example 1.17. Setting lcr_table module parameter
+   Example 1.16. Setting lcr_rule_table module parameter
 ...
-modparam("lcr","lcr_table","lcr")
+modparam("lcr", "lcr_rule_table", "rules")
 ...
 
-3.18. prefix_column (string)
+3.17. prefix_column (string)
 
    Name of the column holding prefix of Request-URI user part.
 
    Default value is “prefix”.
 
-   Example 1.18. Setting prefix_column module parameter
+   Example 1.17. Setting prefix_column module parameter
 ...
-modparam("lcr","prefix_column","prefix")
+modparam("lcr", "prefix_column", "number_prefix")
 ...
 
-3.19. from_uri_column (string)
+3.18. from_uri_column (string)
 
-   Name of the column holding the FROM (source) URI.
+   Name of the column holding the From (caller's) URI.
 
    Default value is “from_uri”.
 
-   Example 1.19. Setting from_uri_column module parameter
+   Example 1.18. Setting from_uri_column module parameter
+...
+modparam("lcr", "from_uri_column", "caller_uri")
+...
+
+3.19. stopper_column (string)
+
+   Name of the column holding rule's stopper attribute.
+
+   Default value is “stopper”.
+
+   Example 1.19. Setting stopper_column module parameter
+...
+modparam("lcr", "stopper_column", "stop")
+...
+
+3.20. enabled_column (string)
+
+   Name of the column telling is the rule is currently enabled or
+   disabled.
+
+   Default value is “enabled”.
+
+   Example 1.20. Setting enabled_column module parameter
+...
+modparam("lcr", "enabled_column", "in_use")
+...
+
+3.21. lcr_rule_target_table (string)
+
+   Name of the table holding information about the LCR rule targets
+   (gateways).
+
+   Default value is “lcr_rule_target”.
+
+   Example 1.21. Setting lcr_rule_target_table module parameter
 ...
-modparam("lcr","from_uri_column","from_uri")
+modparam("lcr", "lcr_rule_target_table", "rules")
 ...
 
-3.20. priority_column (string)
+3.22. rule_id_column (string)
+
+   Name of lcr_rule_target_table column containing an id of lcr_rule
+   table.
+
+   Default value is “rule_id”.
+
+   Example 1.22. Setting rule_id_column module parameter
+...
+modparam("lcr", "rule_id_column", "rule")
+...
+
+3.23. gw_id_column (string)
+
+   Name of lcr_rule_target_table column containing an id of lcr_gw table.
 
-   Name of the column holding the priority of the rule.
+   Default value is “gw_id”.
+
+   Example 1.23. Setting gw_id_column module parameter
+...
+modparam("lcr", "gw_id_column", "gw")
+...
+
+3.24. priority_column (string)
+
+   Name of the column holding the priority of the rule target.
 
    Default value is “priority”.
 
-   Example 1.20. Setting priority_column module parameter
+   Example 1.24. Setting priority_column module parameter
+...
+modparam("lcr", "priority_column", "priority")
+...
+
+3.25. weight_column (string)
+
+   Name of the column holding weight of rule target.
+
+   Default value is “weight”.
+
+   Example 1.25. Setting weight_column module parameter
 ...
-modparam("lcr","priority_column","priority")
+modparam("lcr","weight_column", "target_weight")
 ...
 
-3.21. lcr_count (integer)
+3.26. lcr_count (integer)
 
    Number of LCR instances.
 
    Default value is 1.
 
-   Example 1.21.  Setting lcr_count module parameter
+   Example 1.26.  Setting lcr_count module parameter
 ...
 modparam("lcr", "lcr_count", 10)
 ...
 
-3.22. gw_uri_avp (AVP string)
+3.27. gw_uri_avp (AVP string)
 
    Internal AVP that load_gws() function uses to store information of
    matching gateways.
@@ -525,12 +614,12 @@ modparam("lcr", "lcr_count", 10)
    There is NO default value, thus this variable must be defined in
    sip-router.cfg.
 
-   Example 1.22. Setting gw_uri_avp module parameter
+   Example 1.27. Setting gw_uri_avp module parameter
 ...
 modparam("lcr", "gw_uri_avp", "$avp(i:709)")
 ...
 
-3.23. ruri_user_avp (AVP string)
+3.28. ruri_user_avp (AVP string)
 
    Internal AVP that next_gw function uses to store Request-URI user for
    subsequent next_gw calls.
@@ -538,12 +627,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.23. Setting ruri_user_avp module parameter
+   Example 1.28. Setting ruri_user_avp module parameter
 ...
 modparam("lcr", "ruri_user_avp", "$avp(i:500)")
 ...
 
-3.24. flags_avp (AVP string)
+3.29. flags_avp (AVP string)
 
    An AVP where successful next_gw and from_gw functions store gateway's
    flags.
@@ -551,24 +640,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.24. Setting flags_avp module parameter
+   Example 1.29. Setting flags_avp module parameter
 ...
 modparam("lcr", "flags_avp", "$avp(i:712)")
 ...
 
-3.25. defunct_capability (integer)
+3.30. 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.25.  Setting defunct_capability module parameter
+   Example 1.30.  Setting defunct_capability module parameter
 ...
 modparam("lcr", "defunct_capability", 1)
 ...
 
-3.26. lcr_id_avp (AVP string)
+3.31. 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
@@ -576,49 +665,71 @@ modparam("lcr", "defunct_capability", 1)
 
    There is NO default value.
 
-   Example 1.26. Setting lcr_id_avp module parameter
+   Example 1.31. Setting lcr_id_avp module parameter
 ...
 modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 ...
 
-3.27. defunct_gw_avp (AVP string)
+3.32. 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
-   gateway defunct capability has been activated.
+   Internal AVP that next_gw() function uses to store internal index of
+   the selected gateway for later use by defunct_gw() function. Only
+   needed if gateway defunct capability has been activated.
 
    There is NO default value.
 
-   Example 1.27. Setting defunct_gw_avp module parameter
+   Example 1.32. Setting defunct_gw_avp module parameter
 ...
 modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 ...
 
-3.28. lcr_hash_size (integer)
+3.33. lcr_rule_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
-   less collisions with other prefixes. Hash size value should be a power
-   of 2.
+   Defines the size of hash table used to store LCR rules. Hashing is done
+   based on rule's prefix. Larger value means less collisions with other
+   prefixes. Hash size value should be a power of 2.
 
    Default value is 128.
 
-   Example 1.28.  Setting lcr_hash_size module parameter
+   Example 1.33.  Setting lcr_rule_hash_size module parameter
+...
+modparam("lcr", "lcr_rule_hash_size", 1024)
+...
+
+3.34. lcr_gw_count (integer)
+
+   Defines the maximum number of gateways in lcr_gw table.
+
+   Default value is 128.
+
+   Example 1.34.  Setting lcr_gw_count module parameter
+...
+modparam("lcr", "lcr_gw_count", 1024)
+...
+
+3.35. dont_strip_or_tag (integer)
+
+   Defines the flag number used to tell if stripping and tagging is done
+   for the selected gateway.
+
+   Default value is -1 meaning that the flag is not defined.
+
+   Example 1.35.  Setting dont_strip_or_tag_flag module parameter
 ...
-modparam("lcr", "lcr_hash_size", 1024)
+modparam("lcr", "dont_strip_or_tag_flag", 10)
 ...
 
-3.29. fetch_rows (integer)
+3.36. 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
+   data from lcr_rule table. This value can be used to tune the load time
    at startup. For 1MB of private memory (default) it should be below
    3750. In order for this parameter to have effect, the database driver
    must support fetch_result() capability.
 
-   Default value is “2000”.
+   Default value is “1024”.
 
-   Example 1.29. Set fetch_rows parameter
+   Example 1.36. Set fetch_rows parameter
 ...
 modparam("lcr", "fetch_rows", 3000)
 ...
@@ -635,23 +746,22 @@ modparam("lcr", "fetch_rows", 3000)
 
 4.1.  load_gws(lcr_id[, caller_uri])
 
-   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. If caller_uri
-   argument is omitted, it defaults to empty string.
+   Loads attributes 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. If
+   caller_uri argument is omitted, it defaults to empty string.
 
    Returns 1 if at least one matching gateway was found, 2 if no matching
    gateways was found, and -1 on error.
 
    Execution time of load_gws() function is O(N) * O(M), where N is number
    of different prefix lengths and M is number of collisions for matching
-   prefix(es) in lcr hash table of the LCR instance.
+   prefix(es) in lcr rules hash table of the LCR instance.
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.30. load_gws usage
+   Example 1.37. load_gws usage
 ...
 if (!load_gws("1", "$var(caller_uri)")) {
         sl_send_reply("500", "Server Internal Error - Cannot load gateways");
@@ -661,14 +771,14 @@ if (!load_gws("1", "$var(caller_uri)")) {
 
 4.2.  next_gw()
 
-   Upon first call, fetches values stored in first gw_uri_avp, destroys
-   that AVP, and rewrites Request-URI and possibly also destination URI as
-   described in the Overview section. Saves user part of Request-URI into
-   ruri_user_avp for use in subsequent next_gw() calls.
+   Upon first call, fetches attribute values stored in first gw_uri_avp,
+   destroys that AVP, and rewrites Request-URI and possibly also
+   destination URI as described in the Overview section. Saves user part
+   of Request-URI into ruri_user_avp for use in subsequent next_gw()
+   calls.
 
-   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.
+   Upon subsequent calls, does the same as in above, but takes user part
+   of Request-URI from ruri_user_avp.
 
    As a side effect, stores gateway's flags to flags_avp.
 
@@ -679,7 +789,7 @@ if (!load_gws("1", "$var(caller_uri)")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.31. next_gw usage from a route block
+   Example 1.38. next_gw usage from a route block
 ...
 if (!next_gw()) {
         sl_send_reply("503", "Service not available - No gateways");
@@ -687,7 +797,7 @@ if (!next_gw()) {
 };
 ...
 
-   Example 1.32. next_gw usage from a failure route block
+   Example 1.39. next_gw usage from a failure route block
 ...
 if (!next_gw()) {
         t_reply("503", "Service not available - No more gateways");
@@ -706,7 +816,7 @@ if (!next_gw()) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.33. defunct_gw usage
+   Example 1.40. defunct_gw usage
 ...
 defunct_gw("60");
 ...
@@ -731,7 +841,7 @@ defunct_gw("60");
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.34. from_gw usage
+   Example 1.41. from_gw usage
 ...
 if (from_gw("1", "$avp(s:real_source_addr)") {
         ...
@@ -758,7 +868,7 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE.
 
-   Example 1.35. from_gw usage
+   Example 1.42. from_gw usage
 ...
 $var(lcr_id) = from_any_gw();
 ...
@@ -778,7 +888,7 @@ $var(lcr_id) = from_any_gw();
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.36. to_gw usage
+   Example 1.43. to_gw usage
 ...
 if (to_gw("1")) {
         ...
@@ -802,7 +912,7 @@ if (to_gw("1")) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.37. to_gw usage
+   Example 1.44. to_gw usage
 ...
 if (to_any_gw()) {
         ...
@@ -814,18 +924,17 @@ if (to_any_gw()) {
 
    5.1. lcr.reload
    5.2. lcr.dump_gws
-   5.3. lcr.dump_lcrs
+   5.3. lcr.dump_rules
 
 5.1. lcr.reload
 
-   Causes lcr module to re-read the contents of gw and lcr tables into
-   memory.
+   Causes lcr module to re-read the contents of LCR tables into memory.
 
    Name: lcr.reload
 
    Parameters: none
 
-   Example 1.38. lcr.reload RPC example
+   Example 1.45. lcr.reload RPC example
                 $ sercmd lcr.reload
 
 5.2. lcr.dump_gws
@@ -834,21 +943,22 @@ if (to_any_gw()) {
 
    Parameters: none
 
-   Example 1.39. lcr.dump_gws RPC example
+   Example 1.46. lcr.dump_gws RPC example
                 $ sercmd lcr.dump_gws
 
-5.3. lcr.dump_lcrs
+5.3. lcr.dump_rules
 
-   Causes lcr module to dump the contents of its in-memory lcr table.
+   Causes lcr module to dump the contents of its in-memory lcr_rule and
+   lcr_rule_target tables.
 
    Parameters: none
 
-   Example 1.40. lcr.dump_lcr RPC example
-                $ sercmd lcr.dump_lcrs
+   Example 1.47. lcr.dump_rules RPC example
+                $ sercmd lcr.dump_rules
 
 6. Known Limitations
 
-   In-memory gateway and in-memory lcr table are switched by two
-   consecutive machine instructions. If lcr reload process is interrupted
-   after the first one, in-memory gateway table does not match in-memory
-   lcr table until execution of lcr reload process is resumed.
+   In-memory LCR rules and gw tables are switched by two consecutive
+   machine instructions. If lcr reload process is interrupted after the
+   first one, in-memory gateway table does not match in-memory rule table
+   until execution of lcr reload process is resumed.

+ 297 - 126
modules/lcr/doc/lcr_admin.xml

@@ -28,17 +28,18 @@
 	</para>
 	<para>
 	For the purpose of facilitating least cost routing of requests,
-	each gateway of an LCR instance belongs to a gateway group and
-	each gateway group is associated with one or more 
-	&lt;prefix, from pattern, priority&gt;
-	tuples.  A gateway matches a request if	the user part of the Request-URI
+	each gateway of an LCR instance is associated with one or more 
+	&lt;prefix, from pattern, priority, weight&gt;
+	tuples.  A gateway matches a request if user part of the Request-URI
 	matches a "prefix" and the caller's URI matches a "from" pattern in a
-	tuple that belongs to the group of the gateway.
+	tuple that is associated with the gateway.
+	</para>
+	<para>
+	When the function <emphasis>load_gws()</emphasis> is called,
+	matching gateways (that are not currently designated as defunct)
+	are ordered for forwarding purposes as follows:
 	</para>
 	<para>
-	When the function <emphasis>load_gws()</emphasis> is called, matching gateways (that are
-	not currently designated as defunct) are ordered
-	for forwarding purposes in the following order:
 	<itemizedlist>
             <listitem>
                 <para>(1) according to longest user part match
@@ -49,25 +50,33 @@
                 </para>
             </listitem>
             <listitem>
-                <para>(3) gateway's randomized weight within its group
+                <para>(3) according to tuple's randomized weight
                 </para>
             </listitem>
         </itemizedlist>
+	</para>
+	<para>
+	A tuple can be marked as a "stopper" tuple.  If a "stopper"
+	tuple matches, then matching stops at it and all other tuples
+	with shorter prefixes are not considered.
+	</para>
+	<para>
 	Prefix is a string of characters or NULL.  From
 	pattern is a regular expression (see 'man 
 	pcresyntax' for syntax), an empty string, or NULL.  An empty or
-	NULL from pattern or prefix matches anything. 
+	NULL from pattern or prefix matches anything.
 	Smaller priority value means higher priority (highest priority
-	value being 0).  Weight is an integer value from 1 to 254.
+	value being 0 and lowest being 255).  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  
+	time for forwarding.  Upon each call, unless "dont_strip_of_tag"
+	flag is set, 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
+	the gateway's tag.  Upon each call, if a gateway's hostname is
 	NULL, Request-URI will be  
 	rewritten based on gateway's URI scheme, IP address, port,
 	parameters, and transport protocol.  If hostname is not NULL and
@@ -78,9 +87,7 @@
 	rewritten based on 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. 
+	protocol.
 	</para>
         <para>
         Valid URI scheme values are NULL = sip, 1 = sip and 2
@@ -88,8 +95,8 @@
 	none, 1 = udp, 2 = tcp, 3 = tls, and 4 = sctp.
 	</para>
 	<para>
-	As a side effect of the gateway selection, the gateway's flags (that may
-	contain information about capabilities of the gateway)
+	As a side effect of gateway selection, selected gateway's flags
+	(that may contain information about capabilities of the gateway)
 	are stored into an AVP.
 	</para>
 	</section>
@@ -102,11 +109,6 @@
 		The following modules must be loaded before this module:
 		<itemizedlist>
 		<listitem>
-		<para>
-			<emphasis>TM module</emphasis>
-		</para>
-		</listitem>
-		<listitem>
 		<para>
 			<emphasis>A database module like mysql, postgres or 
 			dbtext</emphasis>.
@@ -155,81 +157,85 @@ modparam("lcr","db_url","&exampledb;")
 	</section>
 
 	<section>
-		<title><varname>gw_table</varname> (string)</title>
+		<title><varname>lcr_gw_table</varname> (string)</title>
 		<para>
 		Name of the table holding gateways definitions.
 		</para>
 		<para>
 		<emphasis>
-			Default value is <quote>gw</quote>.
+			Default value is <quote>lcr_gw</quote>.
 		</emphasis>
 		</para>
 		<example>
 		<title>Setting <varname>gw_table</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","gw_table","gw")
+modparam("lcr", "lcr_gw_table","gw")
 ...
 </programlisting>
 		</example>
 	</section>
 
 	<section>
-		<title><varname>lcr_id_column</varname> (string)</title>
+		<title><varname>id_column</varname> (string)</title>
 		<para>
-		Name of the column holding the identifier of an LCR instance.  Common to both gw and lcr tables.
+		Name of the auto-increment, primary key column.  Common
+		to all lcr module tables.
 		</para>
 		<para>
 		<emphasis>
-			Default value is <quote>lcr_id</quote>.
+			Default value is <quote>id</quote>.
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>lcr_id_column</varname> module parameter</title>
+		<title>Setting <varname>id_column</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
-modparam("lcr", "lcr_id_column", "lcr_identifier")
+modparam("lcr", "id_column", "row_id")
 ...
 </programlisting>
 		</example>
 	</section>
 
 	<section>
-		<title><varname>gw_name_column</varname> (string)</title>
+		<title><varname>lcr_id_column</varname> (string)</title>
 		<para>
-		Name of the column holding the gateway name.
+		Name of the column holding the identifier of an LCR
+		instance.  Common to all lcr module tables.
 		</para>
 		<para>
 		<emphasis>
-			Default value is <quote>gw_name</quote>.
+			Default value is <quote>lcr_id</quote>.
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>gw_name_column</varname> module parameter</title>
+		<title>Setting <varname>lcr_id_column</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
-modparam("lcr","gw_name_column","gw_name")
+modparam("lcr", "lcr_id_column", "lcr_identifier")
 ...
 </programlisting>
 		</example>
 	</section>
 
 	<section>
-		<title><varname>grp_id_column</varname> (string)</title>
+		<title><varname>gw_name_column</varname> (string)</title>
 		<para>
-		Name of the column holding the group ID of gateway both
-		in gw and lcr tables.
+		Name of the column holding gateway's name for
+		documentation purpose.
 		</para>
 		<para>
 		<emphasis>
-			Default value is <quote>grp_id</quote>.
+			Default value is <quote>gw_name</quote>.
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>grp_id_column</varname> module parameter</title>
+		<title>Setting <varname>gw_name_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","grp_id_column","grp_id")
+modparam("lcr", "gw_name_column", "name")
 ...
 </programlisting>
 		</example>
@@ -246,10 +252,11 @@ modparam("lcr","grp_id_column","grp_id")
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>ip_addr_column</varname> module parameter</title>
+		<title>Setting <varname>ip_addr_column</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
-modparam("lcr","ip_addr_column","ip_addr")
+modparam("lcr", "ip_addr_column", "ip")
 ...
 </programlisting>
 		</example>
@@ -259,7 +266,7 @@ modparam("lcr","ip_addr_column","ip_addr")
 		<title><varname>hostname_column</varname> (string)</title>
 		<para>
 		Name of the column holding gateway's hostname that is
-		used in Request-URI, when request is sent to the
+		used in Request-URI hostpart, when request is sent to the
 		gateway.
 		</para>
 		<para>
@@ -271,7 +278,7 @@ modparam("lcr","ip_addr_column","ip_addr")
 		<title>Setting <varname>hostname_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr", "hostname_column","hostname")
+modparam("lcr", "hostname_column", "host")
 ...
 </programlisting>
 		</example>
@@ -291,7 +298,7 @@ modparam("lcr", "hostname_column","hostname")
 		<title>Setting <varname>port_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","port_column","port")
+modparam("lcr", "port_column", "port")
 ...
 </programlisting>
 		</example>
@@ -313,7 +320,7 @@ modparam("lcr","port_column","port")
 		<title>Setting <varname>params_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr", "params_column","parameters")
+modparam("lcr", "params_column", "parameters")
 ...
 </programlisting>
 		</example>
@@ -334,7 +341,7 @@ modparam("lcr", "params_column","parameters")
 		parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","uri_scheme_column","uri_scheme")
+modparam("lcr", "uri_scheme_column", "uri_scheme")
 ...
 </programlisting>
 		</example>
@@ -343,8 +350,8 @@ modparam("lcr","uri_scheme_column","uri_scheme")
 	<section>
 		<title><varname>transport_column</varname> (string)</title>
 		<para>
-		Name of the column holding the transport type to be used for 
-		the gateway.
+		Name of the column holding the transport protocol to be
+		used for the gateway.
 		</para>
 		<para>
 		<emphasis>
@@ -356,7 +363,7 @@ modparam("lcr","uri_scheme_column","uri_scheme")
 		parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","transport_column","transport")
+modparam("lcr", "transport_column", "trans")
 ...
 </programlisting>
 		</example>
@@ -379,7 +386,7 @@ modparam("lcr","transport_column","transport")
 		parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","strip_column","strip_count")
+modparam("lcr", "strip_column", "strip_count")
 ...
 </programlisting>
 		</example>
@@ -388,7 +395,8 @@ modparam("lcr","strip_column","strip_count")
 	<section>
 		<title><varname>tag_column</varname> (string)</title>
 		<para>
-		Name of the column holding gateway specific tag string.
+		Name of the column holding gateway specific tag string
+		that is added to Request URI userpart after stripping.
 		</para>
 		<para>
 		<emphasis>
@@ -399,27 +407,7 @@ modparam("lcr","strip_column","strip_count")
 		<title>Setting <varname>tag_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","tag_column","gw_tag")
-...
-</programlisting>
-		</example>
-	</section>
-
-	<section>
-		<title><varname>weight_column</varname> (string)</title>
-		<para>
-		Name of the column holding gateway's weight within its group.
-		</para>
-		<para>
-		<emphasis>
-			Default value is <quote>weight</quote>.
-		</emphasis>
-		</para>
-		<example>
-		<title>Setting <varname>weight_column</varname> module parameter</title>
-		<programlisting format="linespecific">
-...
-modparam("lcr","weight_column","gw_weight")
+modparam("lcr", "tag_column", "gw_tag")
 ...
 </programlisting>
 		</example>
@@ -439,7 +427,7 @@ modparam("lcr","weight_column","gw_weight")
 		<title>Setting <varname>flags_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","flags_column","gw_flags")
+modparam("lcr", "flags_column", "gw_flags")
 ...
 </programlisting>
 		</example>
@@ -460,27 +448,27 @@ modparam("lcr","flags_column","gw_flags")
 		<title>Setting <varname>defunct_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","defunct_column","defunct_until")
+modparam("lcr", "defunct_column", "defunct_until")
 ...
 </programlisting>
 		</example>
 	</section>
 
 	<section>
-		<title><varname>lcr_table</varname> (string)</title>
+		<title><varname>lcr_rule_table</varname> (string)</title>
 		<para>
 		Name of the table holding the LCR rules.
 		</para>
 		<para>
 		<emphasis>
-			Default value is <quote>lcr</quote>.
+			Default value is <quote>lcr_rule</quote>.
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>lcr_table</varname> module parameter</title>
+		<title>Setting <varname>lcr_rule_table</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","lcr_table","lcr")
+modparam("lcr", "lcr_rule_table", "rules")
 ...
 </programlisting>
 		</example>
@@ -498,10 +486,11 @@ modparam("lcr","lcr_table","lcr")
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>prefix_column</varname> module parameter</title>
+		<title>Setting <varname>prefix_column</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
-modparam("lcr","prefix_column","prefix")
+modparam("lcr", "prefix_column", "number_prefix")
 ...
 </programlisting>
 		</example>
@@ -510,7 +499,7 @@ modparam("lcr","prefix_column","prefix")
 	<section>
 		<title><varname>from_uri_column</varname> (string)</title>
 		<para>
-		Name of the column holding the FROM (source) URI.
+		Name of the column holding the From (caller's) URI.
 		</para>
 		<para>
 		<emphasis>
@@ -521,7 +510,120 @@ modparam("lcr","prefix_column","prefix")
 		<title>Setting <varname>from_uri_column</varname> module parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr","from_uri_column","from_uri")
+modparam("lcr", "from_uri_column", "caller_uri")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>stopper_column</varname> (string)</title>
+		<para>
+		Name of the column holding rule's stopper attribute.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>stopper</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>stopper_column</varname> module
+		parameter 
+			</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "stopper_column", "stop")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>enabled_column</varname> (string)</title>
+		<para>
+		Name of the column telling is the rule is currently
+		enabled or disabled.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>enabled</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>enabled_column</varname> module
+		parameter
+		</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "enabled_column", "in_use")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>lcr_rule_target_table</varname> (string)</title>
+		<para>
+		Name of the table holding information about the LCR rule
+		targets (gateways).
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>lcr_rule_target</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>lcr_rule_target_table</varname>
+		module parameter</title> 
+		<programlisting format="linespecific">
+...
+modparam("lcr", "lcr_rule_target_table", "rules")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>rule_id_column</varname> (string)</title>
+		<para>
+		Name of lcr_rule_target_table column containing an id of
+		lcr_rule table.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>rule_id</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>rule_id_column</varname> module
+		parameter 
+			</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "rule_id_column", "rule")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>gw_id_column</varname> (string)</title>
+		<para>
+		Name of lcr_rule_target_table column containing an id of
+		lcr_gw table.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>gw_id</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>gw_id_column</varname> module
+		parameter 
+			</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "gw_id_column", "gw")
 ...
 </programlisting>
 		</example>
@@ -530,7 +632,8 @@ modparam("lcr","from_uri_column","from_uri")
 	<section>
 		<title><varname>priority_column</varname> (string)</title>
 		<para>
-		Name of the column holding the priority of the rule.
+		Name of the column holding the priority of the rule
+		target.
 		</para>
 		<para>
 		<emphasis>
@@ -538,11 +641,32 @@ modparam("lcr","from_uri_column","from_uri")
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>priority_column</varname> module parameter
-			</title>
+		<title>Setting <varname>priority_column</varname> module
+		parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "priority_column", "priority")
+...
+</programlisting>
+		</example>
+	</section>
+
+	<section>
+		<title><varname>weight_column</varname> (string)</title>
+		<para>
+		Name of the column holding weight of rule target.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>weight</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Setting <varname>weight_column</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
-modparam("lcr","priority_column","priority")
+modparam("lcr","weight_column", "target_weight")
 ...
 </programlisting>
 		</example>
@@ -584,7 +708,8 @@ modparam("lcr", "lcr_count", 10)
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>gw_uri_avp</varname> module parameter</title>
+		<title>Setting <varname>gw_uri_avp</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
 modparam("lcr", "gw_uri_avp", "$avp(i:709)")
@@ -674,7 +799,8 @@ modparam("lcr", "defunct_capability", 1)
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>lcr_id_avp</varname> module parameter</title>
+		<title>Setting <varname>lcr_id_avp</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
 modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
@@ -686,8 +812,8 @@ modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 	<section>
 		<title><varname>defunct_gw_avp</varname> (AVP string)</title>
 		<para>
-		Internal AVP that next_gw() function uses to store IP
-		address of the  
+		Internal AVP that next_gw() function uses to store
+		internal index of the  
 		selected gateway for later use by defunct_gw() function.
 		Only needed if 
 		gateway defunct capability has been activated.
@@ -698,7 +824,8 @@ modparam("lcr", "lcr_id_avp", "$avp(s:lcr_id_avp)")
 		</emphasis>
 		</para>
 		<example>
-		<title>Setting <varname>defunct_gw_avp</varname> module parameter</title>
+		<title>Setting <varname>defunct_gw_avp</varname> module
+		parameter</title> 
 		<programlisting format="linespecific">
 ...
 modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
@@ -708,13 +835,35 @@ modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 	</section>
 
 	<section>
-		<title><varname>lcr_hash_size</varname> (integer)</title>
+		<title><varname>lcr_rule_hash_size</varname> (integer)</title>
+		<para>
+		Defines the size of hash table used to store LCR rules.
+		Hashing is done based on rule's prefix.  Larger value means
+		less collisions with other prefixes.  Hash size value
+		should be a power of 2.
+		</para>
+		<para>
+		<emphasis>
+			Default value is 128.
+		</emphasis>
+		</para>
+		<example>
+		<title>
+		Setting <varname>lcr_rule_hash_size</varname> module
+		parameter
+		</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "lcr_rule_hash_size", 1024)
+...
+</programlisting>
+                </example>
+	</section>
+
+	<section>
+		<title><varname>lcr_gw_count</varname> (integer)</title>
 		<para>
-		Defines the size of hash table used to store &lt;prefix,
-		from_pattern, priority&gt; tuples.  Hashing is done based
-		on prefix.  Larger value means less collisions with
-		other prefixes.  Hash size value should be a power of
-		2.
+		Defines the maximum number of gateways in lcr_gw table.
 		</para>
 		<para>
 		<emphasis>
@@ -723,12 +872,36 @@ modparam("lcr", "defunct_gw_avp", "$avp(s:defunct_gw_avp)")
 		</para>
 		<example>
 		<title>
-		Setting <varname>lcr_hash_size</varname> module
+		Setting <varname>lcr_gw_count</varname> module parameter
+		</title>
+		<programlisting format="linespecific">
+...
+modparam("lcr", "lcr_gw_count", 1024)
+...
+</programlisting>
+                </example>
+	</section>
+
+	<section>
+		<title><varname>dont_strip_or_tag</varname> (integer)</title>
+		<para>
+		Defines the flag number used to tell if stripping and
+		tagging is done for the selected gateway.
+		</para>
+		<para>
+		<emphasis>
+			Default value is -1 meaning that the flag is not
+		defined.
+		</emphasis>
+		</para>
+		<example>
+		<title>
+		Setting <varname>dont_strip_or_tag_flag</varname> module
 		parameter
 		</title>
 		<programlisting format="linespecific">
 ...
-modparam("lcr", "lcr_hash_size", 1024)
+modparam("lcr", "dont_strip_or_tag_flag", 10)
 ...
 </programlisting>
                 </example>
@@ -738,7 +911,8 @@ modparam("lcr", "lcr_hash_size", 1024)
 		<title><varname>fetch_rows</varname> (integer)</title>
 		<para>
 		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
+		when loading data from lcr_rule table. This value can be
+		used to tune 
 		the load time at startup.  For 1MB of private memory (default)
 		it should be below 3750. In order for this parameter to
 		have effect, the database driver must support fetch_result()
@@ -746,7 +920,7 @@ modparam("lcr", "lcr_hash_size", 1024)
 		</para>
 		<para>
 		<emphasis>
-			Default value is <quote>2000</quote>.
+			Default value is <quote>1024</quote>.
 		</emphasis>
 		</para>
 		<example>
@@ -765,12 +939,11 @@ modparam("lcr", "fetch_rows", 3000)
 	<title>Exported Functions</title>
 	<section>
 		<title>
-		<function moreinfo="none">load_gws(lcr_id[, caller_uri])</function>
+		<function moreinfo="none">load_gws(lcr_id[, caller_uri])
+		</function> 
 		</title>
 		<para>
-		Loads URI schemes, IP addresses, hostnames, ports,
-		params, and
-		transports of matching gateways to gw_uri_avp
+		Loads attributes 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. 
@@ -780,13 +953,13 @@ modparam("lcr", "fetch_rows", 3000)
 		</para>
 		<para>
 		Returns 1 if at least one matching gateway was found, 2
-	if no matching gateways was found, and -1 on error.
+		if no matching gateways was found, and -1 on error.
 		</para>
 		<para>
 		Execution time of load_gws() function is O(N) * O(M),
 		where N is number of different prefix lengths and M
 		is number of collisions for matching prefix(es) in lcr
-		hash table of the LCR instance.
+		rules hash table of the LCR instance.
 		</para>
 		<para>
 		This function can be used from REQUEST_ROUTE.
@@ -809,7 +982,7 @@ if (!load_gws("1", "$var(caller_uri)")) {
 		<function moreinfo="none">next_gw()</function>
 		</title>	
 		<para>
-		Upon first call, fetches values stored in first
+		Upon first call, fetches attribute values stored in first
 		gw_uri_avp, destroys that AVP, and rewrites
 		Request-URI and possibly also destination URI as
 		described in the Overview section. Saves user part of
@@ -818,8 +991,7 @@ if (!load_gws("1", "$var(caller_uri)")) {
 		</para>
 		<para>
 		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.
+		takes user part of Request-URI from ruri_user_avp.
 		</para>
 		<para>
 		As a side effect, stores gateway's flags to flags_avp.
@@ -942,13 +1114,12 @@ if (from_gw("1", "$avp(s:real_source_addr)") {
 		</para>
 		<para>
 		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. 
+		identifier of the gateway.  Returns -1 on error or if
+		the request does not come from a gateway. 
 		</para>
 		<para>
-		If request comes from a gateway, the gateway's flags are stored into flags_avp
-		as side effect.
+		If request comes from a gateway, the gateway's flags are
+		stored into flags_avp as side effect.
 		</para>
 		<para>
 		Execution time of from_gw() function is M * O(log N),
@@ -1050,7 +1221,7 @@ if (to_any_gw()) {
 		<title><function>lcr.reload</function></title>
 		<para>
 			Causes lcr module to re-read the contents of
-			gw and lcr tables into memory.
+			LCR tables into memory.
 		</para>
 		<para>
 		Name: <emphasis>lcr.reload</emphasis>
@@ -1080,16 +1251,16 @@ if (to_any_gw()) {
 		</section>
 		
 		<section>
-		<title><function>lcr.dump_lcrs</function></title>
+		<title><function>lcr.dump_rules</function></title>
 		<para>
 			Causes lcr module to dump the contents of its
-			in-memory lcr table.
+			in-memory lcr_rule and lcr_rule_target tables.
 		</para>
 		<para>Parameters: <emphasis>none</emphasis></para>
  		<example>
-		<title><function>lcr.dump_lcr</function> RPC example</title>
+		<title><function>lcr.dump_rules</function> RPC example</title>
         <programlisting  format="linespecific">
-		$ sercmd lcr.dump_lcrs
+		$ sercmd lcr.dump_rules
 		</programlisting>
 		</example>
 		</section>
@@ -1097,10 +1268,10 @@ if (to_any_gw()) {
 	<section>
 	<title>Known Limitations</title>
 	<para>
-		In-memory gateway and in-memory lcr table are switched
+		In-memory LCR rules and gw tables are switched
 		by two consecutive machine instructions. If lcr reload
 		process is interrupted after the first one, in-memory
-		gateway table does not match in-memory lcr table until
+		gateway table does not match in-memory rule table until
 		execution of lcr reload process is resumed.
 	</para>
 	</section>

+ 119 - 49
modules/lcr/hash.c

@@ -3,14 +3,14 @@
  *
  * Copyright (C) 2008-2009 Juha Heinanen
  *
- * This file is part of SIP-router, a free SIP server.
+ * This file is part of SIP Router, a free SIP server.
  *
- * SIP-router is free software; you can redistribute it and/or modify
+ * SIP Router is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
- * SIP-router is distributed in the hope that it will be useful,
+ * SIP Router is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -22,7 +22,7 @@
 
 /*!
  * \file
- * \brief SIP-router LCR :: Header file for hash table functions
+ * \brief SIP Router LCR :: Header file for hash table functions
  * \ingroup lcr
  * Module: \ref lcr
  */
@@ -31,52 +31,116 @@
 #include "../../lib/kcore/hash_func.h"
 #include "lcr_mod.h"
 
-#define lcr_hash(_s) core_hash( _s, 0, lcr_hash_size_param)
+#define rule_hash(_s) core_hash(_s, 0, lcr_rule_hash_size_param)
 
 /* Add lcr entry into hash table */
-int lcr_hash_table_insert(struct lcr_info **hash_table,
-			  unsigned short prefix_len, char *prefix,
-			  unsigned short from_uri_len, char *from_uri,
-			  pcre *from_uri_re, unsigned int grp_id,
-			  unsigned short first_gw, unsigned short priority)
+int rule_hash_table_insert(struct rule_info **hash_table,
+			   unsigned int lcr_id, unsigned int rule_id,
+			   unsigned short prefix_len, char *prefix,
+			   unsigned short from_uri_len, char *from_uri,
+			   pcre *from_uri_re, unsigned short stopper)
 {
-    struct lcr_info *lcr;
+    struct rule_info *rule;
     str prefix_str;
     unsigned int hash_val;
 
-    lcr = (struct lcr_info *)shm_malloc(sizeof(struct lcr_info));
-    if (lcr == NULL) {
-	LM_ERR("Cannot allocate memory for lcr hash table entry\n");
+    rule = (struct rule_info *)shm_malloc(sizeof(struct rule_info));
+    if (rule == NULL) {
+	LM_ERR("Cannot allocate memory for rule hash table entry\n");
+	if (from_uri_re) shm_free(from_uri_re);
 	return 0;
     }
-    memset(lcr, 0, sizeof(struct lcr_info));
+    memset(rule, 0, sizeof(struct rule_info));
 
-    lcr->prefix_len = prefix_len;
+    rule->rule_id = rule_id;
+    rule->prefix_len = prefix_len;
     if (prefix_len) {
-	memcpy(lcr->prefix, prefix, prefix_len);
+	memcpy(rule->prefix, prefix, prefix_len);
     }
-    lcr->from_uri_len = from_uri_len;
+    rule->from_uri_len = from_uri_len;
     if (from_uri_len) {
-	memcpy(lcr->from_uri, from_uri, from_uri_len);
-	(lcr->from_uri)[from_uri_len] = '\0';
-	lcr->from_uri_re = from_uri_re;
+	memcpy(rule->from_uri, from_uri, from_uri_len);
+	(rule->from_uri)[from_uri_len] = '\0';
+	rule->from_uri_re = from_uri_re;
     }
-    lcr->grp_id = grp_id;
-    lcr->first_gw = first_gw;
-    lcr->priority = priority;
-    
-    prefix_str.len = lcr->prefix_len;
-    prefix_str.s = lcr->prefix;
+    rule->stopper = stopper;
+    rule->targets = (struct target *)NULL;
+
+    prefix_str.len = rule->prefix_len;
+    prefix_str.s = rule->prefix;
 
-    hash_val = lcr_hash(&prefix_str);
-    lcr->next = hash_table[hash_val];
-    hash_table[hash_val] = lcr;
+    hash_val = rule_hash(&prefix_str);
+    rule->next = hash_table[hash_val];
+    hash_table[hash_val] = rule;
     
-    LM_DBG("inserted prefix <%.*s>, from_uri <%.*s>, grp_id <%u>, "
-	   "priority <%u> into index <%u>\n",
-	   prefix_len, prefix, from_uri_len, from_uri, grp_id,
-	   priority, hash_val);
+    LM_DBG("inserted rule <%u>, prefix <%.*s>, from_uri <%.*s>, stopper <%u>, "
+	   "into index <%u>\n",
+	   rule_id, prefix_len, prefix, from_uri_len, from_uri, stopper,
+	   hash_val);
+
+    return 1;
+}
+
+
+/* Find gw table index with gw_id */
+int get_gw_index(struct gw_info *gws, unsigned int gw_id,
+		 unsigned short *gw_index)
+{
+    unsigned short gw_count, i;
+
+    gw_count = gws[0].ip_addr;
+
+    for (i = 1; i <= gw_count; i++) {
+	if (gws[i].gw_id == gw_id) {
+	    *gw_index = i;
+	    return 1;
+	}
+    }
+    return 0;
+}
+
 
+/* Insert target into hash table rule */
+int rule_hash_table_insert_target(struct rule_info **hash_table,
+				   struct gw_info *gws,
+				   unsigned int rule_id, unsigned int gw_id,
+				   unsigned int priority, unsigned int weight)
+{
+    unsigned int i;
+    unsigned short gw_index;
+    struct rule_info *r;
+    struct target *target;
+
+    target = (struct target *)shm_malloc(sizeof(struct target));
+    if (target == NULL) {
+	LM_ERR("cannot allocate memory for rule target\n");
+	return 0;
+    }
+
+    if (get_gw_index(gws, gw_id, &gw_index) == 0) {
+	LM_ERR("could not find gw with id <%u>\n", gw_id);
+	shm_free(target);
+	return 0;
+    }
+
+    target->gw_index = gw_index;
+    target->priority = priority;
+    target->weight = weight;
+	
+    for (i = 0; i < lcr_rule_hash_size_param; i++) {
+	r = hash_table[i];
+	while (r) {
+	    if (r->rule_id == rule_id) {
+		target->next = r->targets;
+		r->targets = target;
+		return 1;
+	    }
+	    r = r->next;
+	}
+    }
+
+    LM_DBG("could not find (disabled) rule with id <%u>\n", rule_id);
+    shm_free(target);
     return 1;
 }
 
@@ -84,38 +148,44 @@ int lcr_hash_table_insert(struct lcr_info **hash_table,
 /* 
  * Return pointer to lcr hash table entry to which given prefix hashes to.
  */
-struct lcr_info *lcr_hash_table_lookup(struct lcr_info **hash_table,
-				       unsigned short prefix_len, char *prefix)
+struct rule_info *rule_hash_table_lookup(struct rule_info **hash_table,
+					 unsigned short prefix_len,
+					 char *prefix)
 {
     str prefix_str;
 
     prefix_str.len = prefix_len;
     prefix_str.s = prefix;
 
-    return (hash_table)[lcr_hash(&prefix_str)];
+    return (hash_table)[rule_hash(&prefix_str)];
 }
 
 
 /* Free contents of lcr hash table */
-void lcr_hash_table_contents_free(struct lcr_info **hash_table)
+void rule_hash_table_contents_free(struct rule_info **hash_table)
 {
     int i;
-    struct lcr_info *lcr_rec, *next;
+    struct rule_info *r, *next_r;
+    struct target *t, *next_t;
 	
     if (hash_table == 0)
 	return;
 
-    for (i = 0; i <= lcr_hash_size_param; i++) {
-	lcr_rec = hash_table[i];
-	while (lcr_rec) {
-	    LM_DBG("freeing lcr hash table prefix <%.*s> grp_id <%u>\n",
-		   lcr_rec->prefix_len, lcr_rec->prefix, lcr_rec->grp_id);
-	    if (lcr_rec->from_uri_re) {
-		shm_free(lcr_rec->from_uri_re);
+    for (i = 0; i <= lcr_rule_hash_size_param; i++) {
+	r = hash_table[i];
+	while (r) {
+	    if (r->from_uri_re) {
+		shm_free(r->from_uri_re);
+	    }
+	    t = r->targets;
+	    while (t) {
+		next_t = t->next;
+		shm_free(t);
+		t = next_t;
 	    }
-	    next = lcr_rec->next;
-	    shm_free(lcr_rec);
-	    lcr_rec = next;
+	    next_r = r->next;
+	    shm_free(r);
+	    r = next_r;
 	}
 	hash_table[i] = NULL;
     }

+ 18 - 12
modules/lcr/hash.h

@@ -1,16 +1,16 @@
 /*
  * Header file for hash table functions
  *
- * Copyright (C) 2008 Juha Heinanen
+ * Copyright (C) 2008-2010 Juha Heinanen
  *
- * This file is part of Kamailio, a free SIP server.
+ * This file is part of SIP Router, a free SIP server.
  *
- * Kamailio is free software; you can redistribute it and/or modify
+ * SIP Router is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
- * Kamailio is distributed in the hope that it will be useful,
+ * SIP Router is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -32,15 +32,21 @@
 
 #include "lcr_mod.h"
 
-int lcr_hash_table_insert(struct lcr_info **hash_table,
-			  unsigned short prefix_len, char *prefix,
-			  unsigned short from_uri_len, char *from_uri,
-			  pcre *from_uri_re, unsigned int grp_id,
-			  unsigned short first_gw, unsigned short priority);
+int rule_hash_table_insert(struct rule_info **hash_table,
+			   unsigned int lcr_id, unsigned int rule_id,
+			   unsigned short prefix_len, char *prefix,
+			   unsigned short from_uri_len, char *from_uri,
+			   pcre *from_uri_re, unsigned short stopper);
 
-struct lcr_info *lcr_hash_table_lookup(struct lcr_info **hash_table,
-				       unsigned short prefix_len, char *prefix);
+int rule_hash_table_insert_target(struct rule_info **hash_table,
+				  struct gw_info *gws,
+				  unsigned int rule_id, unsigned int gw_id,
+				  unsigned int priority, unsigned int weight);
 
-void lcr_hash_table_contents_free(struct lcr_info **hash_table);
+struct rule_info *rule_hash_table_lookup(struct rule_info **hash_table,
+					 unsigned short prefix_len,
+					 char *prefix);
+
+void rule_hash_table_contents_free(struct rule_info **hash_table);
 
 #endif

File diff suppressed because it is too large
+ 694 - 592
modules/lcr/lcr_mod.c


+ 35 - 21
modules/lcr/lcr_mod.h

@@ -1,18 +1,18 @@
 /*
  * $Id$
  *
- * Various lcr related functions
+ * Various lcr related constant, types, and external variables
  *
- * Copyright (C) 2005-2008 Juha Heinanen
+ * Copyright (C) 2005-2010 Juha Heinanen
  *
- * This file is part of Kamailio, a free SIP server.
+ * This file is part of SIP Router, a free SIP server.
  *
- * Kamailio is free software; you can redistribute it and/or modify
+ * SIP Router is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
- * Kamailio is distributed in the hope that it will be useful,
+ * SIP Router is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -28,7 +28,7 @@
 
 /*!
  * \file
- * \brief SIP-router lcr :: Various LCR related functions
+ * \brief SIP-router lcr :: Various LCR related constant, types, and external variables
  * \ingroup lcr
  * Module: \ref lcr
  */
@@ -47,54 +47,68 @@
 #define MAX_URI_LEN 256
 #define MAX_HOST_LEN 64
 #define MAX_NO_OF_GWS 128
+#define MAX_NAME_LEN 128
 #define MAX_TAG_LEN 16
 #define MAX_USER_LEN 64
 #define MAX_PARAMS_LEN 64
 
-struct lcr_info {
+typedef enum sip_protos uri_transport;
+
+struct rule_info {
+    unsigned int rule_id;
     char prefix[MAX_PREFIX_LEN + 1];
     unsigned short prefix_len;
     char from_uri[MAX_URI_LEN + 1];
     unsigned short from_uri_len;
     pcre *from_uri_re;
-    unsigned int grp_id;
-    unsigned short first_gw;  /* gw table index of first gw in gw's group */
+    unsigned short stopper;
+    unsigned int enabled;
+    struct target *targets;
+    struct rule_info *next;
+};
+
+struct target {
+    unsigned short gw_index;
     unsigned short priority;
-    struct lcr_info *next;
+    unsigned short weight;
+    struct target *next;
 };
 
-typedef enum sip_protos uri_transport;
+struct instance {
+    unsigned short instance_id;
+    struct instance *next;
+};
 
 struct gw_info {
+    unsigned int gw_id;
+    char gw_name[MAX_NAME_LEN];
+    unsigned short gw_name_len;
+    uri_type scheme;
     unsigned int ip_addr;
     char hostname[MAX_HOST_LEN];
     unsigned short hostname_len;
     unsigned int port;
+    uri_transport transport;
     char params[MAX_PARAMS_LEN];
     unsigned short params_len;
-    unsigned int grp_id;
-    uri_type scheme;
-    uri_transport transport;
     unsigned int strip;
     char tag[MAX_TAG_LEN + 1];
     unsigned short tag_len;
-    unsigned short weight;
     unsigned int flags;
     unsigned int defunct_until;
-    unsigned int next;  /* index of next gw in the same group */
 };
 
-extern unsigned int lcr_hash_size_param;
+extern unsigned int lcr_rule_hash_size_param;
 
-extern unsigned int lcr_count;
+extern unsigned int lcr_count_param;
 
 extern gen_lock_t *reload_lock;
 
-extern struct gw_info **gwtp;
-extern struct lcr_info ***lcrtp;
+extern struct gw_info **gw_pt;
+extern struct rule_info ***rule_pt;
 
 int  mi_print_gws(struct mi_node* rpl);
 int  mi_print_lcrs(struct mi_node* rpl);
-int  reload_gws_and_lcrs(int id);
+int  reload_tables();
 
 #endif /* LCR_MOD_H */

+ 123 - 112
modules/lcr/lcr_rpc.c

@@ -3,19 +3,19 @@
  *
  * Copyright (C) 2009-2010 Juha Heinanen
  *
- * This file is part of ser, a free SIP server.
+ * This file is part of SIP Router, a free SIP server.
  *
- * ser is free software; you can redistribute it and/or modify
+ * SIP Router is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
- * For a license to use the ser software under conditions
+ * For a license to use the SIP Router software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    [email protected]
  *
- * ser is distributed in the hope that it will be useful,
+ * SIP Router is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -39,144 +39,155 @@
 
 
 static const char* reload_doc[2] = {
-	"Reload gw and lcr tables from database.",
-	0
+    "Reload lcr tables from database.",
+    0
 };
 
 
 static void reload(rpc_t* rpc, void* c)
 {
-        int i;
-	lock_get(reload_lock);
-	for (i = 1; i <= lcr_count; i++) {
-	        if (reload_gws_and_lcrs(i) != 1)
-		        rpc->fault(c, 500, "LCR Module Reload Failed");
-	}
-	lock_release(reload_lock);
+    int i;
+    lock_get(reload_lock);
+    for (i = 1; i <= lcr_count_param; i++) {
+	if (reload_tables(i) != 1)
+	    rpc->fault(c, 500, "LCR Module Reload Failed");
+    }
+    lock_release(reload_lock);
 }
 
 
 static const char* dump_gws_doc[2] = {
-	"Dump the contents of the gw table.",
-	0
+    "Dump the contents of lcr_gws table.",
+    0
 };
 
 
 static void dump_gws(rpc_t* rpc, void* c)
 {
-	void* st;
-	unsigned int i, j;
-	enum sip_protos transport;
-	str hostname, params;
-	str tag;
-	struct gw_info *gws;
-
-	for (j = 1; j <= lcr_count; j++) {
-	
-	    gws = gwtp[j];
-
-	    for (i = 1; i <= gws[0].ip_addr; i++) {
-		if (rpc->add(c, "{", &st) < 0) return;
-		rpc->struct_add(st, "d", "lcr_id", j);
-		rpc->struct_add(st, "d", "grp_id", gws[i].grp_id);
-		rpc->struct_printf(st, "ip_addr", "%d.%d.%d.%d",
-				   (gws[i].ip_addr << 24) >> 24,
-				   ((gws[i].ip_addr >> 8) << 24) >> 24,
-				   ((gws[i].ip_addr >> 16) << 24) >> 24,
-				   gws[i].ip_addr >> 24);
-		hostname.s=gws[i].hostname;
-		hostname.len=gws[i].hostname_len;
-		rpc->struct_add(st, "S", "hostname", &hostname);
-		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 {
-		    rpc->struct_add(st, "s", "scheme", "sips");
-		}
-		transport = gws[i].transport;
-		switch(transport){
-			case PROTO_UDP:
-				rpc->struct_add(st, "s", "transport", "UDP");
-				break;
-			case PROTO_TCP:
-				rpc->struct_add(st, "s", "transport", "TCP");
-				break;
-			case PROTO_TLS:
-				rpc->struct_add(st, "s", "transport", "TLS");
-				break;
-			case PROTO_SCTP:
-				rpc->struct_add(st, "s", "transport", "SCTP");
-				break;
-			case PROTO_NONE:
-			    break;
-		}
-		tag.s=gws[i].tag;
-		tag.len=gws[i].tag_len;
-		rpc->struct_add(st, "dSddd",
-				"strip",  gws[i].strip,
-				"tag",    &tag,
-				"weight", gws[i].weight,
-				"flags",  gws[i].flags,
-				"defunct_until",  &gws[i].defunct_until
-				);
+    void* st;
+    unsigned int i, j;
+    enum sip_protos transport;
+    str gw_name, hostname, params;
+    str tag;
+    struct gw_info *gws;
+
+    for (j = 1; j <= lcr_count_param; j++) {
+
+	gws = gw_pt[j];
+
+	for (i = 1; i <= gws[0].ip_addr; i++) {
+	    if (rpc->add(c, "{", &st) < 0) return;
+	    rpc->struct_add(st, "d", "lcr_id", j);
+	    rpc->struct_add(st, "d", "gw_id", gws[i].gw_id);
+	    rpc->struct_add(st, "d", "gw_index", i);
+	    gw_name.s=gws[i].gw_name;
+	    gw_name.len=gws[i].gw_name_len;
+	    rpc->struct_add(st, "S", "gw_name", &gw_name);
+	    if (gws[i].scheme == SIP_URI_T) {
+		rpc->struct_add(st, "s", "scheme", "sip");
+	    } else {
+		rpc->struct_add(st, "s", "scheme", "sips");
+	    }
+	    rpc->struct_printf(st, "ip_addr", "%d.%d.%d.%d",
+			       (gws[i].ip_addr << 24) >> 24,
+			       ((gws[i].ip_addr >> 8) << 24) >> 24,
+			       ((gws[i].ip_addr >> 16) << 24) >> 24,
+			       gws[i].ip_addr >> 24);
+	    hostname.s=gws[i].hostname;
+	    hostname.len=gws[i].hostname_len;
+	    rpc->struct_add(st, "S", "hostname", &hostname);
+	    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);
+	    transport = gws[i].transport;
+	    switch(transport){
+	    case PROTO_UDP:
+		rpc->struct_add(st, "s", "transport", "UDP");
+		break;
+	    case PROTO_TCP:
+		rpc->struct_add(st, "s", "transport", "TCP");
+		break;
+	    case PROTO_TLS:
+		rpc->struct_add(st, "s", "transport", "TLS");
+		break;
+	    case PROTO_SCTP:
+		rpc->struct_add(st, "s", "transport", "SCTP");
+		break;
+	    case PROTO_NONE:
+		break;
 	    }
+	    tag.s=gws[i].tag;
+	    tag.len=gws[i].tag_len;
+	    rpc->struct_add(st, "dSdd",
+			    "strip",  gws[i].strip,
+			    "tag",    &tag,
+			    "flags",  gws[i].flags,
+			    "defunct_until",  &gws[i].defunct_until
+			    );
 	}
+    }
 }
 
 
-
-static const char* dump_lcrs_doc[2] = {
-	"Dump the contents of the lcr table.",
-	0
+static const char* dump_rules_doc[2] = {
+    "Dump the contents of the lcr_rules table.",
+    0
 };
 
 
-static void dump_lcrs(rpc_t* rpc, void* c)
+static void dump_rules(rpc_t* rpc, void* c)
 {
-        int i, j;
-	struct lcr_info **lcrs, *lcr_rec;
-	void* st;
-	str prefix, from_uri, lcr_id;
+    int i, j;
+    struct rule_info **rules, *rule;
+    struct target *t;
+    void* st;
+    str prefix, from_uri;
 
-	for (j = 1; j <= lcr_count; j++) {
+    for (j = 1; j <= lcr_count_param; j++) {
 	    
-	    lcrs = lcrtp[j];
-
-	    for (i = 0; i < lcr_hash_size_param; i++) {
-		lcr_rec = lcrs[i];
-		while(lcr_rec){
-			if (rpc->add(c, "{", &st) < 0) return;
-			lcr_id.s = int2str(j, &(lcr_id.len));
-			prefix.s=lcr_rec->prefix;
-			prefix.len=lcr_rec->prefix_len;
-			from_uri.s=lcr_rec->from_uri;
-			from_uri.len=lcr_rec->from_uri_len;
-			rpc->struct_add(st, "dSSdd",
-					"lcr_id", j,
-					"prefix", &prefix,
-					"from_uri", &from_uri,
-					"grp_id", lcr_rec->grp_id,
-					"priority", lcr_rec->priority
-					);
-			lcr_rec=lcr_rec->next;
+	rules = rule_pt[j];
+
+	for (i = 0; i < lcr_rule_hash_size_param; i++) {
+	    rule = rules[i];
+	    while (rule) {
+		if (rpc->add(c, "{", &st) < 0) return;
+		prefix.s=rule->prefix;
+		prefix.len=rule->prefix_len;
+		from_uri.s=rule->from_uri;
+		from_uri.len=rule->from_uri_len;
+		rpc->struct_add(st, "ddSSd",
+				"lcr_id", j,
+				"rule_id", rule->rule_id,
+				"prefix", &prefix,
+				"from_uri", &from_uri,
+				"stopper", rule->stopper
+				);
+		t = rule->targets;
+		while (t) {
+		    if (rpc->add(c, "{", &st) < 0) return;
+		    rpc->struct_add(st, "ddd",
+				    "gw_index", t->gw_index,
+				    "priority", t->priority,
+				    "weight", t->weight
+				    );
+		    t = t->next;
 		}
+		rule=rule->next;
 	    }
-	    lcr_rec=lcrs[lcr_hash_size_param];
-	    while(lcr_rec){
-		rpc->add(c, "d", lcr_rec->prefix_len);
-		lcr_rec=lcr_rec->next;
-	    }
 	}
+	rule=rules[lcr_rule_hash_size_param];
+	while (rule) {
+	    rpc->add(c, "d", rule->prefix_len);
+	    rule=rule->next;
+	}
+    }
 }
 
 
-
 rpc_export_t lcr_rpc[] = {
-	{"lcr.reload", reload, reload_doc, 0},
-	{"lcr.dump_gws",   dump_gws,   dump_gws_doc,   0},
-	{"lcr.dump_lcrs",   dump_lcrs,   dump_lcrs_doc,   0},
-	{0, 0, 0, 0}
+    {"lcr.reload", reload, reload_doc, 0},
+    {"lcr.dump_gws", dump_gws, dump_gws_doc, 0},
+    {"lcr.dump_rules", dump_rules, dump_rules_doc, 0},
+    {0, 0, 0, 0}
 };

+ 6 - 6
modules/lcr/lcr_rpc.h

@@ -1,21 +1,21 @@
 /*
  * Various lcr related functions
  *
- * Copyright (C) 2005 Juha Heinanen
+ * Copyright (C) 2009-2010 Juha Heinanen
  *
- * This file is part of ser, a free SIP server.
+ * This file is part of SIP Router, a free SIP server.
  *
- * ser is free software; you can redistribute it and/or modify
+ * SIP Router is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
- * For a license to use the ser software under conditions
+ * For a license to use the SIP Router software under conditions
  * other than those described here, or to purchase support for this
  * software, please contact iptel.org by e-mail at the following addresses:
  *    [email protected]
  *
- * ser is distributed in the hope that it will be useful,
+ * SIP Router is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -35,7 +35,7 @@
 #define _LCR_RPC_H
 
 #ifndef NO_RPC_SUPPORT
-#define RPC_SUPPORT /* support ser RPCs by default */
+#define RPC_SUPPORT /* support SIP Router RPCs by default */
 #endif
 
 #ifdef RPC_SUPPORT

Some files were not shown because too many files changed in this diff