LCR (Least Cost Routing) Module

Juha Heinanen

   <jh@tutpro.com>

Edited by

Juha Heinanen

   <jh@tutpro.com>

   Copyright © 2005-2008 Juha Heinanen
   Revision History
   Revision $Revision: 5949 $ $Date: 2008-10-16 19:58:34 +0300
                              (Thu, 16 Oct 2008) $
     __________________________________________________________

   Table of Contents

   1. Admin Guide

        1.1. Overview
        1.2. Dependencies

              1.2.1. Kamailio modules
              1.2.2. External libraries or applications

        1.3. Exported Parameters

              1.3.1. db_url (string)
              1.3.2. gw_table (string)
              1.3.3. gw_name_column (string)
              1.3.4. grp_id_column (string)
              1.3.5. ip_addr_column (string)
              1.3.6. hostname_column (string)
              1.3.7. port_column (string)
              1.3.8. uri_scheme_column (string)
              1.3.9. transport_column (string)
              1.3.10. strip_column (string)
              1.3.11. tag_column (string)
              1.3.12. weight_column (string)
              1.3.13. flags_column (string)
              1.3.14. ping_column (string)
              1.3.15. lcr_table (string)
              1.3.16. prefix_column (string)
              1.3.17. from_uri_column (string)
              1.3.18. priority_column (string)
              1.3.19. gw_uri_avp (AVP string)
              1.3.20. rpid_avp (AVP string)
              1.3.21. ruri_user_avp (AVP string)
              1.3.22. flags_avp (AVP string)
              1.3.23. lcr_hash_size (integer)
              1.3.24. fetch_rows (integer)
              1.3.25. ping_interval (integer)
              1.3.26. ping_from (string)
              1.3.27. ping_method (string)
              1.3.28. positive_codes (string)
              1.3.29. negative_codes (string)

        1.4. Exported Functions

              1.4.1. load_gws([pvar])
              1.4.2. load_gws_from_grp(group-id)
              1.4.3. next_gw()
              1.4.4. from_gw([pvar])
              1.4.5. from_gw_grp(group-id)
              1.4.6. to_gw([group-id])

        1.5. Exported MI Commands

              1.5.1. lcr_reload
              1.5.2. lcr_gw_dump
              1.5.3. lcr_lcr_dump

        1.6. Known Limitations

   List of Examples

   1.1. Setting db_url module parameter
   1.2. Setting gw_table module parameter
   1.3. Setting gw_name_column module parameter
   1.4. Setting grp_id_column module parameter
   1.5. Setting ip_addr_column module parameter
   1.6. Setting hostname_column module parameter
   1.7. Setting port_column module parameter
   1.8. Setting uri_scheme_column module parameter
   1.9. Setting transport_column module parameter
   1.10. Setting strip_column module parameter
   1.11. Setting tag_column module parameter
   1.12. Setting weight_column module parameter
   1.13. Setting flags_column module parameter
   1.14. Setting ping_column module parameter
   1.15. Setting lcr_table module parameter
   1.16. Setting prefix_column module parameter
   1.17. Setting from_uri_column module parameter
   1.18. Setting priority_column module parameter
   1.19. Setting gw_uri_avp module parameter
   1.20. Setting rpid_avp module parameter
   1.21. Setting ruri_user_avp module parameter
   1.22. Setting flags_avp module parameter
   1.23. Setting lcr_hash_size module parameter
   1.24. Set fetch_rows parameter
   1.25. Set ping_interval parameter
   1.26. Set ping_from parameter
   1.27. Set ping_method parameter
   1.28. Set positive_codes parameter
   1.29. Set negative_codes parameter
   1.30. load_gws usage
   1.31. load_gws_from_grp usage
   1.32. next_gw usage from a route block
   1.33. next_gw usage from a failure route block
   1.34. from_gw usage
   1.35. from_gw usage with pseudo variable argument
   1.36. from_gw_grp usage
   1.37. to_gw usage
   1.38. to_gw usage with group-id

Chapter 1. Admin Guide

1.1. Overview

   Least cost routing (LCR) module implements capability to
   serially forward a request to one or more gateways so that the
   order in which the gateways is tried is based on admin defined
   "least cost".

   For the purpose of facilitating least cost routing of requests,
   each gateway 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 user part of Request URI
   matches a prefix and caller's URI matches a from pattern in a
   tuple that belongs to the group of the gateway.

   When function load_gws() is called, matching gateways are
   ordered for forwarding purpose (1) according to longest user
   part match, (2) according to tuple's priority, and (3)
   gateway's randomized weight within its group. Prefix is a
   string of characters or NULL. From pattern is a regular
   expression (see 'man pcresyntax' for syntax), an empty string,
   or NULL. 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.

   LCR module may be configured via ping_interval module parameter
   to check if certain gateways are alive. A gateway is subject
   for checking if its ping_column has value 1 (default is 0).
   When load_gws() is called, only matching gateways that are
   currently not found to be dead or that are not subject for
   checking, will be loaded.

   Function next_gw() can then be used to select one gateway at a
   time for forwarding. Upon each call, user part of original
   Request URI is first stripped by the number of characters as
   specified by the gateway's strip count and then prefixed by
   gateway's tag. Upon first call, if gateway's hostname is NULL,
   Request URI is rewritten based on gateway's URI scheme, IP
   address, port, and transport protocol. If hostname is not NULL,
   Request-URI is rewritten based on 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
   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 = tls, and 4 = sctp.

   As a side effect of gateway selection, gateway's flags (that
   may contain information about capabilities of the gateway) are
   stored into an AVP.

1.2. Dependencies

1.2.1. Kamailio modules

   The following modules must be loaded before this module:
     * TM module
     * A database module like mysql, postgres or dbtext.

1.2.2. External libraries or applications

   The following libraries or applications must be installed
   before running Kamailio with this module:
     * none.

1.3. Exported Parameters

1.3.1. db_url (string)

   URL of the database table to be used.

   Default value is
   "mysql://openserro:openserro@localhost/openser".

   Example 1.1. Setting db_url module parameter
...
modparam("lcr","db_url","dbdriver://username:password@dbhost/dbname")
...

1.3.2. gw_table (string)

   Name of the table holding the gateways definitions.

   Default value is "gw".

   Example 1.2. Setting gw_table module parameter
...
modparam("lcr","gw_table","gw")
...

1.3.3. gw_name_column (string)

   Name of the column holding the gateway name.

   Default value is "gw_name".

   Example 1.3. Setting gw_name_column module parameter
...
modparam("lcr","gw_name_column","gw_name")
...

1.3.4. grp_id_column (string)

   Name of the column holding the group ID of gateway both in gw
   and lcr tables.

   Default value is "grp_id".

   Example 1.4. Setting grp_id_column module parameter
...
modparam("lcr","grp_id_column","grp_id")
...

1.3.5. ip_addr_column (string)

   Name of the column holding the IP address of the gateway.

   Default value is "ip_addr".

   Example 1.5. Setting ip_addr_column module parameter
...
modparam("lcr","ip_addr_column","ip_addr")
...

1.3.6. hostname_column (string)

   Name of the column holding gateway's hostname that is used in
   Request-URI, when request is sent to the gateway. Note that
   request is not forwarded based on hostname, but based on
   gateway's IP address in destination uri.

   Default value is "hostname".

   Example 1.6. Setting hostname_column module parameter
...
modparam("lcr", "hostname_column","host")
...

1.3.7. port_column (string)

   Name of the column holding the port number of the gateway.

   Default value is "port".

   Example 1.7. Setting port_column module parameter
...
modparam("lcr","port_column","port")
...

1.3.8. uri_scheme_column (string)

   Name of the column holding the uri scheme of the gateway.

   Default value is "uri_scheme".

   Example 1.8. Setting uri_scheme_column module parameter
...
modparam("lcr","uri_scheme_column","scheme")
...

1.3.9. transport_column (string)

   Name of the column holding the transport type to be used for
   the gateway.

   Default value is "transport".

   Example 1.9. Setting transport_column module parameter
...
modparam("lcr","transport_column","transport")
...

1.3.10. 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.10. Setting strip_column module parameter
...
modparam("lcr","strip_column","strip_count")
...

1.3.11. tag_column (string)

   Name of the column holding gateway specific tag string.

   Default value is "tag".

   Example 1.11. Setting tag_column module parameter
...
modparam("lcr","tag_column","gw_tag")
...

1.3.12. weight_column (string)

   Name of the column holding gateway's weight within its group.

   Default value is "weight".

   Example 1.12. Setting weight_column module parameter
...
modparam("lcr","weight_column","gw_weight")
...

1.3.13. flags_column (string)

   Name of the column holding gateway specific flag values.

   Default value is "flags".

   Example 1.13. Setting flags_column module parameter
...
modparam("lcr","flags_column","gw_flags")
...

1.3.14. ping_column (string)

   Name of the column telling if gateway is subject for aliveness
   check.

   Default value is "ping".

   Example 1.14. Setting ping_column module parameter
...
modparam("lcr", "ping_column", "gw_ping")
...

1.3.15. lcr_table (string)

   Name of the table holding the LCR rules.

   Default value is "lcr".

   Example 1.15. Setting lcr_table module parameter
...
modparam("lcr","lcr_table","lcr")
...

1.3.16. prefix_column (string)

   Name of the column holding prefix of Request URI user part.

   Default value is "prefix".

   Example 1.16. Setting prefix_column module parameter
...
modparam("lcr","prefix_column","prefix")
...

1.3.17. from_uri_column (string)

   Name of the column holding the FROM (source) URI.

   Default value is "from_uri".

   Example 1.17. Setting from_uri_column module parameter
...
modparam("lcr","from_uri_column","from_uri")
...

1.3.18. priority_column (string)

   Name of the column holding the priority of the rule.

   Default value is "priority".

   Example 1.18. Setting priority_column module parameter
...
modparam("lcr","priority_column","priority")
...

1.3.19. gw_uri_avp (AVP string)

   Internal AVP that load_gws function uses to store information
   of matching gateways.

   There is NO default value, thus this variable must be defined
   in kamailio.cfg.

   Example 1.19. Setting gw_uri_avp module parameter
...
modparam("lcr", "gw_uri_avp", "$avp(i:709)")
...

1.3.20. rpid_avp (AVP string)

   An AVP that contains caller's RPID (if any).

   There is NO default value, thus this variable must be defined
   in kamailio.cfg.

   Example 1.20. Setting rpid_avp module parameter
...
modparam("^auth$|lcr", "rpid_avp", "$avp(i:302)")
...

1.3.21. ruri_user_avp (AVP string)

   Internal AVP that next_gw function uses to store Request-URI
   user for subsequent next_gw calls.

   There is NO default value, thus this variable must be defined
   in kamailio.cfg.

   Example 1.21. Setting ruri_user_avp module parameter
...
modparam("lcr", "ruri_user_avp", "$avp(i:500)")
...

1.3.22. flags_avp (AVP string)

   An AVP where successful next_gw and from_gw functions store
   gateway's flags.

   There is NO default value, thus this variable must be defined
   in kamailio.cfg.

   Example 1.22. Setting flags_avp module parameter
...
modparam("lcr", "flags_avp", "$avp(i:712)")
...

1.3.23. 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 less collisions with other prefixes.
   Hash size value should be a power of 2.

   Default value is 128.

   Example 1.23.  Setting lcr_hash_size module parameter
...
modparam("lcr", "lcr_hash_size", 1024)
...

1.3.24. fetch_rows (integer)

   The number of the rows to be fetched at once from database when
   loading data from lcr 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, database driver must support fetch_result() capability.

   Default value is "2000".

   Example 1.24. Set fetch_rows parameter
...
modparam("lcr", "fetch_rows", 3000)
...

1.3.25. ping_interval (integer)

   How often (in seconds) gateways are checked for aliveness. If
   set to 0, checking of gateways is disabled. The interval cannot
   be less than 180 seconds.

   Default value is 0.

   Example 1.25. Set ping_interval parameter
...
modparam("lcr", "ping_interval", 300)
...

1.3.26. ping_from (string)

   From URI used in gateway aliveness check.

   Default value is "sip:127.0.0.1".

   Example 1.26. Set ping_from parameter
...
modparam("lcr", "ping_from", "sip:gateway.kamalio.org")
...

1.3.27. ping_method (string)

   SIP method used for aliveness check.

   Default value is "OPTIONS".

   Example 1.27. Set ping_method parameter
...
modparam("lcr", "ping_method", "INFO")
...

1.3.28. positive_codes (string)

   Semicolon separated reply codes that are interpreted as
   positive replies to aliveness check.

   Default value is "200;501;403;404".

   Example 1.28. Set positive_codes parameter
...
modparam("lcr", "positive_codes", "200;501;403;404")
...

1.3.29. negative_codes (string)

   Semicolon separated reply codes that are interpreted as
   negative replies to aliveness check.

   Default value is "408".

   Example 1.29. Set negative_codes parameter
...
modparam("lcr", "negative_codes", "408")
...

1.4. Exported Functions

1.4.1.  load_gws([pvar])

   Loads URI schemes, IP addresses, hostnames, ports, and
   transports of matching gateways to gw_uri_avp (see Overview
   section). If optional pseudo variable argument is included,
   caller's URI is taken from it. If pseudo variable argument is
   not included, caller's URI is taken from rpid_avp or, if
   rpid_avp value is empty, from From URI. Returns 1 or -1
   depending on success.

   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.

   This function can be used from REQUEST_ROUTE.

   Example 1.30. load_gws usage
...
if (!load_gws("$var(caller_uri)")) {
        sl_send_reply("500", "Server Internal Error - Cannot load gatewa
ys");
        exit;
};
...

1.4.2.  load_gws_from_grp(group-id)

   Loads URI schemes, IP addresses, hostnames, ports, and
   transports of gateways that belong to a given group to
   gw_uri_avp. group-id argument is a string that may contain
   pseudo-variables. Its value must be a a string of digits that
   are converted to an integer group id. Returns 1 or -1 depending
   on success.

   Execution time of load_gws_from_grp() function is O(N), where N
   is number of gateways.

   This function can be used from REQUEST_ROUTE.

   Example 1.31. load_gws_from_grp usage
...
if (!load_gws_from_grp("1")) {
        sl_send_reply("500", "Server Internal Error - Cannot load gatewa
ys from group 1");
        exit;
};
...

if (!load_gws_from_grp("$avp(s:gateway_group)")) {
        sl_send_reply("500", "Server Internal Error - Cannot load gatewa
ys");
        exit;
};
...

1.4.3.  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 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.

   As a side effect, stores gateway's flags to flags_avp.

   Returns 1 on success and -1 if there were no gateways left or
   if an error occurred (see syslog).

   Must be preceded by successful load_gws() call.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.

   Example 1.32. next_gw usage from a route block
...
if (!next_gw()) {
        sl_send_reply("503", "Service not available - No gateways");
        exit;
};
...

   Example 1.33. next_gw usage from a failure route block
...
if (!next_gw()) {
        t_reply("503", "Service not available - No more gateways");
        exit;
};
...

1.4.4.  from_gw([pvar])

   Checks if request came from IP address of a gateway. IP address
   to be checked is either taken from source IP address of the
   request or (if present) from pseudo variable argument. As a
   side effect, stores gateway's flags to flags_avp.

   Execution time of from_gw() function is O(log N), where N is
   number of gateways.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
   ONREPLY_ROUTE.

   Example 1.34. from_gw usage
...
if (from_gw()) {
        ...
};
...

   Example 1.35. from_gw usage with pseudo variable argument
...
if (from_gw("$si")) {
        ...
};
...

1.4.5.  from_gw_grp(group-id)

   Checks if request came from IP address of a gateway that
   belongs to the given group (integer string). Sets or resets a
   message flag depending on whether the gateway supports directed
   media.

   Execution time of from_gw_grp() function is O(log N), where N
   is number of gateways.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
   ONREPLY_ROUTE.

   Example 1.36. from_gw_grp usage
...
if (from_gw_grp("1")) {
        ...
};
...

1.4.6.  to_gw([group-id])

   Checks if in-dialog request goes to a gateway. If an optional
   group-id (integer string) is given, only gateways belonging to
   this group are checked.

   Execution time of to_gw() function is O(log N), where N is
   number of gateways.

   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.

   Example 1.37. to_gw usage
...
if (to_gw()) {
        ...
        exit;
};
...

   Example 1.38. to_gw usage with group-id
...
if (to_gw("1")) {
        ...
        exit;
};
...

1.5. Exported MI Commands

1.5.1. lcr_reload

   Causes lcr module to re-read the contents of gateway and lcr
   tables into memory.

   Reload fails if number of gateways is larger than value of
   constant MAX_NO_OF_GWS in file lcr_mod.c, which defaults to
   128. If you have more than 128 gateways, you need to increase
   the value of this constant and recompile lcr module.

   Name: lcr_reload

   Parameters: none

   MI FIFO Command Format:
                :lcr_reload:_reply_fifo_file_
                _empty_line_

1.5.2. lcr_gw_dump

   Causes lcr module to dump the contents of its in-memory gw
   table.

   Name: lcr_gw_dump

   Parameters: none

   MI FIFO Command Format:
                :lcr_gw_dump:_reply_fifo_file_
                _empty_line_

1.5.3. lcr_lcr_dump

   Causes lcr module to dump the contents of its in-memory lcr
   table.

   Name: lcr_lcr_dump

   Parameters: none

   MI FIFO Command Format:
                :lcr_gw_dump:_reply_fifo_file_
                _empty_line_

1.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.
